From e2d20f051d1307d00bea41fc134786ca2d86eb15 Mon Sep 17 00:00:00 2001 From: Ben Komor Date: Wed, 15 Feb 2017 14:22:53 +0100 Subject: [PATCH 1/3] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dac020063..50f1c764e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The integration is based on the Site Genesis demo store provided by Commerce Clo ## Installation, Usage and Configuration -Installation, Usage and Configuration is explained in our[manual](https://docs.adyen.com/developers/salesforce-commerce-cloud#setup). +Installation, Usage and Configuration is explained in our d[manual](https://docs.adyen.com/developers/salesforce-commerce-cloud#setup). ## Support @@ -19,4 +19,4 @@ Supply as much information as possible: your merchant account, skin code, time, ## Licence -MIT license see LICENSE. \ No newline at end of file +MIT license see LICENSE. From c3a070bf658bc6da8e97d545f76df483f39c80cb Mon Sep 17 00:00:00 2001 From: Ben Komor Date: Wed, 15 Feb 2017 14:23:08 +0100 Subject: [PATCH 2/3] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50f1c764e..072c558cf 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The integration is based on the Site Genesis demo store provided by Commerce Clo ## Installation, Usage and Configuration -Installation, Usage and Configuration is explained in our d[manual](https://docs.adyen.com/developers/salesforce-commerce-cloud#setup). +Installation, Usage and Configuration is explained in our [manual](https://docs.adyen.com/developers/salesforce-commerce-cloud#setup). ## Support From f923c2d94bdbcb2b2feb7ed34ac3b161abce08a3 Mon Sep 17 00:00:00 2001 From: Joe Greenwood Date: Wed, 22 Feb 2017 11:10:41 -0600 Subject: [PATCH 3/3] mods in salesforce code NOT in github code --- .../cartridge/scripts/adyen3DVerification.ds | 17 +- .../cartridge/scripts/adyenCancel.ds | 32 +- .../cartridge/scripts/adyenCancelOrRefund.ds | 32 +- .../cartridge/scripts/adyenCapture.ds | 32 +- .../scripts/adyenCreditVerification.ds | 22 +- .../scripts/adyenHppCancelledPayment.ds | 14 +- .../scripts/adyenHppPendingPayment.ds | 13 +- .../scripts/adyenHppRefusedPayment.ds | 14 +- .../adyenRedirectVerificationSHA256.ds | 14 +- .../scripts/adyenRemovePreviousPI.ds | 14 +- .../authorizeConfirmationCallSHA256.ds | 20 +- .../scripts/buildOpenInvoiceResponse.ds | 92 ++--- .../scripts/checkNotificationAuth.ds | 18 +- .../scripts/createAdyenPaymentInstrument.ds | 23 +- .../cartridge/scripts/deleteCustomObjects.ds | 14 +- .../scripts/getPaymentMethodsSHA256.ds | 23 +- .../cartridge/scripts/handleCustomObject.ds | 66 ++-- .../cartridge/scripts/handleNotify.ds | 18 +- .../cartridge/scripts/job/notifications.js | 174 ++++++++++ .../scripts/readOpenInvoiceRequest.ds | 52 +-- .../cartridge/controllers/Adyen.js | 320 ++++++++++++++---- .../scripts/payment/processor/ADYEN_CREDIT.js | 131 +++++-- .../scripts/payment/processor/Adyen.js | 46 +-- 23 files changed, 923 insertions(+), 278 deletions(-) create mode 100644 cartridges/int_adyen/cartridge/scripts/job/notifications.js diff --git a/cartridges/int_adyen/cartridge/scripts/adyen3DVerification.ds b/cartridges/int_adyen/cartridge/scripts/adyen3DVerification.ds index 419e67b54..81419f041 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyen3DVerification.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyen3DVerification.ds @@ -32,8 +32,16 @@ importScript('libs/libAdyen.ds'); //script include var AdyenHelper = require ("int_adyen/cartridge/scripts/util/AdyenHelper"); +function execute( args : PipelineDictionary ) : Number +{ + var result = verify(args); + if (result == PIPELET_ERROR){ + return PIPELET_ERROR; + } + return PIPELET_NEXT; +} -function execute( args : PipelineDictionary ) : Number { +function verify( args : PipelineDictionary ) : Number { var VERSION : String = "4"; var MERCHANTACCOUNT : String = Site.getCurrent().getCustomPreferenceValue("Adyen_merchantCode"); @@ -140,5 +148,10 @@ function execute( args : PipelineDictionary ) : Number { return PIPELET_ERROR; } - return PIPELET_NEXT; + return args; +} + +module.exports = { + 'execute': execute, + 'verify': verify } diff --git a/cartridges/int_adyen/cartridge/scripts/adyenCancel.ds b/cartridges/int_adyen/cartridge/scripts/adyenCancel.ds index d70cc8e5e..38bec33d6 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenCancel.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenCancel.ds @@ -17,9 +17,19 @@ var AdyenHelper = require ("int_adyen/cartridge/scripts/util/AdyenHelper"); function execute( args : PipelineDictionary ) : Number { - // Get the input parameters - var order : Order = args.Order; + var decision = cancel(args.Order); + if (decision == PIPELET_ERROR){ + args.Decision = "ERROR"; + return PIPELET_ERROR; + } + + args.Decision = decision; + return PIPELET_NEXT; +} + +function cancel( order : Order ) : Number +{ // Check the input parameters if (order == null) { Logger.getLogger("Adyen").fatal("Cancellation of order payment has failed. No order was provided."); @@ -28,6 +38,7 @@ function execute( args : PipelineDictionary ) : Number // Get orderNo which is needed for some functions (error handling) var orderNo : String = order.getOrderNo(); + var decision = "ERROR"; // Error handling configuration var fatalErrMsgPrefix : String = "Cancellation of payment for order #" + orderNo + " has failed. "; @@ -84,7 +95,7 @@ function execute( args : PipelineDictionary ) : Number if (!empty(result)) { if (result.indexOf("cancel-received") != -1) { // Define the result of script execution - args.Decision = "SUCCESS"; + decision = "SUCCESS"; // Update the order order.custom.Adyen_eventCode = "CANCELLATION"; @@ -99,7 +110,7 @@ function execute( args : PipelineDictionary ) : Number Logger.getLogger("Adyen").info("Payment modification result for order #" + orderNo + ": Cancellation"); } else { // Define the result of script execution - args.Decision = "REFUSED"; + decision = "REFUSED"; // Update the order order.custom.Adyen_eventCode = "CANCELLATION REFUSED"; @@ -108,22 +119,21 @@ function execute( args : PipelineDictionary ) : Number Logger.getLogger("Adyen").info("Payment modification result for order #" + orderNo + ": Cancellation Refused"); } } else { - // Define the result of script execution - args.Decision = "ERROR"; - // Log the error and exit Logger.getLogger("Adyen").fatal(fatalErrMsgPrefix + "The call to Adyen API did not return any result."); return PIPELET_ERROR; } } catch (e) { - // Define the result of script execution - args.Decision = "ERROR"; - // Log the error and exit Logger.getLogger("Adyen").fatal(fatalErrMsgPrefix + "An error occurred during the call to Adyen API."); return PIPELET_ERROR; } - return PIPELET_NEXT; + return decision; } + +module.exports = { + 'execute': execute, + 'cancel': cancel +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/adyenCancelOrRefund.ds b/cartridges/int_adyen/cartridge/scripts/adyenCancelOrRefund.ds index 3dda66ad2..9828837e6 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenCancelOrRefund.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenCancelOrRefund.ds @@ -17,9 +17,19 @@ var AdyenHelper = require ("int_adyen/cartridge/scripts/util/AdyenHelper"); function execute( args : PipelineDictionary ) : Number { - // Get the input parameters - var order : Order = args.Order; + var decision = cancelOrRefund(args.Order); + if (decision == PIPELET_ERROR){ + args.Decision = "ERROR"; + return PIPELET_ERROR; + } + + args.Decision = decision; + return PIPELET_NEXT; +} + +function cancelOrRefund( order : Order ) : Number +{ // Check the input parameters if (order == null) { Logger.getLogger("Adyen").fatal("Cancellation or refund of order payment has failed. No order was provided."); @@ -28,6 +38,7 @@ function execute( args : PipelineDictionary ) : Number // Get orderNo which is needed for some functions (error handling) var orderNo : String = order.getOrderNo(); + var decision = "ERROR"; // Error handling configuration var fatalErrMsgPrefix : String = "Cancellation or refund of payment for order #" + orderNo + " has failed. "; @@ -85,7 +96,7 @@ function execute( args : PipelineDictionary ) : Number if (!empty(result)) { if (result.indexOf("cancelOrRefund-received") != -1) { // Define the result of script execution - args.Decision = "SUCCESS"; + decision = "SUCCESS"; // Update the order order.custom.Adyen_eventCode = "CANCELLATION OR REFUND"; @@ -100,7 +111,7 @@ function execute( args : PipelineDictionary ) : Number Logger.getLogger("Adyen").info("Payment modification result for order #" + orderNo + ": Cancellation Or Refund"); } else { // Define the result of script execution - args.Decision = "REFUSED"; + decision = "REFUSED"; // Update the order order.custom.Adyen_eventCode = "CANCELLATION OR REFUND REFUSED"; @@ -109,22 +120,21 @@ function execute( args : PipelineDictionary ) : Number Logger.getLogger("Adyen").info("Payment modification result for order #" + orderNo + ": Cancellation Or Refund Refused"); } } else { - // Define the result of script execution - args.Decision = "ERROR"; - // Log the error and exit Logger.getLogger("Adyen").fatal(fatalErrMsgPrefix + "The call to Adyen API did not return any result."); return PIPELET_ERROR; } } catch (e) { - // Define the result of script execution - args.Decision = "ERROR"; - // Log the error and exit Logger.getLogger("Adyen").fatal(fatalErrMsgPrefix + "An error occurred during the call to Adyen API."); return PIPELET_ERROR; } - return PIPELET_NEXT; + return decision; +} + +module.exports = { + 'execute': execute, + 'cancelOrRefund': cancelOrRefund } diff --git a/cartridges/int_adyen/cartridge/scripts/adyenCapture.ds b/cartridges/int_adyen/cartridge/scripts/adyenCapture.ds index dc2686218..99c9e3067 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenCapture.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenCapture.ds @@ -17,9 +17,19 @@ var AdyenHelper = require ("int_adyen/cartridge/scripts/util/AdyenHelper"); function execute( args : PipelineDictionary ) : Number { - // Get the input parameters - var order : Order = args.Order; + var decision = capture(args.Order); + if (decision == PIPELET_ERROR){ + args.Decision = "ERROR"; + return PIPELET_ERROR; + } + + args.Decision = decision; + return PIPELET_NEXT; +} + +function capture( order : Order ) : Number +{ // Check the input parameters if (order == null) { Logger.getLogger("Adyen").fatal("Capturing of order payment has failed. No order was provided."); @@ -28,6 +38,7 @@ function execute( args : PipelineDictionary ) : Number // Get orderNo which is needed for the API call and some other functions (error handling) var orderNo : String = order.getOrderNo(); + var decision = "ERROR"; // Error handling configuration var fatalErrMsgPrefix : String = "Payment capturing of order #" + orderNo + " has failed. "; @@ -95,7 +106,7 @@ function execute( args : PipelineDictionary ) : Number if (!empty(result)) { if (result.indexOf("capture-received") != -1) { // Define the result of script execution - args.Decision = "SUCCESS"; + decision = "SUCCESS"; // Update the order order.custom.Adyen_eventCode = "CAPTURING"; @@ -110,7 +121,7 @@ function execute( args : PipelineDictionary ) : Number Logger.getLogger("Adyen").info("Payment modification result for order #" + orderNo + ": Capturing"); } else { // Define the result of script execution - args.Decision = "REFUSED"; + decision = "REFUSED"; // Update the order order.custom.Adyen_eventCode = "CAPTURING REFUSED"; @@ -119,22 +130,21 @@ function execute( args : PipelineDictionary ) : Number Logger.getLogger("Adyen").info("Payment modification result for order #" + orderNo + ": Capturing Refused"); } } else { - // Define the result of script execution - args.Decision = "ERROR"; - // Log the error and exit Logger.getLogger("Adyen").fatal(fatalErrMsgPrefix + "The call to Adyen API did not return any result."); return PIPELET_ERROR; } } catch (e) { - // Define the result of script execution - args.Decision = "ERROR"; - // Log the error and exit Logger.getLogger("Adyen").fatal(fatalErrMsgPrefix + "An error occurred during the call to Adyen API."); return PIPELET_ERROR; } - return PIPELET_NEXT; + return decision; +} + +module.exports = { + 'execute': execute, + 'capture': capture } diff --git a/cartridges/int_adyen/cartridge/scripts/adyenCreditVerification.ds b/cartridges/int_adyen/cartridge/scripts/adyenCreditVerification.ds index 244a1728f..1472c4f02 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenCreditVerification.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenCreditVerification.ds @@ -8,6 +8,7 @@ * @input PaymentInstrument : dw.order.PaymentInstrument * @input CurrentSession : dw.system.Session * @input CurrentRequest : dw.system.Request +* @input CreditCardForm : dw.web.Form * * @output Decision : String * @output PaymentStatus : String @@ -34,7 +35,16 @@ importScript('libs/libAdyen.ds'); //script include var AdyenHelper = require ("int_adyen/cartridge/scripts/util/AdyenHelper"); -function execute( args : PipelineDictionary ) : Number { +function execute( args : PipelineDictionary ) : Number +{ + var result = verify(args); + if (result == PIPELET_ERROR){ + return PIPELET_ERROR; + } + return PIPELET_NEXT; +} + +function verify( args : PipelineDictionary ) : Number { var VERSION : String = "4"; var MERCHANTACCOUNT : String = Site.getCurrent().getCustomPreferenceValue("Adyen_merchantCode"); @@ -57,9 +67,7 @@ function execute( args : PipelineDictionary ) : Number { var orderNo = order.currentOrderNo; var a = Math.floor(Math.random()*10000); var c : Object = args.PaymentInstrument; - - var f : Object = args.CurrentForms; - var card : Object = f.billing.paymentMethods.creditCard; + var card : Object = args.CreditCardForm.object; var cardnr : String = card.number.value; var cardcvc : String = card.cvn.value; @@ -223,6 +231,10 @@ function execute( args : PipelineDictionary ) : Number { return PIPELET_ERROR; } - return PIPELET_NEXT; + return args; } +module.exports = { + 'execute': execute, + 'verify': verify +} diff --git a/cartridges/int_adyen/cartridge/scripts/adyenHppCancelledPayment.ds b/cartridges/int_adyen/cartridge/scripts/adyenHppCancelledPayment.ds index 609f6a015..a291df57c 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenHppCancelledPayment.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenHppCancelledPayment.ds @@ -11,10 +11,10 @@ importPackage( dw.util ); function execute( args : PipelineDictionary ) : Number { - // Get the input parameters - var hpm : Object = args.CurrentHttpParameterMap; - var order : Order = args.Order; - + return handle(args.CurrentHttpParameterMap, args.Order); +} + +function handle (hpm : Object, order : Order) : Number { // Log detailed response to ScriptLog and log file var msg : String = createLogMessage(hpm); Logger.getLogger("Adyen").debug(msg); @@ -66,7 +66,6 @@ function execute( args : PipelineDictionary ) : Number return PIPELET_NEXT; } - function createLogMessage(hpm) { var VERSION : String= "4d"; var msg = ""; @@ -85,3 +84,8 @@ function createLogMessage(hpm) { } return msg; } + +module.exports = { + 'execute': execute, + 'handle': handle +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/adyenHppPendingPayment.ds b/cartridges/int_adyen/cartridge/scripts/adyenHppPendingPayment.ds index f84385e3f..e62a366b7 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenHppPendingPayment.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenHppPendingPayment.ds @@ -11,10 +11,10 @@ importPackage( dw.util ); function execute( args : PipelineDictionary ) : Number { - // Get the input parameters - var hpm : Object = args.CurrentHttpParameterMap; - var order : Order = args.Order; - + return handle(args.CurrentHttpParameterMap, args.Order); +} + +function handle (hpm : Object, order : Order) : Number { // Log detailed response to ScriptLog and log file var msg : String = createLogMessage(hpm); Logger.getLogger("Adyen").debug(msg); @@ -85,3 +85,8 @@ function createLogMessage(hpm) { } return msg; } + +module.exports = { + 'execute': execute, + 'handle': handle +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/adyenHppRefusedPayment.ds b/cartridges/int_adyen/cartridge/scripts/adyenHppRefusedPayment.ds index d47b32a7f..8f3a95ff1 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenHppRefusedPayment.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenHppRefusedPayment.ds @@ -11,10 +11,10 @@ importPackage( dw.util ); function execute( args : PipelineDictionary ) : Number { - // Get the input parameters - var hpm : Object = args.CurrentHttpParameterMap; - var order : Order = args.Order; - + return handle(args.CurrentHttpParameterMap, args.Order); +} + +function handle (hpm : Object, order : Order) : Number { // Log detailed response to ScriptLog and log file var msg : String = createLogMessage(hpm); Logger.getLogger("Adyen").debug(msg); @@ -75,3 +75,9 @@ function createLogMessage(hpm) { msg = msg + "\npaymentMethod : " + hpm.paymentMethod.stringValue; return msg; } + + +module.exports = { + 'execute': execute, + 'handle': handle +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/adyenRedirectVerificationSHA256.ds b/cartridges/int_adyen/cartridge/scripts/adyenRedirectVerificationSHA256.ds index 1e61b76aa..e30016843 100644 --- a/cartridges/int_adyen/cartridge/scripts/adyenRedirectVerificationSHA256.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenRedirectVerificationSHA256.ds @@ -32,6 +32,13 @@ var AdyenHelper = require ("int_adyen/cartridge/scripts/util/AdyenHelper"); function execute( args : PipelineDictionary ) : Number { + if (verify(args) === PIPELET_ERROR) { + return PIPELET_ERROR; + } + return PIPELET_NEXT; +} + +function verify (args) { //configuration var VERSION : String= "8"; @@ -178,5 +185,10 @@ function execute( args : PipelineDictionary ) : Number //Log those information just when custom logs debug mode is enabled Logger.getLogger("Adyen").debug(orderNo+ " - " +msg); - return PIPELET_NEXT; + return args; } + +module.exports = { + 'execute': execute, + 'verify': verify +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/adyenRemovePreviousPI.ds b/cartridges/int_adyen/cartridge/scripts/adyenRemovePreviousPI.ds index c63460508..47ffeeba9 100755 --- a/cartridges/int_adyen/cartridge/scripts/adyenRemovePreviousPI.ds +++ b/cartridges/int_adyen/cartridge/scripts/adyenRemovePreviousPI.ds @@ -11,15 +11,18 @@ importPackage( dw.value ); importPackage( dw.web ); function execute( args : PipelineDictionary ) : Number +{ + return removePaymentInstruments(args.Basket); +} + +function removePaymentInstruments( basket : dw.order.Basket ) : Number { // verify that we have a basket and a valid credit card form - if( args.Basket == null ) + if( basket == null ) { return PIPELET_ERROR; } - var basket : Basket = args.Basket; - // get all credit card payment instruments var ccPaymentInstrs : Collection = basket.getPaymentInstruments(); var iter : Iterator = ccPaymentInstrs.iterator(); @@ -33,4 +36,9 @@ function execute( args : PipelineDictionary ) : Number } return PIPELET_NEXT; +} + +module.exports = { + 'execute': execute, + 'removePaymentInstruments': removePaymentInstruments } \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/authorizeConfirmationCallSHA256.ds b/cartridges/int_adyen/cartridge/scripts/authorizeConfirmationCallSHA256.ds index 225f7f587..160ab8346 100644 --- a/cartridges/int_adyen/cartridge/scripts/authorizeConfirmationCallSHA256.ds +++ b/cartridges/int_adyen/cartridge/scripts/authorizeConfirmationCallSHA256.ds @@ -22,11 +22,14 @@ importPackage( dw.util ); function execute( args : PipelineDictionary ) : Number { - if(empty(args.MerchantSig) || empty(args.AuthResult) || empty(args.PspReference) || empty(args.MerchantReference) - || empty(args.SkinCode)){ - return PIPELET_ERROR; + args.Authenticated = authorize(args); + return PIPELET_NEXT; +} + + function authorize( args : PipelineDictionary ) : Boolean { + if(empty(args.MerchantSig) || empty(args.AuthResult) || empty(args.PspReference) || empty(args.MerchantReference) || empty(args.SkinCode)){ + return false; } - var authResult : String = args.AuthResult; var merchantReference : String = args.MerchantReference; var paymentMethod : String = args.PaymentMethod; @@ -69,7 +72,10 @@ function execute( args : PipelineDictionary ) : Number var signature : String = Encoding.toBase64(c.digest(requestString, keyBytes)); // If the signatures match then the call is authorized - args.Authenticated = (merchantSig == signature); - - return PIPELET_NEXT; + return merchantSig == signature; } + +module.exports = { + 'execute': execute, + 'authorize': authorize +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/buildOpenInvoiceResponse.ds b/cartridges/int_adyen/cartridge/scripts/buildOpenInvoiceResponse.ds index 4fbb00ab9..7467dde11 100755 --- a/cartridges/int_adyen/cartridge/scripts/buildOpenInvoiceResponse.ds +++ b/cartridges/int_adyen/cartridge/scripts/buildOpenInvoiceResponse.ds @@ -1,21 +1,28 @@ /** * Build the openinvoice response needed for the Afterpay payment method (see Adyen Manual for details) * +* @input Order : dw.order.Order +* @output openInvoiceResponse : String */ importPackage( dw.system ); importPackage( dw.order ); function execute( args : PipelineDictionary ) : Number { - args.openInvoiceResponse = ""; + args.openInvoiceResponse = getInvoiceResponse(args.Order); + return PIPELET_NEXT; +} + +function getInvoiceResponse (order : Order) : String { + var openInvoiceResponse = ""; var count=0; - var valutaCode = args.order.getCurrencyCode(); + var valutaCode = order.getCurrencyCode(); var TotalAmount:number = 0; - for each(var line in args.order.allProductLineItems) { + for each(var line in order.allProductLineItems) { if (count != 0) { - args.openInvoiceResponse += "&"; + openInvoiceResponse += "&"; } var quantity:number=line.quantity.value; var SalesPrice = line.adjustedNetPrice; @@ -26,22 +33,22 @@ function execute( args : PipelineDictionary ) : Number var TaxPriceAmount:number = Math.round(TaxPrice * 100); var OneTaxPrice:number = Math.round(TaxPriceAmount/quantity); - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+(OneSalesPrice).toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT="+(OneTaxPrice).toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems="+quantity.toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description="+encodeURIComponent(line.lineItemText)+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=High&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+(OneSalesPrice).toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT="+(OneTaxPrice).toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems="+quantity.toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description="+encodeURIComponent(line.lineItemText)+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=High&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); TotalAmount += OneSalesPrice*quantity; TotalAmount += OneTaxPrice*quantity; count++; } - for each(var line in args.order.priceAdjustments) { + for each(var line in order.priceAdjustments) { if (count != 0) { - args.openInvoiceResponse += "&"; + openInvoiceResponse += "&"; } var SalesPrice = line.netPrice; var SalesPriceAmount:number = Math.round(SalesPrice * 100); @@ -49,38 +56,38 @@ function execute( args : PipelineDictionary ) : Number var TaxPrice = line.tax; var TaxPriceAmount:number = Math.round(TaxPrice * 100); - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+(SalesPriceAmount).toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT="+(TaxPriceAmount).toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems=1&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description="+encodeURIComponent(line.lineItemText)+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=High&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+(SalesPriceAmount).toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT="+(TaxPriceAmount).toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems=1&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description="+encodeURIComponent(line.lineItemText)+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=High&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); TotalAmount += SalesPriceAmount; TotalAmount += TaxPriceAmount; count++; } - var SalesPrice = args.order.shippingTotalNetPrice; + var SalesPrice = order.shippingTotalNetPrice; if (SalesPrice > 0) { - for each(var line in args.order.shipments) { + for each(var line in order.shipments) { if (count != 0) { - args.openInvoiceResponse += "&"; + openInvoiceResponse += "&"; } var SalesPrice = line.adjustedShippingTotalNetPrice; var SalesPriceAmount:number = Math.round(SalesPrice * 100); var TaxPrice = line.adjustedShippingTotalTax; var TaxPriceAmount:number = Math.round(TaxPrice * 100); - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+(SalesPriceAmount).toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT="+TaxPriceAmount.toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems=1&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description=Shipping&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=High&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+(SalesPriceAmount).toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT="+TaxPriceAmount.toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems=1&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description=Shipping&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=High&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); TotalAmount += SalesPriceAmount; TotalAmount += TaxPriceAmount; @@ -88,22 +95,27 @@ function execute( args : PipelineDictionary ) : Number } } - var TotalOrderAmount:number = Math.round(args.order.totalGrossPrice * 100); + var TotalOrderAmount:number = Math.round(order.totalGrossPrice * 100); if (TotalAmount != TotalOrderAmount) { if (count != 0) { - args.openInvoiceResponse += "&"; + openInvoiceResponse += "&"; } - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+Math.round(TotalOrderAmount-TotalAmount).toString()+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT=0&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems=1&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description=AfrondCorrectie&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=None&"; - args.openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemPrice="+Math.round(TotalOrderAmount-TotalAmount).toString()+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".itemVAT=0&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".currency="+valutaCode+"&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".numberOfItems=1&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".description=AfrondCorrectie&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".vatCategory=None&"; + openInvoiceResponse += "openInvoiceDetailResult.lines."+count+".lineReference="+(count+1); } - Logger.getLogger("Adyen").debug("OpenInvoice Response : " +args.openInvoiceResponse); + Logger.getLogger("Adyen").debug("OpenInvoice Response : " +openInvoiceResponse); return PIPELET_NEXT; } + +module.exports = { + 'execute': execute, + 'getInvoiceResponse': getInvoiceResponse +} diff --git a/cartridges/int_adyen/cartridge/scripts/checkNotificationAuth.ds b/cartridges/int_adyen/cartridge/scripts/checkNotificationAuth.ds index eb00c0dda..fde2f4554 100755 --- a/cartridges/int_adyen/cartridge/scripts/checkNotificationAuth.ds +++ b/cartridges/int_adyen/cartridge/scripts/checkNotificationAuth.ds @@ -10,14 +10,22 @@ importScript("libs/libAuthenticationUtils.ds"); function execute( args : PipelineDictionary ) : Number { + args.Authenticated = check(args.CurrentRequest); + return PIPELET_NEXT; +} + +function check (request) { var baUser : String = Site.getCurrent().getCustomPreferenceValue("Adyen_notification_user"); var baPassword : String = Site.getCurrent().getCustomPreferenceValue("Adyen_notification_password"); - var baHeader : String = args.CurrentRequest.httpHeaders["authorization"]; + var baHeader : String = request.httpHeaders["authorization"]; if(empty(baUser) || empty(baPassword) || empty(baHeader)){ - return PIPELET_ERROR; + return false; } - args.Authenticated = AuthenticationUtils.checkGivenCredentials(baHeader, baUser, baPassword); - - return PIPELET_NEXT; + return AuthenticationUtils.checkGivenCredentials(baHeader, baUser, baPassword); } + +module.exports = { + 'execute': execute, + 'check': check +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/createAdyenPaymentInstrument.ds b/cartridges/int_adyen/cartridge/scripts/createAdyenPaymentInstrument.ds index bd31b552f..2484873f0 100755 --- a/cartridges/int_adyen/cartridge/scripts/createAdyenPaymentInstrument.ds +++ b/cartridges/int_adyen/cartridge/scripts/createAdyenPaymentInstrument.ds @@ -15,24 +15,35 @@ importPackage( dw.web ); importScript( dw.web.Resource.msg('demandware.core.cartridge', 'int_adyen', 'app_storefront_core') + ':checkout/Utils.ds' ); -function execute( pdict : PipelineDictionary ) : Number +function execute( args : PipelineDictionary ) : Number { - var basket : Basket = pdict.Basket; + var result = create(args.Basket); + if (result == PIPELET_ERROR){ + return PIPELET_ERROR; + } + + args.PaymentInstrument = result; + return PIPELET_NEXT; +} +function create( basket : dw.order.Basket ) : Number +{ // verify that we have a basket and a valid credit card form if( basket == null )//|| !creditCardForm.valid { return PIPELET_ERROR; } - // calculate the amount to be charged for the credit card var amount = calculateNonGiftCertificateAmount( basket ); - // create a payment instrument for this credit card var paymentInstr : PaymentInstrument = basket.createPaymentInstrument( "Adyen", amount ); - pdict.PaymentInstrument = paymentInstr; - return PIPELET_NEXT; + return paymentInstr; +} + +module.exports = { + 'execute': execute, + 'create': create } \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/deleteCustomObjects.ds b/cartridges/int_adyen/cartridge/scripts/deleteCustomObjects.ds index 1a1887255..e8eee9642 100644 --- a/cartridges/int_adyen/cartridge/scripts/deleteCustomObjects.ds +++ b/cartridges/int_adyen/cartridge/scripts/deleteCustomObjects.ds @@ -7,10 +7,11 @@ importPackage( dw.system ); importPackage( dw.object ); importPackage( dw.util ); -function execute( args : PipelineDictionary ) : Number -{ - var orderID : String = args.orderID; - +function execute( args : PipelineDictionary ) : Number { + return handle(args.orderID); +} + +function handle( orderID : String ) : Object { var queryString : String = "custom.orderId LIKE '" + orderID + "*'"; var searchQuery : SeekableIterator = CustomObjectMgr.queryCustomObjects("adyenNotification", queryString, null); if (searchQuery.count > 0) { @@ -29,3 +30,8 @@ function execute( args : PipelineDictionary ) : Number searchQuery.close(); return PIPELET_NEXT; } + +module.exports = { + 'execute': execute, + 'handle': handle +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/getPaymentMethodsSHA256.ds b/cartridges/int_adyen/cartridge/scripts/getPaymentMethodsSHA256.ds index df4a66e02..cee0a686d 100644 --- a/cartridges/int_adyen/cartridge/scripts/getPaymentMethodsSHA256.ds +++ b/cartridges/int_adyen/cartridge/scripts/getPaymentMethodsSHA256.ds @@ -16,7 +16,17 @@ importPackage( dw.svc ); //script include var AdyenHelper = require("int_adyen/cartridge/scripts/util/AdyenHelper"); -function execute(args: PipelineDictionary): Number { +function execute( args : PipelineDictionary ) : Number +{ + var result = getMethods(args.Basket); + if (result == PIPELET_ERROR) { + return result; + } + args.PaymentMethods = result; + return PIPELET_NEXT; +} + +function getMethods (basket : dw.order.Basket) { var skinCode: String = Site.getCurrent().getCustomPreferenceValue("Adyen_skinCode"); var merchantAccount: String = Site.getCurrent().getCustomPreferenceValue("Adyen_merchantCode"); var HMACkey: String = Site.getCurrent().getCustomPreferenceValue("Adyen_HMACkey"); @@ -39,9 +49,9 @@ function execute(args: PipelineDictionary): Number { args.allowedMethods = ""; } - var currencyCode: String = args.Basket.currencyCode; + var currencyCode: String = basket.currencyCode; var merchantReference: String = "Request payment methods"; - var paymentAmount: Number = args.Basket.getTotalGrossPrice() ? args.Basket.getTotalGrossPrice().getValue() * 100 : 1000; + var paymentAmount: Number = basket.getTotalGrossPrice() ? basket.getTotalGrossPrice().getValue() * 100 : 1000; var countryCode: String = request.geolocation.countryCode; var sessionValidity: String = new Date(); sessionValidity.setHours(sessionValidity.getHours() + 1); @@ -99,8 +109,11 @@ function execute(args: PipelineDictionary): Number { } resultObject = callResult.object; - args.PaymentMethods = JSON.parse(resultObject.text); + return JSON.parse(resultObject.text); +} - return PIPELET_NEXT; +module.exports = { + 'execute': execute, + 'getMethods': getMethods } diff --git a/cartridges/int_adyen/cartridge/scripts/handleCustomObject.ds b/cartridges/int_adyen/cartridge/scripts/handleCustomObject.ds index b01449e0d..39f8aa1df 100644 --- a/cartridges/int_adyen/cartridge/scripts/handleCustomObject.ds +++ b/cartridges/int_adyen/cartridge/scripts/handleCustomObject.ds @@ -23,24 +23,37 @@ importPackage( dw.order ); importPackage( dw.util ); function execute( args : PipelineDictionary ) : Number +{ + var result = handle(args.CustomObj); + + args.EventCode = result.EventCode; + args.SkipNotification = result.SkipNotification; + args.RefusedHpp = result.RefusedHpp; + args.Pending = result.Pending; + args.SkipOrder = result.SkipOrder; + args.Order = result.Order; + + return result.status; +} +function handle( customObj : CustomObject ) : Object { var paymentSuccess : Boolean = false; var refusedHpp : Boolean = false; var pending : Boolean = false; + var result = {}; + result.status = PIPELET_ERROR; - var customObj : CustomObject = args.CustomObj; - - args.EventCode = customObj.custom.eventCode; - args.SkipNotification = false; - args.SkipOrder = false; + result.EventCode = customObj.custom.eventCode; + result.SkipNotification = false; + result.SkipOrder = false; var orderId = customObj.custom.orderId.split("-", 1); var order : Order = OrderMgr.getOrder(orderId[0]); - args.Order = order; + result.Order = order; if (order == null) { Logger.getLogger("Adyen", "adyen").fatal("Notification for not existing order {0} received.", customObj.custom.orderId); - return PIPELET_ERROR; + return result; } var orderCreateDate : Date = order.creationDate; @@ -55,24 +68,24 @@ function execute( args : PipelineDictionary ) : Number if(order.paymentStatus == Order.PAYMENT_STATUS_PAID){ Logger.getLogger("Adyen", "adyen").info ("Duplicate callback received for order {0}.",order.orderNo); paymentSuccess = true; - args.SkipNotification = true; + result.SkipNotification = true; } else if(order.paymentStatus == "PARTIALLY PAID"){ paymentSuccess = true; Logger.getLogger("Adyen", "adyen").info ("Partial payment received for order {0}.",order.orderNo); - args.SkipNotification = true; + result.SkipNotification = true; } else { order.setPaymentStatus(Order.PAYMENT_STATUS_PAID); order.setExportStatus(Order.EXPORT_STATUS_READY); order.setConfirmationStatus(Order.CONFIRMATION_STATUS_CONFIRMED); Logger.getLogger("Adyen", "adyen").info ("Order {0} updated to status PAID.",order.orderNo); - args.SkipNotification = true; + result.SkipNotification = true; paymentSuccess = true; } }else{ Logger.getLogger("Adyen", "adyen").info ("Authorization for order {0} was not successful - no update.",order.orderNo); - args.SkipNotification = true; + result.SkipNotification = true; // Determine if payment was refused and was used Adyen payment method if (customObj.custom.reason == "Refused") { var paymentInstruments : Collection = order.getPaymentInstruments(); @@ -82,7 +95,7 @@ function execute( args : PipelineDictionary ) : Number refusedHpp = true; paymentSuccess = false; setProcessedCOInfo(customObj); - return PIPELET_ERROR; + return result; break; } } @@ -94,21 +107,21 @@ function execute( args : PipelineDictionary ) : Number order.setExportStatus(Order.EXPORT_STATUS_NOTEXPORTED); Logger.getLogger("Adyen", "adyen").info ("Order {0} was cancelled.",order.orderNo); setProcessedCOInfo(customObj); - return PIPELET_ERROR; + return result; break; case "CANCEL_OR_REFUND" : order.setPaymentStatus(Order.PAYMENT_STATUS_NOTPAID); order.setExportStatus(Order.EXPORT_STATUS_NOTEXPORTED); Logger.getLogger("Adyen", "adyen").info ("Order {0} was cancelled or refunded.",order.orderNo); setProcessedCOInfo(customObj); - return PIPELET_ERROR; + return result; break; case "REFUND" : order.setPaymentStatus(Order.PAYMENT_STATUS_NOTPAID); order.setExportStatus(Order.EXPORT_STATUS_NOTEXPORTED); Logger.getLogger("Adyen", "adyen").info ("Order {0} was refunded.",order.orderNo); setProcessedCOInfo(customObj); - return PIPELET_ERROR; + return result; break; case "ORDER_OPENED" : Logger.getLogger("Adyen", "adyen").info ("Order {0} updated to status PARTIALLY PAID.",order.orderNo); @@ -129,8 +142,8 @@ function execute( args : PipelineDictionary ) : Number default: Logger.getLogger("Adyen", "adyen").info ("Order {0} received unhandled status {1}",order.orderNo,customObj.custom.eventCode); } - //args.RefusedHpp = refusedHpp; - //args.Pending = pending; + //result.RefusedHpp = refusedHpp; + //result.Pending = pending; // If payment was refused and was used Adyen payment method, the fields are changed when user is redirected back from Adyen HPP if (!refusedHpp) { @@ -164,14 +177,16 @@ function execute( args : PipelineDictionary ) : Number } } else { Logger.getLogger("Adyen", "adyen").debug("Order date > current Date."); - args.SkipOrder = true; - return PIPELET_NEXT; + result.SkipOrder = true; + result.status = PIPELET_NEXT; + return result; } - - args.RefusedHpp = refusedHpp; - args.Pending = pending; + + result.status = PIPELET_NEXT; + result.RefusedHpp = refusedHpp; + result.Pending = pending; - return PIPELET_NEXT; + return result; } function setProcessedCOInfo(customObj) @@ -273,3 +288,8 @@ function pad ( num : Number ) { } return num; } + +module.exports = { + 'execute': execute, + 'handle': handle +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/handleNotify.ds b/cartridges/int_adyen/cartridge/scripts/handleNotify.ds index 6fb74db29..b8530228d 100755 --- a/cartridges/int_adyen/cartridge/scripts/handleNotify.ds +++ b/cartridges/int_adyen/cartridge/scripts/handleNotify.ds @@ -18,10 +18,10 @@ importPackage( dw.object ); function execute( args : PipelineDictionary ) : Number { - - // Get the input parameters - var hpm : Object = args.CurrentHttpParameterMap; - + return notify(args.CurrentHttpParameterMap); +} + +function notify (hpm) { // Check the input parameters if (hpm == null) { Logger.getLogger("Adyen", "adyen").fatal("Handling of Adyen notification has failed. No input parameters were provided."); @@ -79,8 +79,9 @@ function execute( args : PipelineDictionary ) : Number } catch(e) { var ex = e; Logger.getLogger("Adyen", "adyen").error(e.message); - } - return PIPELET_NEXT; + } + + return PIPELET_NEXT; } function createLogMessage(hpm){ @@ -102,4 +103,9 @@ function createLogMessage(hpm){ msg = msg + "\npaymentMethod : " + hpm.paymentMethod.stringValue; msg = msg + "\nlive : " + hpm.live.stringValue; return msg; +} + +module.exports = { + 'execute': execute, + 'notify': notify } \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/job/notifications.js b/cartridges/int_adyen/cartridge/scripts/job/notifications.js new file mode 100644 index 000000000..8a924437b --- /dev/null +++ b/cartridges/int_adyen/cartridge/scripts/job/notifications.js @@ -0,0 +1,174 @@ + /* + * Script to run Adyen notification related jobs + */ + +/* API Includes */ +var Order = require('dw/order/Order'); +var OrderMgr = require('dw/order/OrderMgr'); +var Resource = require('dw/web/Resource'); +var Status = require('dw/system/Status'); +var Transaction = require('dw/system/Transaction'); +var CustomObjectMgr = require('dw/object/CustomObjectMgr'); +var logger = require('dw/system/Logger').getLogger('Adyen', 'adyen'); + +function execute(pdict) { + processNotifications(pdict); + clearNotifications(pdict); + return PIPELET_NEXT; +} + +/** + * ProcessNotifications - search for custom objects that need to be processed and handle them to place or fail order + */ +function processNotifications(pdict) { + var objectsHandler = require('int_adyen/cartridge/scripts/handleCustomObject'); + var searchQuery = CustomObjectMgr.queryCustomObjects("adyenNotification", "custom.updateStatus = 'PROCESS'", null); + logger.info("Process notifications start with count {0}", searchQuery.count); + + + var customObj, handlerResult, order, notify; + while (searchQuery.hasNext()) { + customObj = searchQuery.next(); + Transaction.wrap(function () { + handlerResult = objectsHandler.handle(customObj); + }); + + /* + Sometimes order cannot be found in DWRE DB even if it exists there, + in that case we shouldn't reply to Adyen that all was ok in order to get a new notification + */ + + order = handlerResult.Order; + notify = !handlerResult.SkipNotification; + + if (!handlerResult.status || handlerResult.status === PIPELET_ERROR) { + // Only CREATED orders can be failed + if (order == null || order.status != dw.order.Order.ORDER_STATUS_CREATED || handlerResult.RefusedHpp) { + continue; + } + // Refused payments which are made with using Adyen payment method are handled when user is redirected back from Adyen HPP. + // Here we shouldn't fail an order and send a notification + Transaction.wrap(function () { + OrderMgr.failOrder(order); + }); + + // sent order reject email + if (notify){ + Email.sendMail({ + template: 'mail/orderrejected', // 'mail/orderconfirmation' + recipient: order.getCustomerEmail(), + subject: 'Your order with Demandware online store', + context: { + Order: order + } + }); + } + continue; + } + + if (handlerResult.SkipOrder || handlerResult.Pending) { + continue; + } + + // Submitting an order -> update status and send all required email + var placeOrderResult = submitOrder(order, notify); + if (!placeOrderResult.order_created || placeOrderResult.error) { + logger.error('Failed to place an order: {0}, during notification process.', order.orderNo); + } + } + logger.info("Process notifications finished with count {0}", searchQuery.count); + searchQuery.close(); + + return PIPELET_NEXT; +} + +/** + * cleanNotifications + */ +function clearNotifications(pdict) { + var deleteCustomObjects = require('int_adyen/cartridge/scripts/deleteCustomObjects'); + var searchQuery = CustomObjectMgr.queryCustomObjects("adyenNotification", "custom.processedStatus = 'SUCCESS'", null); + logger.info("Removing Processed Custom Objects start with count {0}", searchQuery.count); + + var customObj, orderID; + while (searchQuery.hasNext()) { + customObj = searchQuery.next(); + orderID = customObj.custom.orderId.split("-", 1)[0]; + Transaction.wrap(function () { + deleteCustomObjects.handle(orderID); + }); + + } + logger.info("Removing Processed Custom Objects finished with count {0}", searchQuery.count); + searchQuery.close(); + + return PIPELET_NEXT; +} + +/** + * Place an order using OrderMgr. If order is placed successfully, + * its status will be set as confirmed, and export status set to ready. + * @param {dw.order.Order} order + */ +function placeOrder(order) { + var placeOrderStatus = OrderMgr.placeOrder(order); + if (placeOrderStatus === Status.ERROR) { + OrderMgr.failOrder(order); + throw new Error('Failed to place order.'); + } + order.setConfirmationStatus(Order.CONFIRMATION_STATUS_CONFIRMED); + order.setExportStatus(Order.EXPORT_STATUS_READY); +} + +/** + * Submits an order, original function located in OrderModel, but we need to manage triggering of email + * @param order {dw.order.Order} The order object to be submitted. + * @transactional + * @return {Object} object If order cannot be placed, object.error is set to true. Ortherwise, object.order_created is true, and object.Order is set to the order. + */ +function submitOrder(order, notificate) { + var Email = require('app_storefront_controllers/cartridge/scripts/models/EmailModel'); + var GiftCertificate = require('app_storefront_controllers/cartridge/scripts/models/GiftCertificateModel'); + + try { + Transaction.begin(); + placeOrder(order); + + // Creates gift certificates for all gift certificate line items in the order + // and sends an email to the gift certificate receiver + + order.getGiftCertificateLineItems().toArray().map(function (lineItem) { + return GiftCertificate.createGiftCertificateFromLineItem(lineItem, order.getOrderNo()); + }).forEach(GiftCertificate.sendGiftCertificateEmail); + + Transaction.commit(); + } catch (e) { + Transaction.rollback(); + return { + error: true, + PlaceOrderError: new Status(Status.ERROR, 'confirm.error.technical') + }; + } + + if (notificate) { + Email.sendMail({ + template: 'mail/orderconfirmation', + recipient: order.getCustomerEmail(), + subject: Resource.msg('order.orderconfirmation-email.001', 'order', null), + context: { + Order: order + } + }); + } + + return { + Order: order, + order_created: true + }; +} + +module.exports = { + 'execute': execute, + 'processNotifications': processNotifications, + 'clearNotifications': clearNotifications +} \ No newline at end of file diff --git a/cartridges/int_adyen/cartridge/scripts/readOpenInvoiceRequest.ds b/cartridges/int_adyen/cartridge/scripts/readOpenInvoiceRequest.ds index 7f0b50b6b..3a2c603bb 100755 --- a/cartridges/int_adyen/cartridge/scripts/readOpenInvoiceRequest.ds +++ b/cartridges/int_adyen/cartridge/scripts/readOpenInvoiceRequest.ds @@ -22,8 +22,17 @@ importPackage( dw.io ); function execute( args : PipelineDictionary ) : Number { + var params = getInvoiceParams(args.httpParameterMap); + args.openInvoiceReference = params.openInvoiceReference; + args.openInvoiceCurrency = params.openInvoiceCurrency; + args.openInvoiceAmount = params.openInvoiceAmount; - var httpParameterMap = args.httpParameterMap; + return PIPELET_NEXT; +} + +function getInvoiceParams( httpParameterMap : dw.web.HttpParameterMap ): Object { + + var result = {}; var querystring : String = httpParameterMap.requestBodyAsString; Logger.getLogger("Adyen").debug("OpenInvoice Request : " +querystring); @@ -38,15 +47,15 @@ function execute( args : PipelineDictionary ) : Number var amount : String = getParameterFromXML(querystring,"value"); var reference : String = getParameterFromXML(querystring,"reference"); - args.openInvoiceCurrency = currency; - args.openInvoiceReference = reference; - args.openInvoiceAmount = amount; + result.openInvoiceCurrency = currency; + result.openInvoiceReference = reference; + result.openInvoiceAmount = amount; - if (args.openInvoiceReference == "testMerchantRef1") + if (result.openInvoiceReference == "testMerchantRef1") { //for testing - args.openInvoiceReference = "00000201"; - args.openInvoiceAmount = "7890"; + result.openInvoiceReference = "00000201"; + result.openInvoiceAmount = "7890"; } } @@ -54,18 +63,18 @@ function execute( args : PipelineDictionary ) : Number { //incorect post request. workaround.. //example: openInvoiceDetailRequest.reference=testMerchantRef1&openInvoiceDetailRequest.amount.currency=EUR&action=OpenInvoiceDetailService.retrieveDetail&openInvoiceDetailRequest.merchantAccount=SuitSupplyCOM&openInvoiceDetailRequest.amount.value=1403 - args.openInvoiceReference = getParameterByName("?"+querystring,"openInvoiceDetailRequest.reference"); - args.openInvoiceCurrency = getParameterByName("?"+querystring,"openInvoiceDetailRequest.amount.currency"); - args.openInvoiceAmount = getParameterByName("?"+querystring,"openInvoiceDetailRequest.amount.value"); + result.openInvoiceReference = getParameterByName("?"+querystring,"openInvoiceDetailRequest.reference"); + result.openInvoiceCurrency = getParameterByName("?"+querystring,"openInvoiceDetailRequest.amount.currency"); + result.openInvoiceAmount = getParameterByName("?"+querystring,"openInvoiceDetailRequest.amount.value"); - if (args.openInvoiceReference == "testMerchantRef1") + if (result.openInvoiceReference == "testMerchantRef1") { //for testing - args.openInvoiceReference = "00000197"; - args.openInvoiceAmount = "38088"; + result.openInvoiceReference = "00000197"; + result.openInvoiceAmount = "38088"; - args.openInvoiceReference = "00000201"; - args.openInvoiceAmount = "7890"; + result.openInvoiceReference = "00000201"; + result.openInvoiceAmount = "7890"; } } @@ -73,11 +82,11 @@ function execute( args : PipelineDictionary ) : Number else { //Post request - args.openInvoiceReference = httpParameterMap.get("openInvoiceDetailRequest.reference").getStringValue(); - args.openInvoiceCurrency = httpParameterMap.get("openInvoiceDetailRequest.amount.currency").getStringValue(); - args.openInvoiceAmount = httpParameterMap.get("openInvoiceDetailRequest.amount.value").getStringValue(); + result.openInvoiceReference = httpParameterMap.get("openInvoiceDetailRequest.reference").getStringValue(); + result.openInvoiceCurrency = httpParameterMap.get("openInvoiceDetailRequest.amount.currency").getStringValue(); + result.openInvoiceAmount = httpParameterMap.get("openInvoiceDetailRequest.amount.value").getStringValue(); } - return PIPELET_NEXT; + return result; } function getParameterByName(querystring, name) @@ -103,3 +112,8 @@ function getParameterFromXML(xmlstring, tag) else return results[2]; } + +module.exports = { + 'execute': execute, + 'getInvoiceParams': getInvoiceParams +} \ No newline at end of file diff --git a/cartridges/int_adyen_controllers/cartridge/controllers/Adyen.js b/cartridges/int_adyen_controllers/cartridge/controllers/Adyen.js index f962741f2..2172d5322 100644 --- a/cartridges/int_adyen_controllers/cartridge/controllers/Adyen.js +++ b/cartridges/int_adyen_controllers/cartridge/controllers/Adyen.js @@ -3,9 +3,9 @@ /* API Includes */ var Resource = require('dw/web/Resource'); var URLUtils = require('dw/web/URLUtils'); -var Pipeline = require('dw/system/Pipeline'); var logger = require('dw/system/Logger').getLogger('Adyen', 'adyen'); var OrderMgr = require('dw/order/OrderMgr'); +var Site = require('dw/system/Site'); var Status = require('dw/system/Status'); var Transaction = require('dw/system/Transaction'); @@ -26,87 +26,230 @@ var OrderModel = app.getModel('Order'); * Called by Adyen to update status of payments. It should always display [accepted] when finished. */ function notify() { - Pipeline.execute('Adyen-Notify'); + var checkAuth = require('int_adyen/cartridge/scripts/checkNotificationAuth'); + + var status = checkAuth.check(request); + if (!status) { + app.getView().render('error'); + return {}; + } + + var handleNotify = require('int_adyen/cartridge/scripts/handleNotify'); + Transaction.wrap(function () { + handleNotify.notify(request.httpParameterMap); + }); + app.getView().render('notify'); } /** * Redirect to Adyen after saving order etc. */ function redirect(order) { - var pdict = Pipeline.execute('Adyen-Redirect',{ - Order : order, - PaymentInstrument : order.paymentInstrument - }); + var adyenVerificationSHA256 = require('int_adyen/cartridge/scripts/adyenRedirectVerificationSHA256'), + result; + Transaction.wrap(function () { + result = adyenVerificationSHA256.verify({ + 'Order': order, + 'OrderNo': order.orderNo, + 'CurrentSession' : session, + 'CurrentUser' : customer, + 'PaymentInstrument' : order.paymentInstrument, + 'brandCode': request.httpParameterMap.brandCode.value, + 'issuerId' : request.httpParameterMap.issuerId.value + }); + }); + if (result === PIPELET_ERROR) { + app.getView().render('error'); + return {}; + } + + var pdict = { + 'merchantSig' : result.merchantSig, + 'Amount100' : result.Amount100, + 'shopperEmail' : result.shopperEmail, + 'shopperReference' : result.shopperReference, + 'allowedMethods' : result.allowedMethods, + 'ParamsMap' : result.paramsMap, + 'SessionValidity' : result.sessionValidity, + 'Order': order, + 'OrderNo': order.orderNo + }; + + app.getView(pdict).render('redirect_sha256'); } /** * Show confirmation after return from Adyen */ function showConfirmation() { - var pdict = Pipeline.execute('Adyen-ShowConfirmation'); - switch (pdict.EndNodeName) { - case 'showConfirmation': - app.getController('COSummary').ShowConfirmation(pdict.Order); - break; - case 'error': + if (request.httpParameterMap.authResult.value != 'CANCELLED') { + var authorizeConfirmation = require('int_adyen/cartridge/scripts/authorizeConfirmationCallSHA256'); + var authorized = authorizeConfirmation.authorize({ + 'AuthResult': request.httpParameterMap.authResult.stringValue, + 'MerchantReference': request.httpParameterMap.merchantReference.getStringValue(), + 'PaymentMethod': request.httpParameterMap.paymentMethod.getStringValue(), + 'PspReference': request.httpParameterMap.pspReference.getStringValue(), + 'ShopperLocale': request.httpParameterMap.shopperLocale.getStringValue(), + 'SkinCode': request.httpParameterMap.skinCode.getStringValue(), + 'MerchantSig': request.httpParameterMap.merchantSig.getStringValue(), + 'MerchantReturnData': (!empty(request.httpParameterMap.merchantReturnData) ? request.httpParameterMap.merchantReturnData.getStringValue() : "") + }); + if (!authorized) { + app.getController('Error').Start(); + return {}; + } + } + + var order = OrderMgr.getOrder(request.httpParameterMap.merchantReference.toString()); + if (!order) { app.getController('Error').Start(); - break; - case 'summaryStart': - // A successful billing page will jump to the next checkout step. - app.getController('COSummary').Start({ - PlaceOrderError: pdict.PlaceOrderError - }); - break; + return {}; + } + + if (request.httpParameterMap.authResult.value == 'AUTHORISED' || request.httpParameterMap.authResult.value == 'PENDING') { + pendingPayment(order); + app.getController('COSummary').ShowConfirmation(order); + return {}; + } + + if (order.status != dw.order.Order.ORDER_STATUS_CREATED) { + // If the same order is tried to be cancelled more than one time, show Error page to user + if (CurrentHttpParameterMap.authResult.value == 'CANCELLED') { + app.getController('Error').Start(); + } else { + // TODO: check is there should be errro value { PlaceOrderError: pdict.PlaceOrderError } + app.getController('COSummary').Start(); + } + return {}; } + + // Handle Cancelled or Refused payments + cancelledPayment(order); + refusedPayment(order); + // fail order + Transaction.wrap(function () { + OrderMgr.failOrder(order); + }); + + // should be assingned by previous calls or not + var errorStatus = new dw.system.Status(dw.system.Status.ERROR, "confirm.error.declined"); + + app.getController('COSummary').Start({ + PlaceOrderError: errorStatus + }); + return {}; } - /** * Make a request to Adyen to get payment methods based on countryCode. Called from COBilling-Start */ function getPaymentMethods(cart) { - var pdict = Pipeline.execute('Adyen-GetPaymentMethods', {Basket: cart.object}); - return pdict.AdyenHppPaymentMethods; + // TODO: check is that used CSE Enabled (AdyenCseEnabled) Site.getCurrent().getCustomPreferenceValue("AdyenCseEnabled"); + // Site.getCurrent().getCustomPreferenceValue("Adyen_directoryLookup") + if (Site.getCurrent().getCustomPreferenceValue("Adyen_directoryLookup")) { + var getPaymentMethods = require('int_adyen/cartridge/scripts/getPaymentMethodsSHA256'); + return getPaymentMethods.getMethods(cart.object); + } + + return {}; } - /** * Get orderdata for the Afterpay Payment method */ function afterpay() { - Pipeline.execute('Adyen-Afterpay'); + var readOpenInvoiceRequest = require('int_adyen/cartridge/scripts/readOpenInvoiceRequest'); + var invoice = readOpenInvoiceRequest.getInvoiceParams(request.httpParameterMap); + var order = OrderMgr.getOrder(invoice.penInvoiceReference); + // show error if data mismach + if ((order.getBillingAddress().getPostalCode() != request.httpParameterMap.pc.toString()) + || (order.getBillingAddress().getPhone() != request.httpParameterMap.pn.toString()) + || (order.getCustomerNo() != request.httpParameterMap.cn.toString()) + || (order.getCustomerEmail() != request.httpParameterMap.ce.toString()) + || (invoice.openInvoiceAmount != Math.round(order.totalGrossPrice * 100))) + { + app.getView().render('afterpayerror'); + return {}; + } + + var buildOpenInvoiceResponse = require('int_adyen/cartridge/scripts/buildOpenInvoiceResponse'); + var invoiceResponse = buildOpenInvoiceResponse.getInvoiceResponse(order); + app.getView({OpenInvoiceResponse:invoiceResponse}).render('afterpay'); } /** * Handle Refused payments */ -function refusedPayment() { - Pipeline.execute('Adyen-RefusedPayment'); +function refusedPayment(order) { + if (request.httpParameterMap.authResult.value == 'REFUSED') { + var adyenHppRefusedPayment = require('int_adyen/cartridge/scripts/adyenHppRefusedPayment.ds'); + Transaction.wrap(function () { + adyenHppRefusedPayment.handle(request.httpParameterMap, order); + }); + + } + return ''; } /** * Handle payments Cancelled on Adyen HPP */ -function cancelledPayment() { - Pipeline.execute('Adyen-CancelledPayment'); +function cancelledPayment(order) { + if (request.httpParameterMap.authResult.value == 'CANCELLED') { + var adyenHppCancelledPayment = require('int_adyen/cartridge/scripts/adyenHppCancelledPayment'); + Transaction.wrap(function () { + adyenHppCancelledPayment.handle(request.httpParameterMap, order); + }); + } + return ''; } /** * Handle payments Pending on Adyen HPP */ -function pendingPayment() { - Pipeline.execute('Adyen-PendingPayment'); +function pendingPayment(order) { + if (request.httpParameterMap.authResult.value == 'PENDING') { + var adyenHppPendingPayment = require('int_adyen/cartridge/scripts/adyenHppPendingPayment'); + Transaction.wrap(function () { + adyenHppPendingPayment.handle(request.httpParameterMap, order); + }); + } + return ''; } /** * Call the Adyen API to capture order payment */ -function capture() { - Pipeline.execute('Adyen-Capture'); +function capture(args) { + var order = args.Order; + var orderNo = args.OrderNo; + + if (!order) { + // Checking order data against values from parameters + order = OrderMgr.getOrder(orderNo); + if (!order || order.getBillingAddress().getPostalCode() != session.custom.pc.toString() + || order.getBillingAddress().getPhone() != session.custom.pn.toString() + || order.getCustomerNo() != session.custom.cn.toString() + || order.getCustomerEmail() != session.custom.ce.toString()) { + return {error: true}; + } + } + + + var adyenCapture = require('int_adyen/cartridge/scripts/adyenCapture'), result; + Transaction.wrap(function () { + result = adyenCapture.capture(order); + }); + + if (result === PIPELET_ERROR) { + return {error: true}; + } + + return {sucess: true}; } @@ -114,7 +257,31 @@ function capture() { * Call the Adyen API to cancel order payment */ function cancel() { - Pipeline.execute('Adyen-Cancel'); + var order = args.Order; + var orderNo = args.OrderNo; + + if (!order) { + // Checking order data against values from parameters + order = OrderMgr.getOrder(orderNo); + if (!order || order.getBillingAddress().getPostalCode() != session.custom.pc.toString() + || order.getBillingAddress().getPhone() != session.custom.pn.toString() + || order.getCustomerNo() != session.custom.cn.toString() + || order.getCustomerEmail() != session.custom.ce.toString()) { + return {error: true}; + } + } + + + var adyenCancel = require('int_adyen/cartridge/scripts/adyenCancel'), result; + Transaction.wrap(function () { + result = adyenCancel.cancel(order); + }); + + if (result === PIPELET_ERROR) { + return {error: true}; + } + + return {sucess: true}; } @@ -122,7 +289,31 @@ function cancel() { * Call the Adyen API to cancel or refund order payment */ function cancelOrRefund() { - Pipeline.execute('Adyen-CancelOrRefund'); + var order = args.Order; + var orderNo = args.OrderNo; + + if (!order) { + // Checking order data against values from parameters + order = OrderMgr.getOrder(orderNo); + if (!order || order.getBillingAddress().getPostalCode() != session.custom.pc.toString() + || order.getBillingAddress().getPhone() != session.custom.pn.toString() + || order.getCustomerNo() != session.custom.cn.toString() + || order.getCustomerEmail() != session.custom.ce.toString()) { + return {error: true}; + } + } + + + var adyenCapture = require('int_adyen/cartridge/scripts/adyenCapture'), result; + Transaction.wrap(function () { + result = adyenCapture.capture(order); + }); + + if (result === PIPELET_ERROR) { + return {error: true}; + } + + return {sucess: true}; } /** @@ -132,30 +323,43 @@ function cancelOrRefund() { */ function authorizeWithForm() { - var order = session.custom.order; - var paymentInstrument = session.custom.paymentInstrument; - var adyenResponse : Object = session.custom.adyenResponse; + var adyen3DVerification = require('int_adyen/cartridge/scripts/adyen3DVerification'), result, + order = session.custom.order, + paymentInstrument = session.custom.paymentInstrument, + adyenResponse = session.custom.adyenResponse; clearCustomSessionFields(); - var pdict = Pipeline.execute('ADYEN_CREDIT-AuthorizeAfterSecure',{ - Order : order, - PaymentInstrument : paymentInstrument, - MD : adyenResponse.MD, - PaRes : adyenResponse.PaRes + + Transaction.begin(); + result = adyen3DVerification.verify({ + Order: order, + Amount: paymentInstrument.paymentTransaction.amount, + PaymentInstrument: paymentInstrument, + CurrentSession: session, + CurrentRequest: request, + MD: adyenResponse.MD, + PaResponse: adyenResponse.PaRes + }); + + if (result === PIPELET_ERROR || result.Decision != 'ACCEPT') { + Transaction.rollback(); + Transaction.wrap(function () { + OrderMgr.failOrder(order); }); - switch (pdict.EndNodeName) { - case 'authorized': - OrderModel.submit(order); - clearForms(); - app.getController('COSummary').ShowConfirmation(order); - break; - case 'error': - Transaction.wrap(function () { - OrderMgr.failOrder(order); - }); - app.getController('COSummary').Start({ - PlaceOrderError: new Status(Status.ERROR, 'confirm.error.technical') - }); - } + app.getController('COSummary').Start({ + PlaceOrderError: new Status(Status.ERROR, 'confirm.error.technical') + }); + return; + } + + + order.setPaymentStatus(dw.order.Order.PAYMENT_STATUS_PAID); + order.setExportStatus(dw.order.Order.EXPORT_STATUS_READY); + paymentInstrument.paymentTransaction.transactionID = result.RequestToken; + Transaction.commit(); + + OrderModel.submit(order); + clearForms(); + app.getController('COSummary').ShowConfirmation(order); } /** @@ -204,12 +408,12 @@ exports.Notify = guard.ensure(['post'], notify); exports.Redirect = redirect; +exports.Afterpay = guard.ensure(['get'], afterpay); + exports.ShowConfirmation = guard.httpsGet(showConfirmation); exports.GetPaymentMethods = getPaymentMethods; -exports.Afterpay = guard.ensure(['get'], afterpay); - exports.RefusedPayment = refusedPayment; exports.CancelledPayment = cancelledPayment; diff --git a/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/ADYEN_CREDIT.js b/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/ADYEN_CREDIT.js index 2ec7daaf9..202d3ee3f 100644 --- a/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/ADYEN_CREDIT.js +++ b/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/ADYEN_CREDIT.js @@ -1,56 +1,129 @@ 'use strict'; /* API Includes */ -var Pipeline = require('dw/system/Pipeline'); -var logger = require('dw/system/Logger').getLogger('Adyen', 'adyen'); var URLUtils = require('dw/web/URLUtils'); - - +var PaymentMgr = require('dw/order/PaymentMgr'); +var Site = require('dw/system/Site'); +var Transaction = require('dw/system/Transaction'); /* Script Modules */ var app = require('app_storefront_controllers/cartridge/scripts/app'); var guard = require('app_storefront_controllers/cartridge/scripts/guard'); +var Cart = require('app_storefront_controllers/cartridge/scripts/models/CartModel'); /** * Creates a Adyen payment instrument for the given basket */ function Handle(args) { - var pdict = Pipeline.execute('ADYEN_CREDIT-Handle',{Basket : args.Basket}); - switch(pdict.EndNodeName) { - case 'success': - return {success : true}; - case 'error': + var cart = Cart.get(args.Basket); + var adyenRemovePreviousPI = require('int_adyen/cartridge/scripts/adyenRemovePreviousPI'), result; + + Transaction.wrap(function () { + result = adyenRemovePreviousPI.removePaymentInstruments(args.Basket); + }); + + if (result === PIPELET_ERROR) { return {error : true}; } + + var adyenCseEnabled = Site.getCurrent().getCustomPreferenceValue('AdyenCseEnabled'); + if (!adyenCseEnabled) { + // Verify payment card + var creditCardForm = app.getForm('billing.paymentMethods.creditCard'); + var cardNumber = creditCardForm.get('number').value(); + var cardSecurityCode = creditCardForm.get('cvn').value(); + var cardType = creditCardForm.get('type').value(); + var expirationMonth = creditCardForm.get('expiration.month').value(); + var expirationYear = creditCardForm.get('expiration.year').value(); + var paymentCard = PaymentMgr.getPaymentCard(cardType); + + var creditCardStatus = paymentCard.verify(expirationMonth, expirationYear, cardNumber, cardSecurityCode); + if (creditCardStatus.error) { + var invalidatePaymentCardFormElements = require('app_storefront_core/cartridge/scripts/checkout/InvalidatePaymentCardFormElements'); + // original second parameter was: session.forms.billing.paymentMethods.creditCard + invalidatePaymentCardFormElements.invalidatePaymentCardForm(creditCardStatus, creditCardForm); + + return {error: true}; + } + } + + // create payment instrument + Transaction.wrap(function () { + cart.removeExistingPaymentInstruments(dw.order.PaymentInstrument.METHOD_CREDIT_CARD); + var paymentInstrument = cart.createPaymentInstrument(dw.order.PaymentInstrument.METHOD_CREDIT_CARD, cart.getNonGiftCertificateAmount()); + if (!adyenCseEnabled) { + paymentInstrument.creditCardHolder = creditCardForm.get('owner').value(); + paymentInstrument.creditCardNumber = cardNumber; + paymentInstrument.creditCardType = cardType; + paymentInstrument.creditCardExpirationMonth = expirationMonth; + paymentInstrument.creditCardExpirationYear = expirationYear; + } + }); + + return {success : true}; } /** * Call the Adyen API to Authorize CC using details entered by shopper. */ function Authorize(args) { - var pdict = Pipeline.execute('ADYEN_CREDIT-AuthorizePrivat',{ - Order : args.Order, - PaymentInstrument : args.PaymentInstrument - }); - switch (pdict.EndNodeName) { - case 'authorized3d' : - session.custom.order = args.Order; - session.custom.paymentInstrument = args.PaymentInstrument; - return { - authorized : true, - authorized3d : true, - view : app.getView({ - ContinueURL: URLUtils.https('Adyen-CloseIFrame', 'utm_nooverride', '1'), - Basket : pdict.Order, - issuerUrl : pdict.issuerUrl, - paRequest: pdict.paRequest, - md : pdict.md - })}; - case 'authorized': + // TODO: check is that one needed + if (args.RequestID) { return {authorized : true}; - case 'error': + } + + var order = args.Order; + var paymentInstrument = args.PaymentInstrument; + var paymentProcessor = PaymentMgr.getPaymentMethod(paymentInstrument.getPaymentMethod()).getPaymentProcessor(); + + Transaction.wrap(function () { + paymentInstrument.paymentTransaction.paymentProcessor = paymentProcessor; + }); + + // ScriptFile adyenCreditVerification.ds + var adyenCreditVerification = require('int_adyen/cartridge/scripts/adyenCreditVerification'); + Transaction.begin(); + var result = adyenCreditVerification.verify({ + Order: order, + Amount: paymentInstrument.paymentTransaction.amount, + CurrentSession: session, + CurrentRequest: request, + PaymentInstrument: paymentInstrument, + CreditCardForm: app.getForm('billing.paymentMethods.creditCard') + }); + + if (result === PIPELET_ERROR) { + Transaction.rollback(); return {error : true}; } + + if (result.IssuerUrl != '' ) { + Transaction.commit(); + + session.custom.order = order; + session.custom.paymentInstrument = paymentInstrument; + return { + authorized : true, + authorized3d : true, + view : app.getView({ + ContinueURL: URLUtils.https('Adyen-CloseIFrame', 'utm_nooverride', '1'), + Basket : order, + issuerUrl : result.IssuerUrl, + paRequest: result.PaRequest, + md : result.MD + })}; + } + + if (result.Decision != 'ACCEPT') { + Transaction.rollback(); + return {error : true}; + } + + paymentInstrument.paymentTransaction.transactionID = result.PspReference; + Transaction.commit(); + + return {authorized : true}; } + exports.Handle = Handle; exports.Authorize = Authorize; diff --git a/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/Adyen.js b/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/Adyen.js index de055ef33..788c4d469 100644 --- a/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/Adyen.js +++ b/cartridges/int_adyen_controllers/cartridge/scripts/payment/processor/Adyen.js @@ -1,9 +1,8 @@ 'use strict'; /* API Includes */ -var Pipeline = require('dw/system/Pipeline'); -var logger = require('dw/system/Logger').getLogger('Adyen', 'adyen'); - +var PaymentMgr = require('dw/order/PaymentMgr'); +var Transaction = require('dw/system/Transaction'); /* Script Modules */ var app = require('app_storefront_controllers/cartridge/scripts/app'); @@ -11,15 +10,25 @@ var app = require('app_storefront_controllers/cartridge/scripts/app'); /** * Creates a Adyen payment instrument for the given basket */ -function handle(args) -{ - var pdict = Pipeline.execute('Adyen-Handle', {Basket : args.Basket}); - switch (pdict.EndNodeName) { - case 'success': - return {success : true}; - case 'error': +function handle(args) { + var adyenRemovePreviousPI = require('int_adyen/cartridge/scripts/adyenRemovePreviousPI'), + adyenPaymentInstrument = require('int_adyen/cartridge/scripts/createAdyenPaymentInstrument'), + result; + + Transaction.wrap(function () { + result = adyenRemovePreviousPI.removePaymentInstruments(args.Basket); + if (result === PIPELET_ERROR) { + return {error : true}; + } + // payment instrument returned on success + result = adyenPaymentInstrument.create(args.Basket); + }); + + if (result === PIPELET_ERROR) { return {error : true}; } + + return {success : true}; } /** @@ -30,15 +39,14 @@ function handle(args) function authorize(args) { var orderNo = args.OrderNo; var paymentInstrument = args.PaymentInstrument; - var pdict = Pipeline.execute('Adyen-Authorize', { - OrderNo : orderNo, - PaymentInstrument : paymentInstrument}); - switch (pdict.EndNodeName) { - case 'authorized': - return {authorized : true}; - case 'error': - return {error : true}; - } + var paymentProcessor = PaymentMgr.getPaymentMethod(paymentInstrument.getPaymentMethod()).getPaymentProcessor(); + + Transaction.wrap(function () { + paymentInstrument.paymentTransaction.transactionID = orderNo; + paymentInstrument.paymentTransaction.paymentProcessor = paymentProcessor; + }); + + return {authorized: true}; } exports.Handle = handle;