MFRA統合
アカウント MFRA 統合
アカウント SFRA
このセクションでは、SFRA/MFRA 構造に基づいて Forter カートリッジを統合する方法について説明します。このセクションでは、影響を受けるすべてのコントローラーのリストを提供します。カートリッジをストアフロントアプリケーションに統合することは、コアカートリッジの変更を意味しません。ファイルを上書きする標準の SFRA/MFRA アプローチを使用する必要があります。
SFCC ストアフロントアプリケーションに同じコントローラーまたはテンプレートが拡張または置き換えられている場合、すべての言及されたコード変更は必須であり、トップレベルのカートリッジに追加する必要があります。
1) Account.js ファイル
以下のコード変更を Account.js ファイルの int_forter_mfra セクションに含めてください。account.js への正確なパスは: Cartridges > int_forter_mfra > cartridge > controllers > Account.js
CUSTOMER_LOGIN(次のコードを含む「ログイン」を置き換えます)
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_LOGIN
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);顧客作成 (`SubmitRegistration’を次のコードを含むもので置き換えます):
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_CREATE
}
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);顧客プロフィール更新 (‘SaveProfile’を次のコードを含むもので置き換えます):
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_PROFILE_UPDATE
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);Complete Account.js (including changes to override code)
'use strict';
// Local Modules
var server = require('server');
server.extend(module.superModule);
var csrfProtection = require('*/cartridge/scripts/middleware/csrf');
server.replace(
'Login',
server.middleware.https,
csrfProtection.validateAjaxRequest,
function (req, res, next) {
var Transaction = require('dw/system/Transaction');
var CustomerMgr = require('dw/customer/CustomerMgr');
var Resource = require('dw/web/Resource');
var URLUtils = require('dw/web/URLUtils');
var email = req.form.loginEmail;
var password = req.form.loginPassword;
var rememberMe = req.form.loginRememberMe
? (!!req.form.loginRememberMe)
: false;
var authenticatedCustomer;
var checkoutLogin = req.querystring.checkoutLogin;
Transaction.wrap(function () {
authenticatedCustomer = CustomerMgr.loginCustomer(email, password, rememberMe);
});
if (authenticatedCustomer && authenticatedCustomer.authenticated) {
// *************** add the replacement 'Login' code: ******************
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_LOGIN
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);
// ****************** end of included 'Login' code ******************
res.setViewData({ authenticatedCustomer: authenticatedCustomer });
res.json({
success: true,
redirectUrl: checkoutLogin
? URLUtils.url('Checkout-Begin').toString()
: URLUtils.url('Account-Show').toString()
});
} else {
res.json({ error: [Resource.msg('error.message.login.form', 'login', null)] });
}
return next();
});
server.replace(
'SubmitRegistration',
server.middleware.https,
csrfProtection.validateAjaxRequest,
function (req, res, next) {
var CustomerMgr = require('dw/customer/CustomerMgr');
var Resource = require('dw/web/Resource');
var formErrors = require('*/cartridge/scripts/formErrors');
var registrationForm = server.forms.getForm('profile');
// form validation
if (registrationForm.customer.email.value.toLowerCase()
!== registrationForm.customer.emailconfirm.value.toLowerCase()
) {
registrationForm.customer.email.valid = false;
registrationForm.customer.emailconfirm.valid = false;
registrationForm.customer.emailconfirm.error =
Resource.msg('error.message.mismatch.email', 'forms', null);
registrationForm.valid = false;
}
if (registrationForm.login.password.value
!== registrationForm.login.passwordconfirm.value
) {
registrationForm.login.password.valid = false;
registrationForm.login.passwordconfirm.valid = false;
registrationForm.login.passwordconfirm.error =
Resource.msg('error.message.mismatch.password', 'forms', null);
registrationForm.valid = false;
}
if (!CustomerMgr.isAcceptablePassword(registrationForm.login.password.value)) {
registrationForm.login.password.valid = false;
registrationForm.login.passwordconfirm.valid = false;
registrationForm.login.passwordconfirm.error =
Resource.msg('error.message.password.constraints.not.matched', 'forms', null);
registrationForm.valid = false;
}
// setting variables for the BeforeComplete function
var registrationFormObj = {
firstName: registrationForm.customer.firstname.value,
lastName: registrationForm.customer.lastname.value,
phone: registrationForm.customer.phone.value,
email: registrationForm.customer.email.value,
emailConfirm: registrationForm.customer.emailconfirm.value,
password: registrationForm.login.password.value,
passwordConfirm: registrationForm.login.passwordconfirm.value,
validForm: registrationForm.valid,
form: registrationForm
};
if (registrationForm.valid) {
res.setViewData(registrationFormObj);
this.on('route:BeforeComplete', function (req, res) { // eslint-disable-line no-shadow
var Transaction = require('dw/system/Transaction');
var URLUtils = require('dw/web/URLUtils');
// getting variables for the BeforeComplete function
var registrationForm = res.getViewData(); // eslint-disable-line
if (registrationForm.validForm) {
var login = registrationForm.email;
var password = registrationForm.password;
var authenticatedCustomer;
// attempt to create a new user and log that user in.
try {
Transaction.wrap(function () {
var newCustomer = CustomerMgr.createCustomer(login, password);
if (newCustomer) {
// assign values to the profile
var newCustomerProfile = newCustomer.getProfile();
authenticatedCustomer =
CustomerMgr.loginCustomer(login, password, false);
newCustomerProfile.firstName = registrationForm.firstName;
newCustomerProfile.lastName = registrationForm.lastName;
newCustomerProfile.phoneHome = registrationForm.phone;
newCustomerProfile.email = registrationForm.email;
}
if (authenticatedCustomer === undefined) {
registrationForm.validForm = false;
registrationForm.form.customer.email.valid = false;
registrationForm.form.customer.emailconfirm.valid = false;
}
});
} catch (e) {
registrationForm.validForm = false;
registrationForm.form.customer.email.valid = false;
registrationForm.form.customer.email.error =
Resource.msg('error.message.username.invalid', 'forms', null);
}
}
delete registrationForm.password;
delete registrationForm.passwordConfirm;
formErrors.removeFormValues(registrationForm.form);
if (registrationForm.validForm) {
// *************** add the replacement 'CUSTOMER_CREATE' code: ******************
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_CREATE
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);
// *************** add the replacement 'Login' code: ******************
res.setViewData({ authenticatedCustomer: authenticatedCustomer });
res.json({
success: true,
redirectUrl: URLUtils.url('Account-Show',
'registration', 'submitted'
).toString()
});
} else {
res.json({
fields: formErrors.getFormErrors(registrationForm)
});
}
});
} else {
res.json({
fields: formErrors.getFormErrors(registrationForm)
});
}
return next();
});
server.replace(
'SaveProfile',
server.middleware.https,
csrfProtection.validateAjaxRequest,
function (req, res, next) {
var Transaction = require('dw/system/Transaction');
var CustomerMgr = require('dw/customer/CustomerMgr');
var Resource = require('dw/web/Resource');
var URLUtils = require('dw/web/URLUtils');
var formErrors = require('*/cartridge/scripts/formErrors');
var profileForm = server.forms.getForm('profile');
// form validation
if (profileForm.customer.email.value.toLowerCase()
!== profileForm.customer.emailconfirm.value.toLowerCase()) {
profileForm.valid = false;
profileForm.customer.email.valid = false;
profileForm.customer.emailconfirm.valid = false;
profileForm.customer.emailconfirm.error =
Resource.msg('error.message.mismatch.email', 'forms', null);
}
var result = {
firstName: profileForm.customer.firstname.value,
lastName: profileForm.customer.lastname.value,
phone: profileForm.customer.phone.value,
email: profileForm.customer.email.value,
confirmEmail: profileForm.customer.emailconfirm.value,
password: profileForm.login.password.value,
profileForm: profileForm
};
if (profileForm.valid) {
res.setViewData(result);
this.on('route:BeforeComplete', function (req, res) { // eslint-disable-line no-shadow
var formInfo = res.getViewData();
var customer = CustomerMgr.getCustomerByCustomerNumber(
req.currentCustomer.profile.customerNo
);
var profile = customer.getProfile();
var customerLogin;
var status;
Transaction.wrap(function () {
status = profile.credentials.setPassword(
formInfo.password,
formInfo.password,
true
);
if (status.error) {
formInfo.profileForm.login.password.valid = false;
formInfo.profileForm.login.password.error =
Resource.msg('error.message.currentpasswordnomatch', 'forms', null);
} else {
customerLogin = profile.credentials.setLogin(
formInfo.email,
formInfo.password
);
}
});
delete formInfo.password;
delete formInfo.confirmEmail;
if (customerLogin) {
Transaction.wrap(function () {
profile.setFirstName(formInfo.firstName);
profile.setLastName(formInfo.lastName);
profile.setEmail(formInfo.email);
profile.setPhoneHome(formInfo.phone);
});
delete formInfo.profileForm;
delete formInfo.email;
// *************** add the replacement 'CUSTOMER_PROFILE_UPDATE' code: ******************
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_PROFILE_UPDATE
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);
// *************** end 'CUSTOMER_PROFILE_UPDATE' code: ******************
res.json({
success: true,
redirectUrl: URLUtils.url('Account-Show').toString()
});
} else {
if (!status.error) {
formInfo.profileForm.customer.email.valid = false;
formInfo.profileForm.customer.email.error =
Resource.msg('error.message.username.invalid', 'forms', null);
}
delete formInfo.profileForm;
delete formInfo.email;
res.json({
success: false,
fields: formErrors.getFormErrors(profileForm)
});
}
});
} else {
res.json({
success: false,
fields: formErrors.getFormErrors(profileForm)
});
}
return next();
});
module.exports = server.exports();2) Address.jsファイル
以下のコード変更を Address.js ファイルの int_forter_mfra セクションに含めてください。account.js への正確なパスは次のとおりです: Cartridges > int_forter_mfra > cartridge > controllers > Address.js 完全な Address.js ファイルも以下に含まれています
CUSTOMER_ADDRESS_UPDATE('List'を以下のコードに置き換えます)
`Address.js` ファイルに以下のコードを含めてください
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_ADDRESS_UPDATE
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);完全な Address.js ファイル
'use strict';
//ローカルモジュール
var server = require('server');
server.extend(module.superModule);
server.append('List', function (req, res, next) {
// *************** 置き換え `CUSTOMER_ADDRESS_UPDATE` コードを追加: ******************
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_ADDRESS_UPDATE
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);
// *************** 含まれている 'CUSTOMER_ADDRESS_UPDATE` コードの終わり: ******************
next();
});
module.exports = server.exports();3) Login.js ファイル
以下のコード変更を Login.js ファイルの int_forter_mfra セクションに含めてください。account.js への正確なパスは: Cartridges > int_forter_mfra > cartridge > controllers > Login.js 完全な Login.js ファイルも以下に含まれています:
CUSTOMER_LOGOUT (次のコードを含めることで「Logout」を前置します)
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_LOGOUT
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);完全な Login.Js ファイル
'use strict';
//ローカルモジュール
var server = require('server');
server.extend(module.superModule);
server.prepend('Logout', function (req, res, next) {
// *************** 置き換え `CUSTOMER_LOGOUT` コードを追加: ******************
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_LOGOUT
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);
// *************** `CUSTOMER_LOGOUT` コードの終了: ******************
next();
});
module.exports = server.exports();4) PaymentInstruments.js ファイル
以下のコード変更を PaymentInstrument.js ファイルの int_forter_mfra セクションに含めてください。account.js への正確なパスは: Cartridges > int_forter_mfra > cartridge > controllers > PaymentInstrument.js 完全な PaymentInstrument.js ファイルも以下に含まれています:
CUSTOMER_PAYMENT_UPDATE (次のコードを含めることで「List」を追加します)
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_PAYMENT_UPDATE
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);全額支払いInstrument.jsファイル
'use strict';
//Local Modules
var server = require('server');
server.extend(module.superModule);
var csrfProtection = require('*/cartridge/scripts/middleware/csrf');
/**
* Checks if a credit card is valid or not
* @param {Object} card - plain object with card details
* @param {Object} form - form object
* @returns {boolean} a boolean representing card validation
*/
function verifyCard(card, form) {
var collections = require('*/cartridge/scripts/util/collections');
var Resource = require('dw/web/Resource');
var PaymentMgr = require('dw/order/PaymentMgr');
var PaymentStatusCodes = require('dw/order/PaymentStatusCodes');
var paymentCard = PaymentMgr.getPaymentCard(card.cardType);
var error = false;
var cardNumber = card.cardNumber;
var creditCardStatus;
var formCardNumber = form.cardNumber;
if (paymentCard) {
creditCardStatus = paymentCard.verify(
card.expirationMonth,
card.expirationYear,
cardNumber
);
} else {
formCardNumber.valid = false;
formCardNumber.error =
Resource.msg('error.message.creditnumber.invalid', 'forms', null);
error = true;
}
if (creditCardStatus && creditCardStatus.error) {
collections.forEach(creditCardStatus.items, function (item) {
switch (item.code) {
case PaymentStatusCodes.CREDITCARD_INVALID_CARD_NUMBER:
formCardNumber.valid = false;
formCardNumber.error =
Resource.msg('error.message.creditnumber.invalid', 'forms', null);
error = true;
break;
case PaymentStatusCodes.CREDITCARD_INVALID_EXPIRATION_DATE:
var expirationMonth = form.expirationMonth;
var expirationYear = form.expirationYear;
expirationMonth.valid = false;
expirationMonth.error =
Resource.msg('error.message.creditexpiration.expired', 'forms', null);
expirationYear.valid = false;
error = true;
break;
default:
error = true;
}
});
}
return error;
}
/**
* Creates an object from form values
* @param {Object} paymentForm - form object
* @returns {Object} a plain object of payment instrument
*/
function getDetailsObject(paymentForm) {
return {
name: paymentForm.cardOwner.value,
cardNumber: paymentForm.cardNumber.value,
cardType: paymentForm.cardType.value,
expirationMonth: paymentForm.expirationMonth.value,
expirationYear: paymentForm.expirationYear.value,
paymentForm: paymentForm
};
}
server.append('List', function (req, res, next) {
// *************** add the replacement `CUSTOMER_PAYMENT_UPDATE` code: ******************
var argCustomerUpdate = {
EventType : require('~/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig.CUSTOMER_PAYMENT_UPDATE
},
forterCall = require('~/cartridge/scripts/pipelets/forter/ForterCustomerUpdate');
forterCall.execute(argCustomerUpdate);
// *************** end the replacement `CUSTOMER_PAYMENT_UPDATE` code: ******************
next();
});
server.replace(
'SavePayment',
csrfProtection.validateAjaxRequest,
function (req, res, next) {
var formErrors = require('*/cartridge/scripts/formErrors');
var HookMgr = require('dw/system/HookMgr');
var PaymentMgr = require('dw/order/PaymentMgr');
var dwOrderPaymentInstrument = require('dw/order/PaymentInstrument');
var paymentForm = server.forms.getForm('creditCard');
var result = getDetailsObject(paymentForm);
if (paymentForm.valid && !verifyCard(result, paymentForm)) {
res.setViewData(result);
this.on('route:BeforeComplete', function (req, res) { // eslint-disable-line no-shadow
var URLUtils = require('dw/web/URLUtils');
var CustomerMgr = require('dw/customer/CustomerMgr');
var Transaction = require('dw/system/Transaction');
var formInfo = res.getViewData();
var customer = CustomerMgr.getCustomerByCustomerNumber(
req.currentCustomer.profile.customerNo
);
var wallet = customer.getProfile().getWallet();
Transaction.wrap(function () {
var paymentInstrument = wallet.createPaymentInstrument('CREDIT_CARD');
paymentInstrument.setCreditCardHolder(formInfo.name);
paymentInstrument.setCreditCardNumber(formInfo.cardNumber);
paymentInstrument.setCreditCardType(formInfo.cardType);
paymentInstrument.setCreditCardExpirationMonth(formInfo.expirationMonth);
paymentInstrument.setCreditCardExpirationYear(formInfo.expirationYear);
//The basic random tokenization makes impossible to get a raw CC number for Forter call.
/*
var processor = PaymentMgr.getPaymentMethod(dwOrderPaymentInstrument.METHOD_CREDIT_CARD).getPaymentProcessor();
var token = HookMgr.callHook(
'app.payment.processor.' + processor.ID.toLowerCase(),
'createMockToken'
);
paymentInstrument.setCreditCardToken(token);*/
});
res.json({
success: true,
redirectUrl: URLUtils.url('PaymentInstruments-List').toString()
});
});
} else {
res.json({
success: false,
fields: formErrors.getFormErrors(paymentForm)
});
}
return next();
});
module.exports = server.exports();5) CheckoutServices.js
「CheckoutServices.js」ファイルは、Forterビジネスマネージャー拡張機能で設定されたカスタマイズされたエラーメッセージを処理するために、以下のコードで「PlaceOrder」を置き換えます:
if (ForterConfig.forterShowDeclinedPage == true && !empty(ForterConfig.forterCustomDeclineMessage)) {
res.json({
error: true,
errorMessage: ForterConfig.forterCustomDeclineMessage
});
}Complete CheckoutServices.js file
'use strict';
var server = require('server');
server.extend(module.superModule);
var COHelpers = require('*/cartridge/scripts/checkout/checkoutHelpers');
var csrfProtection = require('*/cartridge/scripts/middleware/csrf');
var ForterConfig = require('int_forter_mfra/cartridge/scripts/lib/forter/ForterConfig.ds').ForterConfig;
server.replace('PlaceOrder', server.middleware.https, function (req, res, next) {
var BasketMgr = require('dw/order/BasketMgr');
var HookMgr = require('dw/system/HookMgr');
var OrderMgr = require('dw/order/OrderMgr');
var Resource = require('dw/web/Resource');
var Transaction = require('dw/system/Transaction');
var URLUtils = require('dw/web/URLUtils');
var basketCalculationHelpers = require('*/cartridge/scripts/helpers/basketCalculationHelpers');
var currentBasket = BasketMgr.getCurrentBasket();
if (!currentBasket) {
res.json({
error: true,
cartError: true,
fieldErrors: [],
serverErrors: [],
redirectUrl: URLUtils.url('Cart-Show').toString()
});
return next();
}
if (req.session.privacyCache.get('fraudDetectionStatus')) {
res.json({
error: true,
cartError: true,
redirectUrl: URLUtils.url('Error-ErrorCode', 'err', '01').toString(),
errorMessage: Resource.msg('error.technical', 'checkout', null)
});
return next();
}
var validationBasketStatus = HookMgr.callHook(
'app.validate.basket',
'validateBasket',
currentBasket,
false
);
if (validationBasketStatus.error) {
res.json({
error: true,
errorMessage: validationBasketStatus.message
});
return next();
}
// Check to make sure there is a shipping address
if (currentBasket.defaultShipment.shippingAddress === null) {
res.json({
error: true,
errorStage: {
stage: 'shipping',
step: 'address'
},
errorMessage: Resource.msg('error.no.shipping.address', 'checkout', null)
});
return next();
}
// Check to make sure billing address exists
if (!currentBasket.billingAddress) {
res.json({
error: true,
errorStage: {
stage: 'payment',
step: 'billingAddress'
},
errorMessage: Resource.msg('error.no.billing.address', 'checkout', null)
});
return next();
}
// Calculate the basket
Transaction.wrap(function () {
basketCalculationHelpers.calculateTotals(currentBasket);
});
// Re-validates existing payment instruments
var validPayment = COHelpers.validatePayment(req, currentBasket);
if (validPayment.error) {
res.json({
error: true,
errorStage: {
stage: 'payment',
step: 'paymentInstrument'
},
errorMessage: Resource.msg('error.payment.not.valid', 'checkout', null)
});
return next();
}
// Re-calculate the payments.
var calculatedPaymentTransactionTotal = COHelpers.calculatePaymentTransaction(currentBasket);
if (calculatedPaymentTransactionTotal.error) {
res.json({
error: true,
errorMessage: Resource.msg('error.technical', 'checkout', null)
});
return next();
}
// Creates a new order.
var order = COHelpers.createOrder(currentBasket);
if (!order) {
res.json({
error: true,
errorMessage: Resource.msg('error.technical', 'checkout', null)
});
return next();
}
// Handles payment authorization
var handlePaymentResult = COHelpers.handlePayments(order, order.orderNo);
if (handlePaymentResult.error) {
// *************** include `custome message` code: ******************
if (ForterConfig.forterShowDeclinedPage == true && !empty(ForterConfig.forterCustomDeclineMessage)) {
res.json({
error: true,
errorMessage: ForterConfig.forterCustomDeclineMessage
});
} else {
res.json({
error: true,
errorMessage: Resource.msg('error.technical', 'checkout', null)
});
}
// *************** end `custom message` code: ******************
return next();
}
var fraudDetectionStatus = HookMgr.callHook('app.fraud.detection', 'fraudDetection', currentBasket);
if (fraudDetectionStatus.status === 'fail') {
Transaction.wrap(function () { OrderMgr.failOrder(order); });
// fraud detection failed
req.session.privacyCache.set('fraudDetectionStatus', true);
res.json({
error: true,
cartError: true,
redirectUrl: URLUtils.url('Error-ErrorCode', 'err', fraudDetectionStatus.errorCode).toString(),
errorMessage: Resource.msg('error.technical', 'checkout', null)
});
return next();
}
// Places the order
var placeOrderResult = COHelpers.placeOrder(order, fraudDetectionStatus);
if (placeOrderResult.error) {
res.json({
error: true,
errorMessage: Resource.msg('error.technical', 'checkout', null)
});
return next();
}
COHelpers.sendConfirmationEmail(order, req.locale.id);
// Reset usingMultiShip after successful Order placement
req.session.privacyCache.set('usingMultiShipping', false);
TODO
res.json({
error: false,
orderID: order.orderNo,
orderToken: order.orderToken,
continueUrl: URLUtils.url('Order-Confirm').toString()
});
return next();
});
module.exports = server.exports();ForterConfig.forterCustomDeclineMessage (次のコードを含む‘PlaceOrder’を置き換えます)