Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cartridges/int_marketpay_headless/caches.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"caches": [
{
"id": "marketPayRestOauthToken",
"expireAfterSeconds": 3500
}
]
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict';

const Logger = require('dw/system/Logger');
const Site = require('dw/system/Site');

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

const Logger = require('dw/system/Logger');

exports.afterPOST = function (basketId) {

var HookMgr = require('dw/system/HookMgr');

if (HookMgr.hasHook('dw.order.createOrderNo')) {
var orderNo = HookMgr.callHook('dw.order.createOrderNo', 'createOrderNo');
Logger.info("MarketPayOrderNo Created via hook: " + orderNo);
} else {
Logger.error("dw.order.createOrderNo hook not found");
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,8 @@

const Site = require('dw/system/Site');
const Logger = require('dw/system/Logger');
const BasketMgr = require('dw/order/BasketMgr');
const Transaction = require('dw/system/Transaction');

exports.afterPOST = function (basketId) {

Logger.info("basket afterPost Called ");

var HookMgr = require('dw/system/HookMgr');

if (HookMgr.hasHook('dw.order.createOrderNo')) {
var orderNo = HookMgr.callHook('dw.order.createOrderNo', 'createOrderNo');
Logger.info("MarketPayOrderNo Created via hook: " + orderNo);
} else {
Logger.error("dw.order.createOrderNo hook not found");
}
}

exports.modifyGETResponse_v2 = function (basket, paymentMethodResultResponse) {

Expand All @@ -26,7 +13,7 @@ exports.modifyGETResponse_v2 = function (basket, paymentMethodResultResponse) {
const marketPayDataHelper = require('*/cartridge/scripts/helpers/marketPayDataHelper');

var marketPayTokenAndSession = marketPayService.getTokenAndSessionId(marketPayDataHelper.getFormattedDataForMarketPaySession(basket));
var marketPayPaymentMethods = marketPayService.getPaymentMethods(marketPayTokenAndSession.token, marketPayTokenAndSession.sessionId);
var marketPayPaymentMethods = marketPayService.getPaymentMethods(marketPayTokenAndSession.sessionId);

const site = require('*/cartridge/scripts/helpers/site.js');
var marketPayTerminalsMapping = site.getCustomPreference('marketpayTerminals');
Expand Down Expand Up @@ -97,8 +84,7 @@ exports.modifyGETResponse_v2 = function (basket, paymentMethodResultResponse) {
var paymentMethod = marketPayPaymentMethods.methods[k];
if (paymentMethod.metadata && paymentMethod.metadata.terminalName === terminalMapping.name) {
// Include the matched payment method
method.c_marketPay = {
access_token: marketPayTokenAndSession.token,
method.c_marketPay = {
sessionId: marketPayTokenAndSession.sessionId,
paymentMethod: paymentMethod
}
Expand All @@ -121,46 +107,60 @@ exports.modifyGETResponse_v2 = function (basket, paymentMethodResultResponse) {
}
};

exports.modifyPOSTResponse = function(basket, basketResponse, paymentInstrumentRequest ) {
exports.afterPOST = function (basket, paymentInstrument) {

Logger.info("MarketPay: payment instrument modifyPOSTREsponse ");
Logger.info("basket afterPOST Called ");

var paymentInstrumentRequest = paymentInstrument;
var basketResponse = basket;

const marketPayService = require('*/cartridge/scripts/services/marketPay');
const marketPayDataHelper = require('*/cartridge/scripts/helpers/marketPayDataHelper');

if (paymentInstrumentRequest.c_marketpayPaymentMethodID &&
paymentInstrumentRequest.c_marketPayToken &&
paymentInstrumentRequest.c_marketPaySessionID) {
if (paymentInstrumentRequest.c_marketPayPaymentMethodID &&
paymentInstrumentRequest.c_marketPaySessionID &&
paymentInstrumentRequest.c_marketPayOnInitiatePaymentURL) {

Logger.info("c_marketpayPaymentMethodID: " + paymentInstrumentRequest.c_marketpayPaymentMethodID);
Logger.info("c_marketPayPaymentMethodID: " + paymentInstrumentRequest.c_marketPayPaymentMethodID);

// Token and sessionId should be sent from PWA in the request body
Logger.info("beforePost token: " + paymentInstrumentRequest.c_marketPayToken);
Logger.info("beforePost sessionID: " + paymentInstrumentRequest.c_marketPaySessionID);
Logger.info("modifyPOSTResponse sessionID: " + paymentInstrumentRequest.c_marketPaySessionID);

// Token and sessionId should be sent from PWA in the request body
var mpPayment = marketPayService.createPayment(paymentInstrumentRequest.c_marketPayToken,
var mpPayment = marketPayService.createPayment(
paymentInstrumentRequest.c_marketPaySessionID,
paymentInstrumentRequest.c_marketpayPaymentMethodID);
basketResponse.c_marketPay = mpPayment;
paymentInstrumentRequest.c_marketPayPaymentMethodID,
paymentInstrumentRequest.c_marketPayOnInitiatePaymentURL);

if (basketResponse.paymentInstruments && basketResponse.paymentInstruments.length > 0) {
for (var i = 0; i < basketResponse.paymentInstruments.length; i++) {
var paymentInstrument = basketResponse.paymentInstruments[i];
if (paymentInstrument.paymentMethod === paymentInstrumentRequest.paymentMethodId) {
Transaction.wrap(function () {
paymentInstrument.custom.marketPayPaymentURL = mpPayment.url;
//paymentInstrument.custom.marketPayURLType = mpPayment.type;
});
break;
}
}
}

} else {
var missingFields = [];
if (!paymentInstrumentRequest.c_marketpayPaymentMethodID) {
missingFields.push('c_marketpayPaymentMethodID');
}
if (!paymentInstrumentRequest.c_marketPayToken) {
missingFields.push('c_marketPayToken');
}
if (!paymentInstrumentRequest.c_marketPayPaymentMethodID) {
missingFields.push('c_marketPayPaymentMethodID');
}
if (!paymentInstrumentRequest.c_marketPaySessionID) {
missingFields.push('c_marketPaySessionID');
}

Logger.error("MarketPay: Missing required fields: " + missingFields.join(', '));

basketResponse.c_marketPayError = {
error: true,
message: "Missing required MarketPay fields: " + missingFields.join(', ')
};

return;
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ const LocalServiceRegistry = require('dw/svc/LocalServiceRegistry');
const Encoding = require('dw/crypto/Encoding');
const Bytes = require('dw/util/Bytes');
const Logger = require('dw/system/Logger');
var CacheMgr = require('dw/system/CacheMgr');

const CACHE_ID = 'marketPayRestOauthToken';
const CACHE_KEY = 'oauth_token';

/**
* Creates and returns a LocalServiceRegistry service for authenticating with MarketPay.
Expand All @@ -18,59 +22,63 @@ const Logger = require('dw/system/Logger');
* @returns {dw.svc.HTTPService}
* A configured MarketPay authentication service instance.
*/
function getMarketPayAuthenticateService() {
let authString;
let encodedAuthString;

return LocalServiceRegistry.createService('int.marketpay.auth', {
createRequest: function (svc, payload) {
svc.setRequestMethod('POST');
svc.addHeader('Content-Type', 'application/json');
function fetchNewToken() {

authString = payload.username + ':' + payload.password;
encodedAuthString = Encoding.toBase64(new Bytes(authString));
svc.addHeader('Authorization', 'Basic ' + encodedAuthString);
const tokenService = LocalServiceRegistry.createService("int.marketpay.auth", {
createRequest: function (service, params) {
service.setRequestMethod("POST");
service.addHeader("Content-Type", "application/x-www-form-urlencoded");

return JSON.stringify(payload);
},
const credentials = service.getConfiguration().getCredential();
const clientId = credentials.getUser();
const clientSecret = credentials.getPassword();

parseResponse: function (svc, client) {
try {
return JSON.parse(client.text);
} catch (e) {
throw new Error('Failed to parse authentication response: ' + e.message);
}
},
const authString = clientId + ":" + clientSecret;
const base64Auth = Encoding.toBase64(new Bytes(authString));
service.addHeader("Authorization", "Basic " + base64Auth);

filterLogMessage: function (msg) {
return msg; // Mask if needed
return JSON.stringify({});
},

mockCall: function () {
return {
status: 'SUCCESS',
token: 'mock-auth-token'
};
parseResponse: function (service, response) {
return JSON.parse(response.text);
}
});

const result = tokenService.call();

if (result.ok && result.object && result.object.token) {
const accessToken = result.object.token;

// Cache the token (expires automatically after 3500 seconds)
const cache = CacheMgr.getCache(CACHE_ID);
cache.put(CACHE_KEY, accessToken);

return accessToken;
}


throw new Error("Failed to get token: " + (result.errorMessage || 'Unknown error'));
}

function getService(serviceType, method) {
function getService(serviceType, method, url) {
return LocalServiceRegistry.createService('marketpay.http.service', {
createRequest: function (svc, payload) {

var log = Logger.getLogger("marketpay");

log.info("GetService Marketing _url:" + svc.getURL()+'/'+serviceType);
log.info("GetService token:" + payload.token);
log.info("GetService Marketing _url:" + svc.getURL() + '/' + serviceType);
log.info("GetService token:" + getAuthToken());
log.info("GetService body:" + JSON.stringify(payload.requestBody));


svc.setURL(svc.getURL()+'/'+serviceType);
if (url == null)
svc.setURL(svc.getURL() + '/' + serviceType);
else
svc.setURL(url);

svc.setRequestMethod(method);
svc.addHeader('Content-Type', 'application/json');
svc.addHeader('Authorization', 'Bearer ' + payload.token);
svc.addHeader('Authorization', 'Bearer ' + getAuthToken());

return JSON.stringify(payload.requestBody);
},
Expand All @@ -96,6 +104,7 @@ function getService(serviceType, method) {
});
}


/**
* Creates and returns a LocalServiceRegistry service for creating a MarketPay session.
*
Expand Down Expand Up @@ -158,22 +167,18 @@ function getMarketPaySessionService() {
* @returns {string}
* The MarketPay authentication token.
*/
function getAuthToken() {
const site = require('*/cartridge/scripts/helpers/site.js');
const authService = getMarketPayAuthenticateService();
const payload = {
username: site.getCustomPreference('marketpayUsername'),
password: site.getCustomPreference('marketpayPassword')
};

const result = authService.call(payload);
function getAuthToken() {

const cache = CacheMgr.getCache(CACHE_ID);
let token = cache.get(CACHE_KEY);

if (!result.ok || !result.object || !result.object.token) {
Logger.error('MarketPay Authenticate API error');
throw new Error('Failed to retrieve MarketPay authentication token');
// If token exists in cache, return it (cache handles expiry)
if (token) {
return token;
}

return result.object.token;
// Otherwise fetch new token
return fetchNewToken();
}

/**
Expand All @@ -198,13 +203,13 @@ function getAuthToken() {
* - sessionId: The created MarketPay session ID
*/
function getTokenAndSessionId(requestBody) {
const token = getAuthToken();
const token = getAuthToken();

const sessionService = getMarketPaySessionService();
const result = sessionService.call({
token: token,
requestBody: requestBody
});
const result = sessionService.call({
token: token,
requestBody: requestBody
});

if (!result.ok || !result.object || !result.object.sessionId) {
Logger.error('MarketPay Session API error', result.errorMessage);
Expand All @@ -213,42 +218,36 @@ function getTokenAndSessionId(requestBody) {

return {
token: token,
sessionId: result.object.sessionId
sessionId: result.object.sessionId
};
}

function getPaymentMethods(authToken, checkoutSessionId) {
function getPaymentMethods(checkoutSessionId) {

const service = getService(`session/${checkoutSessionId}/payment-methods`, 'GET');
const result = service.call({
token: authToken,
requestBody: {}
});
const result = service.call({
requestBody: {}
});

//Logger.info('MarketPay PaymentMethods', JSON.stringify(result));

if (!result.ok) {
Logger.error('MarketPay PaymentMethods API error', result.errorMessage);
throw new Error('Failed to retrieve MarketPay Payment Methods');
}



return result.object;
}

function createPayment(authToken, checkoutSessionId, paymentMethodId) {
function createPayment(checkoutSessionId, paymentMethodId, onInitiatePaymentURL) {

const service = getService(`payment`, 'POST');
const result = service.call({
token: authToken,
requestBody: {
paymentMethodId: paymentMethodId,
sessionId: checkoutSessionId
}
});
const service = getService(`payment`, 'POST', onInitiatePaymentURL);
const result = service.call({
requestBody: {
paymentMethodId: paymentMethodId,
sessionId: checkoutSessionId
}
});

if (!result.ok || !result.object ) {
if (!result.ok || !result.object) {
Logger.error('MarketPay createPayment API error', result.errorMessage);
throw new Error('Failed to create MarketPay session ID');
}
Expand All @@ -258,8 +257,6 @@ function createPayment(authToken, checkoutSessionId, paymentMethodId) {

module.exports = {
getTokenAndSessionId: getTokenAndSessionId,
getPaymentMethods: getPaymentMethods,
getPaymentMethods: getPaymentMethods,
createPayment: createPayment
};


Loading