Skip to content

Commit

Permalink
Release/21.09.29 (#25)
Browse files Browse the repository at this point in the history
* SSIG-33 : [SIG-16][BD] Implement passive mode for Pre and post auth implementations (#13)

* SSIG-37 : 2nd Task - [SIG-16][BD] Implement passive mode for Pre and post auth implementations (#14)

SIG-16 : Changing the attribute's name & id

* SSIG-39 : [SIG-18][BD] Pre-Auth Accept/Decline Logic Change (#17)

* SSIG-41 : 3rd Task - [SIG-16][BD] Implement passive mode for Pre and post auth implementations - V2 (#18)

* SSIG-41 : 3rd Task - [SIG-16][BD] Implement passive mode for Pre and post auth implementations - V4 (#19)

SIG-16: Updated the tags to be a single array

* [Pre-auth project][BD] Batch 2 - Fulfillment + job update (#20)

* SSIG-25 : Initial commit for Batch 2

* SSIG-25: Services Metadata Update

* SSIG-25

- Modifications on send fulfillment logic to work with multishipping

Co-authored-by: MelikeBilenn <[email protected]>

* SSIG-43 : [SIG-22][BD] Bug in the code (#21)

* Copy and paste the checkoutHelpers.js file

* Changing the status of the export status depending on SignifydHoldOrderEnable preference.

* SSIG-43

Created new cartridge for SFRA changes and extended base module to overwrite only placeOrder function on checkoutHelpers.js

* SSIG-43

- Renamed the new cartridge
- Updated documentation

Co-authored-by: Renato Diniz <[email protected]>

* SSIG-41: 3rd Task - [SIG-16][BD] Implement passive mode for Pre and post auth implementations (#22)

* SSIG-41

- Updated SignifydPassiveMode custom preference default value to false

* SSIG-41

- Updated documentation for passive mode

* SSIG-25 : [SIG-11][BD] Create Case (v2/cases) & Fulfilment API (v2/fulfilment) Schema change (#23)

- Added modifications for fulfillment API
- Updated documentation for fulfillment API
- Minor fixes

* SSIG-25 : [SIG-11][BD] Create Case (v2/cases) & Fulfilment API (v2/fulfilment) Schema change (#24)

- Updated documentation index

Co-authored-by: MelikeBilenn <[email protected]>
Co-authored-by: MelikeBilenn <[email protected]>
  • Loading branch information
3 people authored Sep 29, 2021
1 parent a7a1c23 commit 82431dd
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 17 deletions.
120 changes: 109 additions & 11 deletions link/cartridges/int_signifyd/cartridge/scripts/service/signifyd.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var StringUtils = require('dw/util/StringUtils');
var BasketMgr = require('dw/order/BasketMgr');
var OrderMgr = require('dw/order/OrderMgr');
var signifydInit = require('int_signifyd/cartridge/scripts/service/signifydInit');
var Shipment = require('dw/order/Shipment');


/**
Expand Down Expand Up @@ -241,7 +242,7 @@ function getCardBin(mainPaymentInst) {
try {
if (!empty(mainPaymentInst.getCreditCardNumber()) && mainPaymentInst.getCreditCardNumber().indexOf("*") < 0) {
cardBin = mainPaymentInst.getCreditCardNumber().substring(0, 6);
} else if (!empty(session.forms.billing.creditCardFields) &&
} else if (!empty(session.forms.billing.creditCardFields) &&
!empty(session.forms.billing.creditCardFields.cardNumber) && !empty(session.forms.billing.creditCardFields.cardNumber.value)) {
cardBin = session.forms.billing.creditCardFields.cardNumber.value.substring(0, 6);
}
Expand Down Expand Up @@ -450,6 +451,7 @@ function setOrderSessionId(order, orderSessionId) {
function getParams(order) {
var SignifydCreateCasePolicy = dw.system.Site.getCurrent().getCustomPreferenceValue('SignifydCreateCasePolicy').value;
var SignifydDecisionRequest = dw.system.Site.getCurrent().getCustomPreferenceValue('SignifydDecisionRequest').value;
var SignifydPassiveMode = dw.system.Site.getCurrent().getCustomPreferenceValue('SignifydPassiveMode');
var orderCreationCal = new Calendar(order.creationDate);
var paramsObj = {
policy: {
Expand All @@ -475,9 +477,13 @@ function setOrderSessionId(order, orderSessionId) {
transactions: [],
userAccount: getUser(order),
seller: {}, // getSeller()
platformAndClient: getPlatform()
platformAndClient: getPlatform(),
};

if (SignifydPassiveMode) {
paramsObj.tags = ["Passive Mode"];
}

// add payment instrument related fields
var mainPaymentInst = getMainPaymentInst(order.getPaymentInstruments());
if (!empty(mainPaymentInst)) {
Expand All @@ -490,8 +496,6 @@ function setOrderSessionId(order, orderSessionId) {
paramsObj.transactions = [{
transactionId: mainTransaction.transactionID,
createdAt: StringUtils.formatCalendar(transactionCreationCal, "yyyy-MM-dd'T'HH:mm:ssZ"),
type: "AUTHORIZATION",
gatewayStatusCode: "SUCCESS",
paymentMethod: mainPaymentInst.getPaymentMethod(),
type: "AUTHORIZATION", // to be updated by the merchant
gatewayStatusCode: "SUCCESS", // to be updated by the merchant
Expand Down Expand Up @@ -581,7 +585,7 @@ function getSendTransactionParams(order) {

if (!empty(mainPaymentInst)) {
paramsObj.checkoutToken = mainPaymentInst.UUID;
paramsObj.transactions.checkoutPaymentDetails = {
paramsObj.transactions[0].checkoutPaymentDetails = {
holderName: mainPaymentInst.creditCardHolder,
cardLast4: mainPaymentInst.creditCardNumberLastDigits,
cardExpiryMonth: mainPaymentInst.creditCardExpirationMonth,
Expand All @@ -597,7 +601,7 @@ function getSendTransactionParams(order) {
countryCode: order.billingAddress.countryCode.value
}
}
paramsObj.transactions.paymentAccountHolder = {
paramsObj.transactions[0].paymentAccountHolder = {
accountId: mainPaymentInst.getBankAccountNumber(),
accountHolderName: mainPaymentInst.getBankAccountHolder(),
billingAddress: {
Expand All @@ -612,7 +616,7 @@ function getSendTransactionParams(order) {
}

if (!empty(mainPaymentProcessor)) {
paramsObj.transactions.gateway = mainPaymentProcessor.ID;
paramsObj.transactions[0].gateway = mainPaymentProcessor.ID;
}

return paramsObj;
Expand Down Expand Up @@ -684,17 +688,17 @@ exports.Call = function (order) {
if (SignifydCreateCasePolicy === "PRE_AUTH") {
caseId = answer.caseId;
if (answer.checkpointAction) {
if (answer.checkpointAction !== "ACCEPT") {
if (answer.checkpointAction === "REJECT") {
declined = true;
}
} else {
if (answer.recommendedAction) {
if (answer.recommendedAction !== "ACCEPT") {
if (answer.recommendedAction === "REJECT") {
declined = true;
}
} else {
if (answer.decisions.paymentFraud.status) {
if (answer.decisions.paymentFraud.status !== "APPROVED") {
if (answer.decisions.paymentFraud.status === "DECLINED") {
declined = true;
}
}
Expand All @@ -710,7 +714,7 @@ exports.Call = function (order) {
var orderUrl = 'https://www.signifyd.com/cases/' + caseId;
order.custom.SignifydOrderURL = orderUrl;

if (answer.checkpointAction) {
if (typeof answer.checkpointAction !== 'undefined' ) {
order.custom.SignifydFraudScore = answer.score;
order.custom.SignifydPolicy = answer.checkpointAction;
order.custom.SignifydPolicyName = answer.checkpointActionReason || '';
Expand Down Expand Up @@ -742,6 +746,100 @@ exports.Call = function (order) {
return returnObj;
};

function getproductLineItems(productLineItems) {
var products = [];

if (!empty(productLineItems)) {
var iterator = productLineItems.iterator();
while (iterator.hasNext()) {
var product = iterator.next();
products.push({
itemName: product.lineItemText,
itemQuantity: product.quantity.value,
itemPrice: product.grossPrice.value,
});
}
}

return products;
}

function getDeliveryAddress(shipment) {
var deliveryAddress = {
streetAddress: shipment.shippingAddress.address1,
streetAddress: shipment.shippingAddress.address1,
streetAddress: shipment.shippingAddress.address1,
unit: shipment.shippingAddress.address2 || "",
city: shipment.shippingAddress.city,
provinceCode: "" ,
postalCode: shipment.shippingAddress.postalCode ,
countryCode: shipment.shippingAddress.countryCode.value
};

return deliveryAddress;
}

function getSendFulfillmentParams(order, shipment) {
var cal = new Calendar(new Date());
var products = getproductLineItems(shipment.productLineItems);
var deliveryAddress = getDeliveryAddress(shipment);
var shipmentId = shipment.shipmentNo;
var fulfillmentStatus = order.getShippingStatus().displayValue === "PARTSHIPPED" ? "PARTIAL" : "COMPLETE";

var paramsObj = {
fulfillments : [{
id: order.orderNo + shipmentId,
orderId: order.orderNo,
createdAt: StringUtils.formatCalendar(cal, "yyyy-MM-dd'T'HH:mm:ssZ"),
recipientName: shipment.shippingAddress.fullName,
deliveryEmail: order.getCustomerEmail(),
fulfillmentStatus: fulfillmentStatus,
products: products,
deliveryAddress: deliveryAddress,
shipmentId: shipmentId,
// shipmentStatus: "", // to be updated by the merchant
// shippingCarrier: "", // to be updated by the merchant
// trackingNumbers: [], // to be updated by the merchant
// trackingUrls: [] // to be updated by the merchant
}]
};

return paramsObj;
}

function sendFulfillment(order) {
if (EnableCartridge) {
if (order && order.currentOrderNo) {
try {
var shipments = order.getShipments();

for (var index in shipments) {
var shipment = shipments[index];
var params = getSendFulfillmentParams(order, shipment);
var service = signifydInit.sendFulfillment();

if (service) {
Logger.getLogger('Signifyd', 'signifyd').info('Info: SendFulfillment API call for order {0}', order.currentOrderNo);

var result = service.call(params);

if (!result.ok) {
Logger.getLogger('Signifyd', 'signifyd').error('Error: SendFulfillment API call for order {0} has failed.', order.currentOrderNo);
}
} else {
Logger.getLogger('Signifyd', 'signifyd').error('Error: Could not initialize SendFulfillment service.');
}
}
} catch (e) {
Logger.getLogger('Signifyd', 'signifyd').error('Error: SendFulfillment method was interrupted unexpectedly. Exception: {0}', e.message);
}
} else {
Logger.getLogger('Signifyd', 'signifyd').error('Error: Please provide correct order for the SendFulfillment method');
}
}
};

exports.setOrderSessionId = setOrderSessionId;
exports.getOrderSessionId = getOrderSessionId;
exports.getSeler = getSeller;
exports.sendFulfillment = sendFulfillment;
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,45 @@ function sendTransaction() {
return service;
}

function sendFulfillment() {
var service = LocalServiceRegistry.createService('Signifyd.REST.SendFulfillment', {
createRequest: function (svc, args) {
var sitePrefs = Site.getCurrent().getPreferences();
var APIkey = sitePrefs.getCustom().SignifydApiKey;
var authKey = StringUtils.encodeBase64(APIkey); // move to site preferences
svc.setRequestMethod('POST');
svc.addHeader('Content-Type', 'application/json');
svc.addHeader('Authorization', 'Basic ' + authKey);
var url = svc.getURL(); //ADD THE ORDER ID arguments[1].fulfillments.orderId
url = url.replace(/orderId/g, args.fulfillments[0].orderId);
svc.setURL(url);
if (args) {
return JSON.stringify(args);
}
return null;
},
parseResponse: function (svc, client) {
return client.text;
},
mockCall: function () {
return {
statusCode: 200,
statusMessage: 'Form post successful',
text: '{ "investigationId": 1}'
};
},
getResponseLogMessage: function (response) {
return response.statusMessage;
},
filterLogMessage: function () {
}
});

return service;
}

module.exports = {
createCase: createCase,
sendTransaction: sendTransaction,
sendFulfillment: sendFulfillment
};
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ server.replace('PlaceOrder', server.middleware.https, function (req, res, next)
}

if (SignifydCreateCasePolicy == "PRE_AUTH") {
var SignifydPassiveMode = dw.system.Site.getCurrent().getCustomPreferenceValue('SignifydPassiveMode');
Signifyd.setOrderSessionId(order, orderSessionID);
var response = Signifyd.Call(order);

Expand All @@ -128,13 +129,17 @@ server.replace('PlaceOrder', server.middleware.https, function (req, res, next)
if (response.declined) {
order.custom.SignifydOrderFailedReason = Resource.msg('error.signifyd.order.failed.reason', 'signifyd', null);
}
OrderMgr.failOrder(order);
});
res.json({
error: true,
errorMessage: Resource.msg('error.technical', 'checkout', null)
if (!SignifydPassiveMode) {
OrderMgr.failOrder(order);
}
});
return next();
if (!SignifydPassiveMode) {
res.json({
error: true,
errorMessage: Resource.msg('error.technical', 'checkout', null)
});
return next();
}
}
}

Expand Down
17 changes: 17 additions & 0 deletions link/cartridges/signifyd_sfra_changes/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>signifyd_sfra_changes</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.demandware.studio.core.beehiveElementBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.demandware.studio.core.beehiveNature</nature>
</natures>
</projectDescription>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';

var base = module.superModule || {};

/**
* Attempts to place the order
* @param {dw.order.Order} order - The order object to be placed
* @param {Object} fraudDetectionStatus - an Object returned by the fraud detection hook
* @returns {Object} an error object
*/
function placeOrder(order, fraudDetectionStatus) {
var Transaction = require('dw/system/Transaction');
var OrderMgr = require('dw/order/OrderMgr');
var Status = require('dw/system/Status');
var Order = require('dw/order/Order');
var result = { error: false };

try {
Transaction.begin();
var placeOrderStatus = OrderMgr.placeOrder(order);
if (placeOrderStatus === Status.ERROR) {
throw new Error();
}

if (fraudDetectionStatus.status === 'flag') {
order.setConfirmationStatus(Order.CONFIRMATION_STATUS_NOTCONFIRMED);
} else {
order.setConfirmationStatus(Order.CONFIRMATION_STATUS_CONFIRMED);
}


/* Signifyd Modification Start */
var signifyEnabled = dw.system.Site.getCurrent().getCustomPreferenceValue('SignifydEnableCartridge');
var signifydHoldOrderEnable = dw.system.Site.getCurrent().getCustomPreferenceValue('SignifydHoldOrderEnable');

if (signifyEnabled) {
if (signifydHoldOrderEnable === true) {
order.setExportStatus(Order.EXPORT_STATUS_NOTEXPORTED);
} else {
order.setExportStatus(Order.EXPORT_STATUS_READY);
}
} else {
order.setExportStatus(Order.EXPORT_STATUS_READY);
}
/* Signifyd Modification End */

Transaction.commit();
} catch (e) {
Transaction.wrap(function () { OrderMgr.failOrder(order); });
result.error = true;
}

return result;
}

base.placeOrder = placeOrder;

module.exports = base;
Binary file not shown.
9 changes: 9 additions & 0 deletions link/metadata/meta/system-objecttype-extensions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@
<externally-managed-flag>false</externally-managed-flag>
<default-value>3</default-value>
</attribute-definition>
<attribute-definition attribute-id="SignifydPassiveMode">
<display-name xml:lang="x-default">Signifyd Pre-Auth Passive Mode</display-name>
<description xml:lang="x-default">Signifyd Pre-Auth Passive Mode</description>
<type>boolean</type>
<mandatory-flag>false</mandatory-flag>
<externally-managed-flag>false</externally-managed-flag>
<default-value>false</default-value>
</attribute-definition>
<attribute-definition attribute-id="SignifydEnableDecisionCentre">
<display-name xml:lang="x-default">Enable Decision Centre</display-name>
<description xml:lang="x-default">Enable only if you are using Signifyd's Decision Centre product and DECISION_MADE webhook.</description>
Expand Down Expand Up @@ -175,6 +183,7 @@
<attribute attribute-id="SignifydEnableCartridge"/>
<attribute attribute-id="SignifydMaxRetryCount"/>
<attribute attribute-id="SignifydEnableDecisionCentre"/>
<attribute attribute-id="SignifydPassiveMode"/>
</attribute-group>
</group-definitions>
</type-extension>
Expand Down
Loading

0 comments on commit 82431dd

Please sign in to comment.