Salesforce B2C カートリッジ実装
Salesforce Commerce Cloud B2C カートリッジ実装
ForterのSalesforce B2C カートリッジを利用することで、Forterとの実装を加速することができます。
カートリッジについて
- ForterのSFCC LINKカートリッジはSFRAと互換性があり、SFRAのベストプラクティスをすべて使用して Salesforce 認定開発者(OSF)によって構築されています。
- Forterのカートリッジは、SFCCの最新バージョン(バージョン22.1、SFRA 6.1、2023年3月現在)だけでなく、レガシーコントローラアーキテクチャとも互換性があります。
- SFCC Partner marketplace から、最新バージョンのForterカートリッジに直接アクセスしてダウンロードすることができます。SFCC LINKアカウントをお持ちでない場合、または旧バージョンのForter SFCCカートリッジが必要な場合は、Forterオンボーディングチームまでお問い合わせください。
📘
注意: Forter SFCC カートリッジのインストールを完了するには、Forter アカウントと認証情報が必要です。
カートリッジインストール: 含まれているもの
ForterのSFCCカートリッジは、SFRAとコントローラの両方に対応するほか、2つの主要コンポーネントが含まれています:
- Int_Forter - Forter のエンドポイントへの API リクエストの生成と配置、Forter JavaScript の挿入、リクエストマッピングテンプレートの提供に必要なコード、ファイル、テンプレートが含まれます。
- Bm_Forter - カートリッジ・ビジネス・マネージャーの機能により、SFCCプラットフォーム・ビジネス・マネージャーに新しく「Forter」セクションが生成されます。このセクションでは、注文ステータス更新の自動化を設定したり、Forterの判定に基づく注文処理方法を選択したり、注文やForterの判定を表示したり、レポートをエクスポートしたりすることができます。
実装
Forterのカートリッジは、ForterのAPIコールの配置の柔軟性と、Forterの判定結果の処理をカスタマイズする機能を加盟店に提供します。以下のステップは、チェックアウト時の判定のためにForterのカートリッジを実装するために必要なインストールフローとステップの概要を示しています。
Step 1: カートリッジのインストールとBMパス設定
- Demandwareサーバーに接続し、[Import]オプションを選択し、[Existing Project into Workspace]オプションを選択します。カートリッジを解凍済みの場合は、[Import Projects] → [アーカイブファイル(または「ルートディレクトリ」)]を選択します。
{/-/}
- ForterカートリッジからMetadataをインポートする。
- カートリッジのMetadataフォルダにsite_templateというzipファイルがあります。
- Administration > Site development > Site Import & Export でzipファイルをアップロードしてください。 そこからアップロードしたzipファイルを選択し、"Import "をクリックし、"OK "をクリックして完了です。
- カートリッジのパス Administration > Sites > Manage Sites でカートリッジを追加するサイトを選択。Settingsタブをクリックし、カートリッジのパス int_forter を追加し、Applyをクリックする。

また、ストアフロントのサイトを選択し、ビジネスマネージャーにカートリッジパスを追加します: Administration > Sites > Manage Sites で Business Manager のリンクをクリックします。

Step 2: Forter認証情報の追加
カートリッジのインポートが完了すると、SFCCストアビジネスマネージャーに新しい "Forter "セクションが表示されます。

設定セクションに移動し、API認証情報を追加します。このセクションでは、カートリッジを有効にし、Forterの認証情報を追加し、Forterの判定(承認と辞退)を受け取った時の処理や注文ステータス更新ジョブの自動化などの設定ができます。
Step 3: APIバージョンの追加
APIのバージョンは、専用のForter管理画面で公開されているバージョンと一致している必要があります。Salesforce BMのMerchant Tools→ Site Preferences に進み、 Forter preference をクリックし、 API Version を検索することでバージョンを調整できます。

Step 4: 決済設定の追加
Forterのカートリッジには、承認された注文を自動的に取り込んだり、辞退された注文を無効にしてキャンセルするなど、Forterの判定に基づく支払いを処理するためのオプションが用意されています。
📘 注意 より詳細な決定処理やカスタマイズは、int_forterディレクトリのコードで行うことができる。
Step 5: Forterの注文セクションの確認
カートリッジをインストールすると、新しい Forter> Orders ページが追加されます。カスタム属性(レコメンデーションや外部注文ステータスなど)を列としてことも可能です

Step 6: 注文ステータス更新ジョブの設定
注文ステータス更新ジョブは、注文ステータスの変更をチェックし、これらの更新を Forter Order Status API エンドポイントに送信します。Forterはこれを6時間ごとに実行するように設定することを推奨します。
外部のOMSを使用し、SFCCプラットフォームにデータを送り返さない場合は、直接API接続する必要があるため、 Order Status API documentation を参照してください。
Step 7: Javascript挿入
Forterのカートリッジは、あなたのサイトのフッターに自動的にスクリプトを挿入します。スクリプトのテンプレートはカートリッジ内にあります。このスクリプトは、チェックアウト時のForterの判定を最適化するための重要なサイバーデータと行動データを収集するために使用されます。スクリプトは顧客からPIIデータを収集することはなく、ページ読み込みや顧客体験に影響を与えないよう、非同期で読み込まれます。
🚧 JS スニペットを修正したり、ストアフロントのスニペットの配置を調整したりしないでください。
Step 8: 判定のタイミングや判定後の処理の設定
Forterのカートリッジは、Pre-Auth(決済が与信のためにPSPに送信される前)またはPost-Auth(決済が与信のためにPSPに送信された後)に判定を返すことができます。また、3DS利用、サイトのポリシー違反(クーポン濫用など)を考慮した判定を返すこともできる。
Pre-Auth + Status
📘 Pre-Auth に必要なデータ Pre-Auth +Statusに必要なデータはこちらを参照してください。
SFRA
SFRA ウェブサイトの場合、CheckoutServices.jsファイルにはデフォルトでコメントアウトされるコードがあります。Pre-Authを有効にするには、このコードのコメントアウト解除する必要があります。

PSP から決済処理結果を受信したら、直ちに forter Order Status API エンドポイントを呼び出して、注文の与信ステータス情報を Forter に送信する必要があります。 以下のサンプルコードは、PSP/決済ゲートウェイからの決済処理結果をForterに送る例です。
var argOrderUpdate = {
orderNumber: orderNumber,
updateAttempt: 1
},
forterCall = require('*/cartridge/scripts/pipelets/forter/forterValidate'),
forterDecision = forterCall.postAuthOrderStatusUpdate(argOrderUpdate, "PROCESSING");
if (forterDecision.result === false && forterDecision.updateAttempt == 2) {
forterDecision.updateAttempt = 2;
forterCall.postAuthOrderStatusUpdate(argOrderUpdate, "PROCESSING");
}📘 Pre-Authの場合、デフォルトの注文ステータスは"CANCELED_BY_MERCHANT" (決済処理が失敗した場合) または "PROCESSING" (決済処理が成功した場合)である必要があります。
Controllers
- Controllersベースのサイトの場合、COPlaceOrder.js と handlepayments(order) 関数を更新します。

- また、失敗した決済処理のために、COPlaceOrder.js の start() 関数を変更する必要があります。

3Dセキュア利用推奨ありのPre-Auth
Pre-Auth+StatusのControllersまたはSFRAと同様の設定をしてください。
また、カートリッジへのAPIレスポンスの一部として、"recommendations"パラメータを処理するロジックを追加する必要があります。"recommendations" の値が"VERIFICATION_REQUIRED_3DS_CHALLENGE"であるとき、3Dセキュア処理を行う必要があります。(以下のコードが、Forterの判定レスポンスの例です。)
"recommendations" の値が"VERIFICATION_REQUIRED_3DS_CHALLENGE"であるとき、3Dセキュア処理を行えるように、決済代行業者との接続をカスタマイズする必要があります。
3Dセキュア処理が必要ないとForterが判定した場合、"approve" または "decline"の判定のみが返却されます。
{
"message": "",
"action": "decline",
"recommendations": [
[
"VERIFICATION_REQUIRED_3DS_CHALLENGE"
]
],
"transaction": "123456",
"status": "success"
}Post-Auth
カートリッジは、デフォルトでPre-Auth処理をするようになっています。Forterの判定を受け取るために、CheckoutServices.js (SFRA) や COIPlaceOrder.js (Controllers) を編集する必要はないですが、決済処理結果のマッピングや、それをForterへ送信する処理を変更する必要があります。
- Forterの判定結果の処理方法設定
- 決済処理が失敗した場合の処理方法をカスタマイズします。
- 注文ステータス更新ジョブを設定する: これは、Forter が注文ステータスを完全に把握できるように、非同期で送信する必要があります。Post-Authの統合では、決済処理結果応答を注文ステータス更新ジョブに含める必要はなく、自動化することができます。
Step 9: 注文データのマッピング
コントローラとSFRAの両方について、Forterのカートリッジには、注文データのマッピングのテンプレートを持つForterOrder.jsファイルが含まれています。チェックアウト時に収集するデータ(請求詳細、カートアイテム、配送情報、支払い方法に関する情報)に基づいてこのファイルを変更する必要があります。
function Authorize(orderNumber, paymentInstrument, paymentProcessor) {
var serverErrors = [],
fieldErrors = {},
error = false;
try {
Transaction.wrap(function() {
paymentInstrument.paymentTransaction.setTransactionID(orderNumber);
paymentInstrument.paymentTransaction.setPaymentProcessor(paymentProcessor);
});
var argCCAuth = {
orderNumber: orderNumber,
PaymentInstrument: paymentInstrument
},
authResponse = doAuth(argCCAuth);
if (authResponse.result === false) {
var argOrderValidate = {
orderNumber: orderNumber,
orderValidateAttemptInput: 1,
request: request
},
forterCall = require('int_forter_sfra/cartridge/scripts/pipelets/forter/ForterValidate'),
forterDecision = forterCall.validateOrder(argOrderValidate);
// in case if no response from Forter, try to call one more time
if (forterDecision.result === false && forterDecision.orderValidateAttemptInput == 2) {
var argOrderValidate = {}
orderNumber: orderNumber, orderValidateAttemptInput: 2,
request: request
},
forterCall = require('int_forter_sfra/cartridge/scripts/pipelets/forter/ForterValidate'), forterDecision = forterCall.validateOrder(argOrderValidate);
error = true;
serverErrors.push(Resource.msg('error.technical', 'checkout', null));
}
if (authResponse.result === true) {
var argOrderValidate = {
orderNumber: orderNumber,
orderValidateAttemptInput: 1,
request: request
},
forterCall = require('int_forter_sfra/cartridge/scripts/pipelets/forter/ForterValidate'),
forterDecision = forterCall.validateOrder(argOrderValidate);
// in case if no response from Forter, try to call one more time
if (forterDecision.result === false && forterDecision.orderValidateAttemptInput == 2) {
var argOrderValidate = {
orderNumber: orderNumber,
orderValidateAttemptInput: 2,
request: request
};
forterCall = require('int_forter_sfra/cartridge/scripts/pipelets/forter/ForterValidate'), forterDecision = forterCall.validateOrder(argOrderValidate);
}
if (forterDecision.JsonResponseOutput.processorAction === 'skipCapture' || forterDecision.JsonResponseOutput.processorAction === 'notReviewed') {
error = false;
} else if (forterDecision.JsonResponseOutput.processorAction === 'disabled' ||
forterDecision.JsonResponseOutput.processorAction === 'internalError' || forterDecision.JsonResponseOutput.processorAction === 'capture') {
var argCCCapture = {
Page 3 - 43
}
}
AuthorizeNetResponse: authResponse.AuthorizeNetResponse, orderNumber: orderNumber,
PaymentInstrument: paymentInstrument
},
captureResponse = doCapture(argCCCapture);
if (captureResponse.result === true) {
error = false;
}
if (captureResponse.result === false) {
var argVoid = {
AuthorizeNetResponse: authResponse.AuthorizeNetResponse,
orderNumber: orderNumber,
PaymentInstrument: paymentInstrument
},
voidResponse = doVoid(argVoid);
error = true;
serverErrors.push(
Resource.msg('error.technical', 'checkout', null));
}
} else {
var argVoid = {
AuthorizeNetResponse: authResponse.AuthorizeNetResponse,
orderNumber: orderNumber,
PaymentInstrument: paymentInstrument
},
voidResponse = doVoid(argVoid);
error = true;
serverErrors.push(
Resource.msg('error.technical', 'checkout', null));
} catch (e) {
error = true;
serverErrors.push(
Resource.msg('error.technical', 'checkout', null)
);
}
return {
fieldErrors: fieldErrors,
serverErrors: serverErrors,
error: error
};
}
function doAuth(argCCAuth) {
var authorizenetCCAuthRequest = require('~/cartridge/scripts/pipelets/AuthorizenetCCAuthRequest'),
authResponse = authorizenetCCAuthRequest.execute(argCCAuth);
return authResponse;
}
function doCapture(argCCCapture) {
var authorizenetCCCaptureRequest = require('~/cartridge/scripts/pipelets/AuthorizenetCCCaptureRequest'),
captureResponse = authorizenetCCCaptureRequest.execute(argCCCapture);
return captureResponse;
}
function doVoid(argVoid) {
var authorizenetVoidRequest = require('~/cartridge/scripts/pipelets/AuthorizenetVoidRequest'),
voidResponse = authorizenetVoidRequest.execute(argVoid);
return voidResponse;
}Step 10: 決済処理結果のマッピング
Forterのモデル精度を最適化するため、カード会社によって拒否された注文(「No Auth」)を含むすべての注文をForterに送信する必要があります。ForterはNoAuth注文を判定しません。NoAuthは "not reviewed "判定を受け取るだけですが、各顧客の行動をよりよく理解するための重要なデータポイントです。決済代行業者からの決済処理結果ををForterに渡すには、ForterOrder.ds ファイルを編集する必要があります。 (以下はそのサンプルコードです。)

👍 クレジットカード注文: ForterCreditCard() 関数の verificationResults と paymentGatewayData オブジェクトは、決済代行業者からのレスポンスを反映するように調整する必要があります
Step 11: 決済処理失敗の場合の処理
Forter ビジネス・マネージャーで設定されたエラーメッセージを処理するために、COPlaceOrder.js を調整してください。

start() 関数に、以下を追加してください。
return {
error: true,
PlaceOrderError: new Status(Status.ERROR, handlePaymentsResult.forterErrorCode ? handlePaymentsResult.forterErrorCode.code : 'confirm.error.technical')
};Step 12: テスト
インストール
カートリッジが正しくインストールされ、設定されているかどうかを確認するには、ストアフロントに行き、登録顧客またはゲスト顧客として、いくつかのテスト注文を行う必要があります。その後、Forter専用ページMerchant Tools > Forter > Ordersで注文状況を確認してください。
判定結果に基づく処理
サンドボックスのSFCCウェブサイトを使用し、登録顧客またはゲストとして注文を行う。サイト設定と判定処理に応じて、テスト支払い(決済成功、決済失敗)に基づく適切な確認ページまたはエラーが表示されるはずです。
拒否された取引の例

また、Forterポータル内のすべての注文や、スキーマやフォーマットのエラーを確認することもできます。