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での装飾や、独自要件の追加実装をします。
次のセクションで、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についても記事にできたらなと思います。
それでは皆様、良いお年をー。