LoginSignup
5
1

More than 3 years have passed since last update.

B2C CommerceCloud から CoreのAPIを呼び出す

Last updated at Posted at 2020-12-24

B2C CommerceCloud(以下B2CC)のSFRAを利用してサイトを拡張する際に、Coreとの連携や、外部システムのAPIを利用する、ということはよくあることと思います(B2CCだからってこともないですが)

そこで参考にしやすいシンプルなPluginカートリッジ(Service Cloud Connector
)があったのでその紹介とともに、SFRAのカスタマイズ方法について少し触れていきたいと思います。
※例の如く、B2C CommerceCloudアカウントが無いと、上記Githubリポジトリは参照できません。。。
ソースコードの全量がみたい!という方がいればひっそりコンタクトください
※Pluginカートリッジは、B2CCが提供しているカートリッジです。他にもWishlistや店舗受け取り機能を付与するカートリッジなどがあります。

概要

service cloud connector は B2C Commerceの case/customer/order/shipment/payment などのデータをService CloudにRestを利用して連携する機能を持ったPluginカーリッジです。SalesforceからB2C Commerceへは B2C Commerce Open Commerce API (OCAPI)を利用して、データを連携します。

今回は、B2CCからCore側のRestAPIを呼び出す部分を紹介します。

SFRAの拡張方法

B2C CommerceのSFRA(Storefront Reference Architecture) では 基本的な機能を実装している baseカートリッジが提供されており、そこからcustomカートリッジやPluginカートリッジなどの利用し、機能を拡張していきます。
TOP、PLP、PDP、カート、チェックアウト(決済は含まず)などの、ECの基本的な機能は、baseカートリッジで実装されており、そこに、CSSでの装飾や、独自要件の追加実装をします。

参考:SFRA Architecture

次のセクションで、baseカートリッジのソースと、PlugInカートリッジのソースコードの一部を記載します。

実際のソースコード

Controller

Order.js(baseカートリッジ)
Confirmメソッドは、注文の確定時に呼び出される処理で、エラーが無ければ、注文確定画面への遷移が行われます。

ファイルパス
/cartridges/app_storefront_base/cartridge/controllers/Order.js

server.get(
    'Confirm',
    consentTracking.consent,
    server.middleware.https,
    csrfProtection.generateToken,
    function (req, res, next) {
        var reportingUrlsHelper = require('*/cartridge/scripts/reportingUrls');
        var OrderMgr = require('dw/order/OrderMgr');
        var OrderModel = require('*/cartridge/models/order');
        var Locale = require('dw/util/Locale');
        var order = OrderMgr.getOrder(req.querystring.ID);
        var token = req.querystring.token ? req.querystring.token : null;
        if (!order
            || !token
            || token !== order.orderToken
            || order.customer.ID !== req.currentCustomer.raw.ID
        ) {
            res.render('/error', {
                message: Resource.msg('error.confirmation.error', 'confirmation', null)
            });

            return next();
        }

    // 〜〜省略〜〜

        return next();
    }
);

Order.js(PlugInカートリッジ)
Pluginカートリッジのフォルダ構成は、baseカートリッジと同一にして、同じ場所に該当ファイルを配置します。

ファイルパス
/cartridges/plugin_service_cloud/cartridge/controllers/Order.js
plugin_service_cloud が カートリッジ名で、それ以下のフォルダ構成がbaseカートリッジと同一になっています。

var server = require('server');
server.extend(module.superModule);

//server.append で baseカートリッジのConfirmに処理を追加しています。
server.append('Confirm', function (req, res, next) {
    var OrderMgr = require('dw/order/OrderMgr');
    var order = OrderMgr.getOrder(req.querystring.ID);
    // hookを利用して、apiを呼び出します。
    require('dw/system/HookMgr').callHook('app.order.created', 'created', order);

    next();
});

server.append('CreateAccount', function (req, res, next) {
    this.on('route:Complete', function (requ, resp) {
        if(customer.authenticated){
            require('dw/system/HookMgr').callHook('app.account.created', 'created', customer);
        }
    });
    next();
});

module.exports = server.exports();

拡張の詳細についてはこちらのヘルプ

Api コール部分

認証情報(接続アプリケーションの情報など)は、BuisinessManagerの設定で保持しています。
カスタム表示ラベルやカスタムメタデータ型をイメージしてもらうとそれが近いかもしれません。

処理としては、Restを呼び出し、呼び出し後、結果を元に、B2CCの注文情報を更新しています(連携済みステータスに更新)

/cartridges/int_service_cloud/cartridge/scripts/hooks/customerOrder.js

~~~省略~~~
/**
 * This method will export the given {order} details to Service Cloud through REST API
 * If the async mode is disabled
 *
 * @param {dw.order.Order} order
 * @param {String} status
 */
function handleExport(order, status) {
    var svc;
    var endpoint;

    // Retrieve the current site and it's operation-mode value
    var Site = require('dw/system/Site').getCurrent();
    var isSyncMode = Site.getCustomPreferenceValue('sscIsAsync');

    // Exit early if we're not running in asynchronous-mode
    if (!isSyncMode) { return; }

    var sccOrderModel = new (require('../models/order'))(order);

    svc = ServiceMgr.restCreate();
    endpoint = ServiceMgr.restEndpoints.create.order;

    // Check if the svc variable is not undefined
    // Cannot use empty() as empty(svc) returns false even if the service is correctly initialized
    if (typeof svc === 'undefined' || empty(endpoint)) {
        return;
    }

    sccOrderModel.updateStatus(status);

    // ServiceMgr.restEndpoints.create.order は CoreのEndpointの services/apexrest/Order/Placement です
    var result = svc.call(ServiceMgr.restEndpoints.create.order, JSON.stringify(sccOrderModel));

    if (result.status === 'OK') {
        if (result.object && !result.object.isError && !result.object.isAuthError) {
            sccOrderModel.updateStatus('exported');
            sccOrderModel.updateExternalId(result.object.responseObj.recordId);
            sccOrderModel.updateSyncResponseText('Successfully Exported');
        } else {
            sccOrderModel.updateSyncResponseText(result.object.errorText);
        }
    } else {
        sccOrderModel.updateSyncResponseText(result.msg);
    }

}
exports.created = orderCreated;

SalesforceRestAPIのendpointを定義しているクラスや、パラメータのmodelクラスなどは別途あり、それらを呼び出しているクラスです。
※長いので一部処理を消しています。

svc.callでRestAPIを実行していますが、変数svcは、B2CCが提供しているライブラリ(dw/svc/LocalServiceRegistry)と、前述の認証情報を元に定義されています。

ちなみにですが、APIのリクエスト情報にカスタム情報を追加したい場合は、はCCのModel(パラメータ定義
クラス)を更新しつつ、Core側のカスタムメタデータ型で管理しているマッピング情報を追加すれば追加できます。

まとめ

かんたんではありますが、Pluginカートリッジの紹介と、B2CCのカスタマイズやAPI連携部分の紹介をしてみました。
このように、B2CCのSFRAでは、すべての処理を0から作成するのではなく、ベースの処理を拡張するような形で開発を行います。今回紹介したのはPluginカートリッジですが、自身でカスタマイズする際に作るカスタムカートリッジでもそれは同様です。

今回は紹介していませんが、B2CCが提供しているAPI、Open Commerce APIや、新しく提供されているcommerce apiについても記事にできたらなと思います。

それでは皆様、良いお年をー。

5
1
0

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
5
1