割引アプリガイド

概要

「やさしく簡単に」割引アプリ制作

  • 本ガイドでは割引アプリを手軽に制作できるよう、開発プロセスと動作の仕組みを説明します。
  • また、割引アプリの分かりやすい例示を用いてデータおよびリファレンスを提供し、誰でも効率的に
    アプリを制作することができます。
  • ガイドを活用して割引アプリを制作してみてください。Cafe24では、アプリを開発する中で直面するあらゆる課題の
    解決をサポートします。

アプリ開発の基本情報

アプリ制作のための事前準備については、下記のリンクをご確認ください。

アプリ動作の仕組み

  • 制作したアプリのスクリプト(Script)は、Cafe24ショップのカート/注文書に追加されて割引に必要な基本情報を
    取得します。
  • Cafe24ショップの割引タイプには「商品割引」と「カート割引」の2つがあります。アプリで算定された割引金額は、
    以下の規約に従って「callback」関数で渡します。
  • Cafe24ショップは渡された割引金額に対して検証を行い、実際の決済金額に反映します。

Cafe24とアプリとの動作例を示す「シーケンス・ダイアグラム」

動作プロセス

プロセス
手順 プロセス 内容 参考ページ
1 Cafe24 Front API呼び出し
  • Cafe24が提供するFront APIを活用すると、ショップと会員の基本情報を取得することができます。
    • ショップID、マルチショップの番号、会員ID、ゲストキーなどの基本情報を取得
  • Front APIとグローバル変数は「window.onload」が完了したときにお使いください。
    • 「window.onload」が完了する前までは、変数の値が不完全である可能性があります。
2 割引および「HMAC」
  • 取得した情報を基に様々な割引タイプを実現します。
  • 必須条件:「HMAC」暗号化キーを取得した後、平文データと一緒にレスポンス本文に追加します。
  • 「Cross Domain問題」を避けるために、Response Headerに「("Access-Control-Allow-Origin", "*")」を追加します。
  • 割引ビジネスロジックでCafe24のAPIを呼び出すことは禁止されています。
  • 割引ビジネスロジックが動作する度にCafe24のAPIが呼び出されると、審査に通らない恐れがあります。
3 割引適用
  • レスポンスデータはCafe24のカート/注文書の「Javascript callback」関数である「(AppCallback.setDiscountPrice(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",
    "product_qty": 1,
    "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
[
  {
    "product_qty": 1,
    "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」仕様

  • a. base64_encode(hash_hmac('sha256'、平文データ、Service_key、true));
  • b. アルゴリズムは「sha256」を使用します。
  • c. 「Service_key」はCafe24 Developersから取得したものを使用します。
  • d. 「Service_key」は割引/決済に関するインテグリティチェックのための値で、外部に漏れないようにしてください。
  • e. 「Service_key」が漏洩したか、漏洩が疑われる場合、Cafe24 Developersから再取得してお使いください。
  • f. 「guest_key」値は、会員の場合「md5(member_id)」を、非会員の場合は「EC_GUEST_KEY」をお使いください。
  • g. 「HMAC」の追加方法
    •       - 「guest_key」値は平文データの最後に付けます。
    •       - 「guest_key」値は「HMAC」に暗号化した後、平文データから削除します。
    •       - 平文データの最後に「HMAC」値を追加します。
    •       - PHPでJSONの処理時に「JSON_UNESCAPED_UNICODE| JSON_UNESCAPED_SLASHES」オプションを指定願います。

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
product_qty 数量 string
product_price 商品金額 string
opt_price オプション金額 string
product_sale_price 商品の割引適用金額 string
discount_price 商品の割引金額 string
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 割引設定 JSON Object(or object)
value 割引金額 string
value_type 割引算定タイプ(W:定額, P:定率) string
time 割引リクエスト string
trace_no 追跡番号
  • - 「transaction」別の「key」値
  • - アプリで作成
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",
 "product_qty": 1,
 "product_price": 10000,
 "opt_price": 0,
 "product_sale_price": 10000,
 "discount_price": 0,
 "discount_info": []
 },
 {
 "basket_prd_no": 87,
 "product_no": 21,
 "item_code": "P000000U000B",
 "product_qty": 1,
 "product_price": 20000,
 "opt_price": 0,
 "product_sale_price": 20000,
 "discount_price": 0,
 "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": "1536672695",
 "trace_no": "20180911223134Qkgj54",
 "app_key": "9M0gI35ANt7gDicnD02u8D",
 "hmac": "eOEafN86qA4zh49BkjUAhlB3zF5CqVruBNpS46QTVVs="
}
  • 以下の内容はアプリとcafe24のデータ呼び出し、レスポンスデータの流れを図式化したものです。

サンプルコード

  • 以下の内容はアプリで算定された割引金額が適用される例示になります。
  • この例示を基に作成されたサンプルコードを確認することができます。

割引例示:毎週金曜日にカート割引100円

Front-end

app.js


var SALEAPP_FRONT_FUNCTION = {
    app_do_sale: function (params) {//アプリの割引呼び出しおよび適用
        $.ajax({
            url: "{do_sale_url}",
            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': Math.ceil(new Date().getTime() / 1000)
            },
            success: function (result) {
                console.log('SALE success!');
                AppCallback.setDiscountPrice(JSON.stringify(result));
            }, error: function (e) {
                console.log('SALE error!');
            }
        });
    },

    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;

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







Data

リクエストデータ (var params)
{
    "mall_id": "cafe24_mall",
    "shop_no": "1",
    "member_id": "",
    "guest_key": "9f2c9a3cb0c04a4ff394596ebb23f5cc",
    "member_group_no": "0",
    "time": "1536672695",
    "product": [
        {
            "product_qty": 1,
            "product_no": 20,
            "product_price": 10000,
            "product_sale_price": 100000,
            "opt_price": 0,
            "product_name": "商品A",
            "basket_prd_no": 87,
            "item_code": "P000000U000A"
        },
        {
            "product_qty": 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",
            "product_qty": 1,
            "product_price": 10000,
            "opt_price": 0,
            "product_sale_price": 10000,
            "discount_price": 0,
            "discount_info": []
        },
        {
            "basket_prd_no": 87,
            "product_no": 21,
            "item_code": "P000000U000B",
            "product_qty": 1,
            "product_price": 20000,
            "opt_price": 0,
            "product_sale_price": 20000,
            "discount_price": 0,
            "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": "1536672695",
    "trace_no": "20180911223134Qkgj54",
    "app_key": "9M0gI35ANt7gDicnD02u8D",
    "hmac": "eOEafN86qA4zh49BkjUAhlB3zF5CqVruBNpS46QTVVs="
}

Back-end

https://example.com/sale
public String orderSale(@RequestParam OrderVo orderInfo, HttpServletResponse res) {
  //Cross Domain問題を避けるための必須入力コード
    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);
}

Data

リクエストデータ(OrderVo orderInfo)
{
    "mall_id": "cafe24_mall",
    "shop_no": "1",
    "member_id": "",
    "guest_key": "9f2c9a3cb0c04a4ff394596ebb23f5cc",
    "member_group_no": "0",
    "time": "1536672695",
    "product": [
        {
            "product_qty": 1,
            "product_no": 20,
            "product_price": 10000,
            "product_sale_price": 100000,
            "opt_price": 0,
            "product_name": "商品A",
            "basket_prd_no": 87,
            "item_code": "P000000U000A"
        },
        {
            "product_qty": 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",
            "product_qty": 1,
            "product_price": 10000,
            "opt_price": 0,
            "product_sale_price": 10000,
            "discount_price": 0,
            "discount_info": []
        },
        {
            "basket_prd_no": 87,
            "product_no": 21,
            "item_code": "P000000U000B",
            "product_qty": 1,
            "product_price": 20000,
            "opt_price": 0,
            "product_sale_price": 20000,
            "discount_price": 0,
            "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": "1536672695",
    "trace_no": "20180911223134Qkgj54",
    "app_key": "9M0gI35ANt7gDicnD02u8D",
    "hmac": "eOEafN86qA4zh49BkjUAhlB3zF5CqVruBNpS46QTVVs="
}

Back-end

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;
}

Back-end

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

リクエストデータ(String 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",
            "product_qty": 1,
            "product_price": 10000,
            "opt_price": 0,
            "product_sale_price": 10000,
            "discount_price": 0,
            "discount_info": []
        }
    ],
    "order_discount": [
        {
            "no": "200",
            "price": "1000",
            "apply_product": "P000000U000A"
        }
    ],
    "app_discount_info": [
        {
            "no": 200,
            "type": "O",
            "name": "FRIDAY_DISCOUNT",
            "icon": "http://placehold.it/32x32",
            "config": {
                "value": 1000,
                "value_type": "W"
            }
        }
    ],
    "time": "1536672695",
    "trace_no": "20180911223134Qkgj54",
    "app_key": "9M0gI35ANt7gDicnD02u8D",
    "guest_key": "9f2c9a3cb0c04a4ff394596ebb23f5cc"
}
レスポンスデータ (String cypHmac)
"FR/ZWH2Fj6cF5KMyCEqxIOELFVNRFcaPmmQBbAj7N7U="

参考ページ

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

Cafe24ショップのデータ定義

以下の項目はCafe24ショップに連携されるデータです。

Cafe24ショップのデータ定義
項目 内容
割引算定タイプ
  • 商品割引
  • カート割引
適用範囲
  • すべての商品
  • 特定商品
  • 特定カテゴリ
適用方法
  • 商品単位で割引
  • カート単位で割引
割引タイプ
  • 定額割引
  • 定率割引
割引を適用する会員の範囲
  • 非会員および会員
  • 会員
  • 特定の会員グループ
割引できる価格の範囲 購入金額〇円以上
割引できる購入数量の範囲 購入数量〇点以上

割引の適用順序

  • 割引アプリはCafe24で提供する割引特典と一緒にご利用いただけます。
  • 以下の図式で特典を適用するまでの流れをご確認ください。

追加連携

割引特典アプリケーションで作成された注文に対して追加の連携が必要な場合、cafe24 Developersに掲載の注文(order)APIをご参考ください。
(「Recipe」サービスローンチ後、リアルタイムで連携できるようになります)

cafe24 DevelopersのAPIを見る

次のガイド

リリースガイド

このページはどのくらい役に立ちましたか?
役に立たなかった
役に立った
0文字 入力 /最大300文字