LoginSignup
1

Salesforce B2C Commerce のヘッドレス API を呼んでみる(データ系 API 編)

Last updated at Posted at 2022-03-17

※ これから記載する事項は、私が所属する会社とは一切関係のない事柄です。


この記事はヘッドレス API の使い方のシリーズの一つです。その他の記事は下記を参照してください。


今回は SCAPI と OCAPI のデータ系の API の呼び方を紹介したいと思います。

2 つの分類

SCAPI も OCAPI も大きく分けて 2 つ分類ができます。

  • 顧客がサイトで利用する API (以下、ショッパー系)
  • 管理者が他システムとの連携などで利用する API (以下、データ系)

「ショッパー系」や「データ系」といった分類は公式な分類ではありません。

データ系 API の呼び方

データ系の API を呼ぶ際の基本的な流れは SCAPI も OCAPI も同じです。

1. API クライアントの作成

Add an API Client」 に沿って API クライアントを作成してください。その際に入力画面で、[Roles] には 「Salesforce Commerce API」 ロールと利用するインスタンスを設定してください。また、[Default Scopes] には下記の内容を入力してください。

roles
tenantFilter
openId

そのほかの項目は後ほど説明するのでスキップしてもらって問題ないです。

この時作成した ID とパスワードをメモしておいてください。

2. スコープの設定

a.(SCAPI) Account Manager での設定

上記で作成した API クライアントの詳細画面に遷移し、[Allowed Scopes] の項目に下記の内容をを入力してください。

sfcc.customerlists

他にも追加したいスコープがあればこちらの「スコープ一覧」を参照してください。

b.(OCAPI) Business Manager での設定

Business Manager で 管理 > サイトの開発 > Open Commerce API 設定 に遷移して、今回はデータ系の API なので [タイプの選択] 項目は 「データ」 を選択した上で、下記のような JSON フォーマットで利用するリーソースの権限を設定し、保存してください。JSON のフォーマットに関しては「OCAPI Setting」をご覧ください。

{
    "_v": "21.10",
    "clients": [
        {
            "client_id": "1.で作成したクライアントAPIのUUID",
            "resources": [
                {
                    "methods": [
                        "post"
                    ],
                    "read_attributes": "(**)",
                    "write_attributes": "(**)",
                    "resource_id": "/customer_lists/*/customer_search"
                }
            ]
        }
    ]
}

3. トークンの取得

データ系 API を呼ぶためのアクセストークンの取得方法は2種類あります。

  • 「1. API クライアントの作成」 で取得した ID /パスワードでアクセストークンをリクエストする(ヘルプ
  • JWT を生成してアクセストークンをリクエストする(ヘルプ

a. ID /パスワード

下記のようなリクエストになります。QWxhZGRpbjpvcGVuIHNlc2FtZQ== 部分は ID とパスワードをで : で結合した {ID}:{パスワード} フォーマットを Base64 でエンコードした文字列です。

REQUEST:
POST /dwsso/oauth2/access_token HTTP/1.1
Host: account.demandware.com
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Content-Type: application/x-www-form-urlencoded

REQUEST PARAMETER: 
grant_type=client_credentials

b. JWT

下記のようなリクエストになります。 QeyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...... 部分に生成した JWT を入れてリクエストします。リクエストをする前に証明書の作成や証明書を Account Manager の API クライアントに設定する必要がありますので、「Requesting an access token using a JWT and key pair」を参考にしてください

REQUEST:
POST /dwsso/oauth2/access_token HTTP/1.1
Host: account.demandware.com
Content-Type: application/x-www-form-urlencoded

REQUEST PARAMETER: 
grant_type=client_credentials
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9......

Postman の Pre-request Script で JWT を作成する場合はこのようなコードを利用しましたのでサンプルとして記載しておきます。

var jwtSecret = pm.environment.get('jwtSecret') || ''
var clientID = pm.environment.get('clientID') || ''

var header = {
    'typ': 'JWT',
    'alg': 'RS256'
};

var currentTimestamp = Math.floor(Date.now() / 1000)
var data = {
    'iss': clientID,
    'sub': clientID,
    'aud': "https://account.demandware.com:443/dwsso/oauth2/access_token",
    'exp': currentTimestamp + 30, 
}

function base64url(source) {
    encodedSource = CryptoJS.enc.Base64.stringify(source)
    encodedSource = encodedSource.replace(/=+$/, '')
    encodedSource = encodedSource.replace(/\+/g, '-')
    encodedSource = encodedSource.replace(/\//g, '_')
    return encodedSource
}

function generateJwt() {
    eval(pm.globals.get('jsrsasign-js'));
    var sHeader = JSON.stringify(header);
    var sPayload = JSON.stringify(data);
    var signedToken = KJUR.jws.JWS.sign(header.alg, sHeader, sPayload, jwtSecret);
    pm.environment.set('jwtSigned', signedToken)
    console.log('Signed and encoded JWT', signedToken)
}

var navigator = {}; // fake a navigator object for the lib
var window = {}; // fake a window object for the lib

if (pm.globals.has('jsrsasign-js')) generateJwt();
else pm.sendRequest(
    'https://kjur.github.io/jsrsasign/jsrsasign-all-min.js',
    function (err, res) {
        if (err) {
            console.log(err);
        } else {
            pm.globals.set('jsrsasign-js', res.text());
            generateJwt();
        }});

OCAPI と SCPI でのトークンの取得方法の違い

OCAPI のデータ系の API を呼ぶ場合は上記のままで構わないのですが、 SCAPI の場合はリクエストの中に scope を追加する必要があります。スコープは半角空白区切りで使用します。スコープ sfcc.customerlists を利用する場合、例えばこのような感じです。SALESFORCE_COMMERCE_API は必ず必要となります。

REQUEST:
POST /dwsso/oauth2/access_token HTTP/1.1
Host: account.demandware.com
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Content-Type: application/x-www-form-urlencoded

REQUEST PARAMETER: 
grant_type=client_credentials
&scope=SALESFORCE_COMMERCE_API:{tenantID} sfcc.customerlists

4. データ系 API を呼ぶ

今回は SCAPI、OCAPI 共に顧客の検索を行った時のリクエスト内容を記載します。

その他の API については SCAPI の API ドキュメントの「Shopper〜」から始まっていないもの、 OCAPI の API ドキュメントの Data API をご参照ください。

  • token は上記でアクセストークンリクエストした際に返ってくるレスポンスボディの中の access_token の内容を利用してください。
  • customerListID については Business Manager の 管理 > サイト > 顧客リスト から ID をご確認ください。

SCAPI

REQUEST:
POST /customer/customers/v1/organizations/{orgID}/customer-lists/{customerListID}/customer-search HTTP/1.1
Host: {shortCode}.api.commercecloud.salesforce.com
Authorization: Bearer {token}
Content-Type: application/json

REQUEST BODY:
{
  "limit": 5,
  "query": {
    "textQuery": {
      "fields": [
        "first_name"
      ],
      "searchPhrase": "だ"
    }
  },
  "offset": 0
}

OCAPI

REQUEST:
POST /s/-/dw/data/v21_10/customer_lists/{customerListID}/customer_search HTTP/1.1
Host: {利用しているサンドボックスのドメイン}
Authorization: Bearer {token}
Content-Type: application/json

BODY:
{
    "query": {
        "text_query": {
            "fields": ["first_name"],
            "search_phrase": "だ"
        }
    }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1