割引アプリ制作ガイド

概要

「早く、簡単に」割引アプリ制作

  • 本ガイドは、割引アプリ(App)を簡単に制作できるように、開発プロセスや動作の仕組みについて説明します。
  • また、簡単な割引アプリの例示を通じてデータおよびリファレンスを提供することで、誰でも早く制作できます。
  • ガイドを参考し、割引アプリ(App)の制作を始めてみましょう。開発においてお困りの点などございましたら、cafe24アプリ制作サポートチームまでご連絡ください。

アプリ開発の基本情報

アプリ(App)の登録から検査までの事前準備作業は、以下のリンクをご参照ください。

アプリ動作の仕組み

  • 制作したアプリ(App)のスクリプト(script)は、cafe24ネットショップのカート/注文書に挿入され、割引に必要な基本情報を獲得します。
  • cafe24ネットショップの割引反映基準は、商品割引と注文割引に大きく分けられ、アプリ(App)別のロジックに沿って算定された割引金額を以下の規約に準じてcallback関数へ伝えています。
  • cafe24ネットショップは、伝えられた割引金額に対する検証を行い、実際決済金額に反映します。

cafe24とアプリとの間での動作例を表したシーケンス図

動作プロセス

プロセス
順序 プロセス 内容 参考
1 cafe24 Front Api
呼び出し
  • cafe24で提供するFront APIを活用するとネットショップと会員の基本情報を得られます。
    • ショップID、マルチショップ番号、会員ID、ゲストキーなどの基本情報を獲得
  • Front APIとグローバル変数は、window.onloadが完了した後にご使用ください。
    • window.onloadが完了する前は、該当変数の値が完全でない可能背があります。
2 割引およびHMAC
  • 獲得した情報を基に、いろんな割引を具現します。
  • 必須条件 : hmac暗号化キーを発行後、プレーンテキストと一緒にレスポンス本文に追加します。
  • クロスドメイン問題の回避のため、Response Headerに、(「Access-Control-Allow-Origin」、「*」)を追加します。
  • アプリで割引ロジックを遂行するたびにcafe24 api 呼び出しを厳格に禁じます。
  • アプリ割引ロジックの具現時、cafe24のAPI呼び出しが検針される場合、審査を通過できない場合もあります。
3 割引適用
  • レスポンスデータは、cafe24ショッピングカート/注文書のJavascript callback関数(AppDiscount.setAppDiscountPrice(result);)を呼び出し、割引結果を画面に表示します。
  • JS function / APIを通じて望むデザイン/後続機能を色々といろいろと追加することができます。
  • resultは、JSON.stringify()を通じてjson文字列に変換してから使用しないと正常に動作しません。

JSON.stringify()ページへ

スペックおよびサンプルデータ

1. cafe24ショッピングカート/注文書の商品情報

  1.    a. カートと注文書の注文/商品情報の変数は、必ず使い分けてください。
  2.    b. カートと注文書のみで提供するJavascriptグローバル変数
詳細説明
変数名 タイプ 役割 sample data
sPage string ショッピングカート("ORDER_BASKET") / 注文書("ORDER_ORDERFORM")を区分
var sPage
"ORDER_BASKET";//ショッピングカートの場合
"ORDER_ORDERFORM"; //注文書の場合
aBasketProductData array カートの商品情報
var aBasketProductData
[
  {
    "delvtype": "A",
    "main_cate_no": 1,
    "product_no": 21,
    "opt_id": "000A",
    "product_type": "normal_type",
    "naver_used_exception": "F",
    "quantity": 1,
    "check_quantity": 1,
    "check_quantity_type": "O",
    "option_add": "F",
    "product_min": 1,
    "product_max_type": "F",
    "product_max": 0,
    "product_code": "P000000V",
    "product_price": 10000,
    "opt_price": 0,
    "product_sum_price": 10000,
    "product_sale_price": 10000,
    "product_name": "商品A",
    "opt_str": "",
    "item_code": "P000000V000A",
    "option_type": "T",
    "has_option": "F",
    "has_option_add": "F",
    "is_set_product": "F",
    "set_product_name": "",
    "set_product_no": 0,
    "basket_prd_no": 101,
    "item_listing_type": "C",
    "is_oversea_able": true,
    "set_product_list": null,
    "buy_unit": 1,
    "check_buy_unit_type": "O",
    "wish_selected_item": "",
    "wish_save_data": "",
    "olink_data": "",
    "product_paymethod": "cash,mileage",
    "option_attached_file_info_json": "",
    "total_unit_add_sale": 0,
    "use_store_pickup": "F",
    "layer_option_str": null,
    "sIsBenefitEventProduct": "F",
    "check_buy_unit": 1
  }
];
aBasketProductOrderData array 注文書の商品情報
var aBasketProductOrderData
[
  {
    "quantity": 1,
    "product_sum_price": 10000,
    "option_add": "F",
    "option_type": "T",
    "set_product_no": 0,
    "basket_prd_no": 101,
    "product_no": 21,
    "item_code": "P000000V000A",
    "product_price": 10000,
    "opt_price": 0,
    "product_sale_price": 10000
  }
];

2. HMAC Spec

  •    a. base64_encode(hash_hmac(「sha256」、プレーンテキスト、Service_key, true));
  •    b. アルゴリズムは、「sha256」を使用します。
  •    c. Service_keyは、cafe24 デベロッパーで発行したService_keyを使用します。
  •    d. Service_keyは、割引/決済に関連した完全性検証のための値であり、絶対に外部に露出してはいけません。
  •    e. Service_keyが、露出したか、または露出したと思われる場合、cafe24 デベロッパーで再発行しご使用ください。
  •    f. guest_key 値は、会員 : md5(member_id)、非会員 : EC_GUEST_KEYを使用します。
  •    g. HMAC追加要領
    •       - guest_key値は、プレーンテキストの一番後ろに位置しないといけません。
    •       - guest_key値は、hmacで暗号化した後、プレーンテキストから削除します。
    •       - プレーンテキストの一番後ろにhmac値を追加します。

3. cafe24ショッピングカート/注文書callback関数の要請スペック

   a. パラメータ1、2、3は、スペックにDepthを表します。

詳細説明
パラメータ1 パラメータ2 パラメータ3 用途 タイプ
mall_id ショップID string
shop_no マルチショップ番号 string
member_id 会員ID string
member_group_no 会員グループ string
product_discount 割引商品情報 array
basket_prd_no ショッピングカート番号 string
product_no 商品番号 string
item_code 商品コード string
quantity 数量 string
product_price 商品金額 string
opt_price オプション金額 string
product_sale_price 商品割引適用金額 string
discount_price 商品割引金額 string
app_discount_info 適用された割引固有番号リスト string[]
order_discount 注文割引情報 array
no 割引固有番号 string
price 商品割引金額 string
apply_product 割引適用商品コード string
app_discount_info 割引詳細情報 array
no 割引固有番号 string
type 割引タイプ string
name 割引名 string
icon 割引アイコン string
config 割引設定 object
string
value 割引金額 string
value_type 割引タイプ(W:定額、P:定率) string
time 割引要請 string
trace_no 追跡番号
  • - transaction別のkey値
  • - appで生成
string
app_key app_key string
hmac暗号化情報 hmac暗号化情報 string

Sample Data

var result
{
 "mall_id": "cafe24_mall",
 "shop_no": 1,
 "member_id": "",
 "member_group_no": 0,
 "product_discount": [
 {
 "basket_prd_no": 87,
 "product_no": 20,
 "item_code": "P000000U000A",
 "quantity": 1,
 "product_price": 10000,
 "opt_price": 0,
 "product_sale_price": 10000,
 "discount_price": 0,
 "app_discount_info": []
 },
 {
 "basket_prd_no": 87,
 "product_no": 21,
 "item_code": "P000000U000B",
 "quantity": 1,
 "product_price": 20000,
 "opt_price": 0,
 "product_sale_price": 20000,
 "discount_price": 0,
 "app_discount_info": []
 }
 ],
 "order_discount": [
 {
 "no": "200",
 "price": "1000",
 "apply_product": "P000000U000A,P000000U000B"
 }
 ],
 "app_discount_info": [
 {
 "no": 200,
 "type": "O",
 "name": "FRIDAY_DISCOUNT",
 "icon": "http://placehold.it/32x32",
 "config": {
 "value": 1000,
 "value_type": "W"
 }
 }
 ],
 "time": "1536672695075",
 "trace_no": "20180911223134Qkgj54",
 "app_key": "9M0gI35ANt7gDicnD02u8D",
 "hmac": "eOEafN86qA4zh49BkjUAhlB3zF5CqVruBNpS46QTVVs="
}
  • 以下の図は、基本流れにデータや呼び出し、レスポンスデータを追加した内容です。
  • 各重要ポイントをクリックすると、詳細ガイドへ移動します。

サンプルコード

  • 次は、アプリ(App)で算定した割引金額のロージックが反映される例示です。
  • 例示を基に、作成されたサンプルコードを確認することができます。

割引例示:毎週金曜日に1,000円注文割引

Front-end

app.js
//Appの割引ロージック呼び出し
function app_do_sale(params){
    $.ajax({
        url: "https://example.com/sale",
        dataType: "json",
        method: "POST",
        data: {
            'mall_id': params.ec_mall_id
            , 'shop_no': params.shop_no
            , 'member_id': params.member_id
            , 'guest_key': params.guest_key
            , 'member_group_no': params.group_no
            , 'product': JSON.stringify(params.orderInfos)
            , 'time': new Date().getTime()
        },
        success: function (result) {
            console.log('SALE success!');
            AppDiscount.setAppDiscountPrice(JSON.stringify(result));
        }, error: function (e) {
            console.log('SALE error!');
        }
    });
}

//基本情報および商品情報セッティング
var app_init_sale = function () {
    var app_req_params = {};
    var orderInfos;

    if (sPage == 'ORDER_BASKET')  //ショッピングカートの場合
        orderInfos = aBasketProductData;
    else if (sPage == 'ORDER_ORDERFORM')    //注文書の場合
        orderInfos = aBasketProductOrderData;

    if (orderInfos.length <= 0) return;

    app_req_params.orderInfos = orderInfos;

    //cafe24FrontAPI活用基本情報の照会
    (function(CAFE24API) {
        app_req_params.ec_mall_id = CAFE24API.MALL_ID;
        app_req_params.shop_no = CAFE24API.SHOP_NO;

        // 会員情報の照会
        CAFE24API.getMemberInfo(function (data) {
            app_req_params.member_id = data.id.member_id;
            app_req_params.group_no = Number(data.id.group_no);

            if (app_req_params.member_id == null)
                app_req_params.guest_key = data.id.guest_id;

            app_do_sale(app_req_params);
        });
    })(CAFE24API.init("CAFE24で発行したAPP_KEY"));

};

//window.onload確認後、イベントリスナーに登録
if (document.readyState == 'complete') {
    app_init_sale();
}  else {
    window.addEventListener('load', app_init_sale);
}

Data

リクエストデータ(var params)
{
 "mall_id": "cafe24_mall",
 "shop_no": "1",
 "member_id": "",
 "guest_key": "9f2c9a3cb0c04a4ff394596ebb23f5cc",
 "member_group_no": "0",
 "time": "1536672695075",
 "product": [
 {
 "quantity": 1,
 "product_no": 20,
 "product_price": 10000,
 "product_sale_price": 100000,
 "opt_price": 0,
 "product_name": "商品A",
 "basket_prd_no": 87,
 "item_code": "P000000U000A"
 },
 {
 "quantity": 1,
 "product_no": 21,
 "product_price": 20000,
 "product_sale_price": 20000,
 "opt_price": 0,
 "product_name": "商品B",
 "basket_prd_no": 87,
 "item_code": "P000000U000B"
 }
 ]
};
レスポンスデータ(var result)
{
 "mall_id": "cafe24_mall",
 "shop_no": 1,
 "member_id": "",
 "member_group_no": 0,
 "product_discount": [
 {
 "basket_prd_no": 87,
 "product_no": 20,
 "item_code": "P000000U000A",
 "quantity": 1,
 "product_price": 10000,
 "opt_price": 0,
 "product_sale_price": 10000,
 "discount_price": 0,
 "app_discount_info": []
 },
 {
 "basket_prd_no": 87,
 "product_no": 21,
 "item_code": "P000000U000B",
 "quantity": 1,
 "product_price": 20000,
 "opt_price": 0,
 "product_sale_price": 20000,
 "discount_price": 0,
 "app_discount_info": []
 }
 ],
 "order_discount": [
 {
 "no": "200",
 "price": "1000",
 "apply_product": "P000000U000A,P000000U000B"
 }
 ],
 "app_discount_info": [
 {
 "no": 200,
 "type": "O",
 "name": "FRIDAY_DISCOUNT",
 "icon": "http://placehold.it/32x32",
 "config": {
 "value": 1000,
 "value_type": "W"
 }
 }
 ],
 "time": "1536672695075",
 "trace_no": "20180911223134Qkgj54",
 "app_key": "9M0gI35ANt7gDicnD02u8D",
 "hmac": "eOEafN86qA4zh49BkjUAhlB3zF5CqVruBNpS46QTVVs="
}

Back-end

https://example.com/sale
public String orderSale(@RequestParam OrderVo orderInfo, HttpServletResponse res) {
    //クロスドメイン問題を回避するためには必須
    res.addHeader("Access-Control-Allow-Origin", "*");

    Gson gson = new Gson();
    String trace_no = makeTrace_no();

    LinkedHashMap respOrderMap = saleService.doSale(orderInfo, trace_no);

    if (orderInfo.getMember_id() != null && !orderInfo.getMember_id().isEmpty())
        respOrderMap.put("guest_key", saleService.getEncMD5(orderInfo.getMember_id()));
    else
        respOrderMap.put("guest_key", orderInfo.getGuest_key());

    respOrderMap.put("hmac", saleService.getHmac(respOrderMap));
    respOrderMap.remove("guest_key");

    log.info("[" + trace_no + "]" + "response_params : " + respOrderMap.toString());

    return gson.toJson(respOrderMap);
}
getDiscountAmount
public double getDiscountAmount() {

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(new Date());
    int day_num = calendar.get(Calendar.DAY_OF_WEEK);
    double discount_amount = 0;

    if (day_num == 6) {
        discount_amount = 1000;
    }

    return discount_amount;
}
HMAC
private String makeHmac(String plainText) {
    log.info("[" + trace_no + "]" + "makeHmac plainText : " + plainText);

    String CypHmac = "";

    try {
        Mac mac = Mac.getInstance(Const.algorithm);
        mac.init(new SecretKeySpec(Const.app_secret_key.getBytes(), Const.algorithm));
        mac.update(plainText.getBytes(Const.character_set));

        CypHmac = Base64.encodeBase64String(mac.doFinal());
    } catch (UnsupportedEncodingException | NoSuchAlgorithmException | InvalidKeyException e) {
        e.printStackTrace();
    }

    log.info("[" + trace_no + "]" + "CypHmac : " + CypHmac);

    return CypHmac;
}

Data

リクエストデータ(OrderVo orderInfo)
{
 "mall_id": "cafe24_mall",
 "shop_no": "1",
 "member_id": "",
 "guest_key": "9f2c9a3cb0c04a4ff394596ebb23f5cc",
 "member_group_no": "0",
 "time": "1536672695075",
 "product": [
 {
 "quantity": 1,
 "product_no": 20,
 "product_price": 10000,
 "product_sale_price": 100000,
 "opt_price": 0,
 "product_name": "商品A",
 "basket_prd_no": 87,
 "item_code": "P000000U000A"
 },
 {
 "quantity": 1,
 "product_no": 21,
 "product_price": 20000,
 "product_sale_price": 20000,
 "opt_price": 0,
 "product_name": "商品B",
 "basket_prd_no": 87,
 "item_code": "P000000U000B"
 }
 ]
};
レスポンスデータ(LinkedHashMap respOrderMap)
{
 "mall_id": "cafe24_mall",
 "shop_no": 1,
 "member_id": "",
 "member_group_no": 0,
 "product_discount": [
 {
 "basket_prd_no": 87,
 "product_no": 20,
 "item_code": "P000000U000A",
 "quantity": 1,
 "product_price": 10000,
 "opt_price": 0,
 "product_sale_price": 10000,
 "discount_price": 0,
 "app_discount_info": []
 },
 {
 "basket_prd_no": 87,
 "product_no": 21,
 "item_code": "P000000U000B",
 "quantity": 1,
 "product_price": 20000,
 "opt_price": 0,
 "product_sale_price": 20000,
 "discount_price": 0,
 "app_discount_info": []
 }
 ],
 "order_discount": [
 {
 "no": "200",
 "price": "1000",
 "apply_product": "P000000U000A,P000000U000B"
 }
 ],
 "app_discount_info": [
 {
 "no": 200,
 "type": "O",
 "name": "FRIDAY_DISCOUNT",
 "icon": "http://placehold.it/32x32",
 "config": {
 "value": 1000,
 "value_type": "W"
 }
 }
 ],
 "time": "1536672695075",
 "trace_no": "20180911223134Qkgj54",
 "app_key": "9M0gI35ANt7gDicnD02u8D",
 "hmac": "eOEafN86qA4zh49BkjUAhlB3zF5CqVruBNpS46QTVVs="
}
リクエストデータ(plainText)
{ "mall_id": "cafe24_mall",
 "shop_no": 1,
 "member_id": "",
 "member_group_no": 0,
 "product_discount": [
 {
 "basket_prd_no": 87,
 "product_no": 20,
 "item_code": "P000000U000A",
 "quantity": 1,
 "product_price": 10000,
 "opt_price": 0,
 "product_sale_price": 10000,
 "discount_price": 0,
 "app_discount_info": []
 },
 {
 "basket_prd_no": 87,
 "product_no": 21,
 "item_code": "P000000U000B",
 "quantity": 1,
 "product_price": 20000,
 "opt_price": 0,
 "product_sale_price": 20000,
 "discount_price": 0,
 "app_discount_info": []
 }
 ],
 "order_discount": [
 {
 "no": "200",
 "price": "1000",
 "apply_product": "P000000U000A,P000000U000B"
 }
 ],
 "app_discount_info": [
 {
 "no": 200,
 "type": "O",
 "name": "FRIDAY_DISCOUNT",
 "icon": "http://placehold.it/32x32",
 "config": {
 "value": 1000,
 "value_type": "W"
 }
 }
 ],
 "time": "1536672695075",
 "trace_no": "20180911223134Qkgj54",
 "app_key": "9M0gI35ANt7gDicnD02u8D",
 "guest_key": "9f2c9a3cb0c04a4ff394596ebb23f5cc"
}
レスポンスデータ(plainText)
{ "mall_id": "cafe24_mall",
 "shop_no": 1,
 "member_id": "",
 "member_group_no": 0,
 "product_discount": [
 {
 "basket_prd_no": 87,
 "product_no": 20,
 "item_code": "P000000U000A",
 "quantity": 1,
 "product_price": 10000,
 "opt_price": 0,
 "product_sale_price": 10000,
 "discount_price": 0,
 "app_discount_info": []
 },
 {
 "basket_prd_no": 87,
 "product_no": 21,
 "item_code": "P000000U000B",
 "quantity": 1,
 "product_price": 20000,
 "opt_price": 0,
 "product_sale_price": 20000,
 "discount_price": 0,
 "app_discount_info": []
 }
 ],
 "order_discount": [
 {
 "no": "200",
 "price": "1000",
 "apply_product": "P000000U000A,P000000U000B"
 }
 ],
 "app_discount_info": [
 {
 "no": 200,
 "type": "O",
 "name": "FRIDAY_DISCOUNT",
 "icon": "http://placehold.it/32x32",
 "config": {
 "value": 1000,
 "value_type": "W"
 }
 }
 ],
 "time": "1536672695075",
 "trace_no": "20180911223134Qkgj54",
 "app_key": "9M0gI35ANt7gDicnD02u8D",
 "hmac": "FR/ZWH2Fj6cF5KMyCEqxIOELFVNRFcaPmmQBbAj7N7U="

参考事項

cafe24ネットショップデータの定義および割引適用順序

cafe24ネットショップデータの定義

該当データは、cafe24ネットショップとの連動データです。

cafe24ネットショップデータの定義
項目 説明
割引種類
  • 商品割引
  • 注文割引
適用範囲
  • すべての商品
  • 特定商品
  • 特定カテゴリ
適用方法
  • 商品別の割引
  • 注文単位別の割引
割引種類
  • 定額割引
  • 定率割引
割引適用会員の範囲
  • 非会員+会員
  • 会員
  • 特定会員グループ
割引可能な価格の範囲 購入金額 ~以上
割引可能な購入個数の範囲 購入個数 ~以上

割引適用順序

  • cafe24ネットショップでは、割引アプリをダウンロードし単独で使用することができますが、基本的にはcafe24で提供する割引特典を一緒に使用可能です。
  • アプリ(App)とcafe24ネットショップの割引の計算連関性/特典適用順序は、以下の図をご参考ください。

後続連動

割引特典アプリケーション(App)を通じて生成された注文に対する後続連動が必要な場合、「cafe24 デベロッパー」を通じて提供している注文(order)APIをご参考ください。
(Recipeサービスのオープン後、リアルタイム連動が可能をなる予定です。)

cafe24 デベロッパーAPI案内を見る(API詳細仕様(Admin)