Skip to content

Instantly share code, notes, and snippets.

@Mozu-CS
Last active February 13, 2019 02:36
Show Gist options
  • Save Mozu-CS/1692560bb8101b644d6aa3f025bafb2d to your computer and use it in GitHub Desktop.
Save Mozu-CS/1692560bb8101b644d6aa3f025bafb2d to your computer and use it in GitHub Desktop.
embedded.commerce.payments.action.after.js
/**
* Implementation for embedded.commerce.payments.action.before
* This custom function will receive the following context object:
{
"exec": {
"setActionAmount": {
"parameters": [
{
"name": "amount",
"type": "number"
}
],
"return": {
"type": "mozu.commerceRuntime.contracts.payments.paymentAction"
}
},
"setPaymentData": {
"parameters": [
{
"name": "key",
"type": "string"
},
{
"name": "value",
"type": "object"
}
]
},
"removePaymentData": {
"parameters": [
{
"name": "key",
"type": "string"
}
]
},
"setActionPreAuthFlag": {
"parameters": [
{
"name": "isPreAuth",
"type": "bool"
}
]
}
},
"setPaymentTerm": {
"parameters": [
{
"name": "purchaseOrderPaymentTermObject",
"type": "object"
}
],
"return": {
"type": "mozu.commerceRuntime.contracts.payments.purchaseorderpaymentterm"
}
},
"get": {
"payment": {
"parameters": [],
"return": {
"type": "mozu.commerceRuntime.contracts.payments.payment"
}
},
"paymentAction": {
"parameters": [],
"return": {
"type": "mozu.commerceRuntime.contracts.payments.paymentAction"
}
}
}
}
*/
var constants = require("../../constants");
var softdecline = require("../../softdecline");
var _ = require("underscore");
module.exports = function(context, callback) {
var paymentAction = context.get.paymentAction();
var payment = context.get.payment();
var order = context.get.order();
var cardsFor1DollarAuth = context.configuration.cardType1$;
console.log('entering softdecline.');
console.log("Payment Action", paymentAction);
console.log("Payment", payment);
console.log("Order", order);
console.log("apiContext", context.apiContext);
console.log("configuration", context.configuration);
console.log("CardTypes", cardsFor1DollarAuth);
var isStorefrontInitiated = context.get.isStorefrontInitiated();
console.log('isStorefrontInitiated = ' + isStorefrontInitiated);
if (!isStorefrontInitiated) {
console.log('This is not storefront initiated.');
return callback();
}
if (!softdecline.isSoftDeclinePayment(payment, paymentAction)) {
console.log('not a softdecline payment.');
return callback();
}
if (!softdecline.shouldSoftDecline(payment)) {
console.log('cannot softdecline because retries exceeded.');
return callback();
}
var originalAuthAmount = softdecline.getOriginalAuthAmount(payment);
if (!originalAuthAmount) {
console.log('saving original authorize amount.');
context.exec.setPaymentData(constants.ORIGINAL_AUTH_AMOUNT_KEY, paymentAction.amount);
}
// set 1 dollar as the amount for Auth for cards other than Visa. Visa is 0 dollar.
/*var authAmount =1;
if (payment.billingInfo.card.paymentOrCardType.toUpperCase() !== "AMEX" && payment.billingInfo.card.paymentOrCardType.toUpperCase() !== "DISCOVER") {
authAmount = 0;
} */
var authAmount;
if (cardsFor1DollarAuth.indexOf(payment.billingInfo.card.paymentOrCardType.toUpperCase()) > -1) {
console.log('Performing $1 Auth');
authAmount = 1;
console.log('Auth Amount : ', authAmount);
}
else {
console.log('Not Performing $1 Auth');
authAmount = 0;
}
if (softdecline.getSoftDeclineCount(payment) >= 3) {
console.log('setting original amount for auth.');
authAmount = softdecline.getOriginalAuthAmount(payment);
// since this is no longer a pre auth, if it's the fourth time round.
context.exec.setActionPreAuthFlag(false);
} else {
context.exec.setActionPreAuthFlag(true);
}
// testmode
if (context.configuration && context.configuration.isTestMode && context.configuration.zeroDollarAuthAmount) {
console.log('App is running in TestMode');
// in test mode, pass in the configured amount.
if (softdecline.getSoftDeclineCount(payment) < 3) {
authAmount = Number(context.configuration.zeroDollarAuthAmount);
/*if (payment.billingInfo.card.paymentOrCardType.toUpperCase() !== "AMEX" && payment.billingInfo.card.paymentOrCardType.toUpperCase() !== "DISCOVER") {
authAmount = authAmount + 1;
}*/
if (cardsFor1DollarAuth.indexOf(payment.billingInfo.card.paymentOrCardType.toUpperCase()) > -1) {
}
else {
authAmount = authAmount + 1;
}
}
}
console.log('setting auth amount to ' + authAmount);
context.exec.setPaymentData(constants.PRE_AUTH_AMOUNT_KEY, authAmount);
context.exec.setActionAmount(authAmount);
context.exec.setPaymentData("DoSubscriptionAuth","true");
console.log('exiting softdecline.');
return callback();
};
/**
* Implementation for embedded.commerce.payments.action.after
* This custom function will receive the following context object:
{
"exec": {
"setActionAmount": {
"parameters": [
{
"name": "amount",
"type": "number"
}
],
"return": {
"type": "mozu.commerceRuntime.contracts.payments.paymentAction"
}
},
"setFailedStateName": {
"parameters": [
{
"name": "stateName",
"type": "string"
}
]
},
"setSuccessFlag": {
"parameters": [
{
"name": "isSuccess",
"type": "bool"
}
]
},
"setNewStateName": {
"parameters": [
{
"name": "stateName",
"type": "string"
}
]
},
"setPaymentData": {
"parameters": [
{
"name": "key",
"type": "string"
},
{
"name": "value",
"type": "object"
}
]
},
"removePaymentData": {
"parameters": [
{
"name": "key",
"type": "string"
}
]
},
"setRetryFlag": {
"parameters": [
{
"name": "shouldRetry",
"type": "bool"
}
]
},
"setActionPreAuthFlag": {
"parameters": [
{
"name": "isPreAuth",
"type": "bool"
}
]
}
},
"get": {
"payment": {
"parameters": [],
"return": {
"type": "mozu.commerceRuntime.contracts.payments.payment"
}
},
"paymentAction": {
"parameters": [],
"return": {
"type": "mozu.commerceRuntime.contracts.payments.paymentAction"
}
}
}
}
*/
var constants = require("../../constants");
var softdecline = require("../../softdecline");
var _ = require("underscore");
function gatewayInteractionIsSoftDecline(paymentInteraction) {
var result = _.contains(constants.SOFTDECLINE_CODES, paymentInteraction.gatewayResponseCode);
return result;
}
function clearSoftDeclineCount(context, payment) {
if (payment.Data && _.has(payment.Data, constants.SOFTDECLINECOUNT_KEY)) {
context.exec.removePaymentData(constants.SOFTDECLINECOUNT_KEY);
}
}
function getLatestPaymentInteraction(payment) {
var orderedPaymentInteractions = _.sortBy(payment.interactions, function(i) {
return i.interactionDate;
});
var latestPaymentInteraction = _.last(orderedPaymentInteractions);
return latestPaymentInteraction;
}
module.exports = function(context, callback) {
var paymentAction = context.get.paymentAction();
var payment = context.get.payment();
var order = context.get.order();
console.log("Payment Action", paymentAction);
console.log("Payment", payment);
console.log("Order", order);
console.log("apiContext", context.apiContext);
var isStorefrontInitiated = context.get.isStorefrontInitiated();
console.log('isStorefrontInitiated = ' + isStorefrontInitiated);
if (!isStorefrontInitiated) {
console.log('This is not storefront initiated.');
return callback();
}
// not a soft decline payment type .. we don't do anything.
if (!softdecline.isSoftDeclinePayment(payment, paymentAction)) {
console.log('not a softdecline payment.');
return callback();
}
var latestPaymentInteraction = getLatestPaymentInteraction(payment);
// success, clear the softdecline count, and indicate we need a retry, with the original auth amount.
if (latestPaymentInteraction.status.toUpperCase() === "AUTHORIZED") {
console.log('interaction was AUTHORIZED, so nothing to do.');
clearSoftDeclineCount(context, payment);
var preAuthAmount = (!payment.Data || !_.has(payment.Data, constants.PRE_AUTH_AMOUNT_KEY)) ? 0 : payment.Data[constants.PRE_AUTH_AMOUNT_KEY];
console.log('Pre auth amount was - ' + preAuthAmount);
if (paymentAction.amount === preAuthAmount) {
console.log('interaction amount was less than 1, so get the original auth amount.');
var originalAuthAmount = softdecline.getOriginalAuthAmount(payment);
context.exec.setActionAmount(originalAuthAmount);
context.exec.setRetryFlag(false);
context.exec.setActionPreAuthFlag(false);
}
return callback();
}
// hard decline, clear the softdecline count, nothing else to do.
if (latestPaymentInteraction.status.toUpperCase() === "DECLINED" &&
!gatewayInteractionIsSoftDecline(latestPaymentInteraction)) {
console.log('interaction was hard DECLINED, so nothing to do.');
clearSoftDeclineCount(context, payment);
return callback();
}
// soft decline.
if (latestPaymentInteraction.status.toUpperCase() === "DECLINED" &&
gatewayInteractionIsSoftDecline(latestPaymentInteraction) &&
softdecline.shouldSoftDecline(payment)) {
var retryCount = (!payment.Data || !_.has(payment.Data, constants.SOFTDECLINECOUNT_KEY)) ? 0 : payment.Data[constants.SOFTDECLINECOUNT_KEY];
var newRetryCount = retryCount + 1;
context.exec.setPaymentData(constants.SOFTDECLINECOUNT_KEY, newRetryCount);
// soft decline
if (retryCount < constants.RETRYCOUNT) {
console.log('interaction is a soft decline with retryCount=' + newRetryCount);
context.exec.setFailedStateName("New");
return callback();
}
// soft decline 4th time
if (retryCount == constants.RETRYCOUNT) {
console.log('interaction is a soft decline, but treating as a successful Auth.');
context.exec.setSuccessFlag(true);
context.exec.setNewStateName("Authorized");
return callback();
}
}
context.exec.removePaymentData("DoSubscriptionAuth");
return callback();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment