We will work on Apr 26th (Saturday) and will be off from Apr 30th (Wednesday) until May 2nd (Friday) for public holiday in our country

Commit 245987bd authored by attilak's avatar attilak

[WIP]

resolve code review comments
use adyen-3ds2-js-utils helper function
component js updated to v2.2.1
parent d6e0c615
...@@ -27,8 +27,8 @@ namespace Adyen\Payment\Api; ...@@ -27,8 +27,8 @@ namespace Adyen\Payment\Api;
interface AdyenThreeDS2ProcessInterface interface AdyenThreeDS2ProcessInterface
{ {
/** /**
* @param mixed $payload * @param string $payload
* @return mixed * @return string
*/ */
public function initiate($payload); public function initiate($payload);
} }
...@@ -56,7 +56,7 @@ class TransactionPayment implements ClientInterface ...@@ -56,7 +56,7 @@ class TransactionPayment implements ClientInterface
{ {
$request = $transferObject->getBody(); $request = $transferObject->getBody();
// If the payments call is already done return the // If the payments call is already done return the request
if (!empty($request['resultCode'])) { if (!empty($request['resultCode'])) {
//Initiate has already a response //Initiate has already a response
return $request; return $request;
......
...@@ -44,6 +44,7 @@ class AddressDataBuilder implements BuilderInterface ...@@ -44,6 +44,7 @@ class AddressDataBuilder implements BuilderInterface
* AddressDataBuilder constructor. * AddressDataBuilder constructor.
* *
* @param \Adyen\Payment\Helper\Data $adyenHelper * @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/ */
public function __construct( public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper, \Adyen\Payment\Helper\Data $adyenHelper,
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
namespace Adyen\Payment\Gateway\Request; namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Gateway\Request\BuilderInterface;
use Adyen\Payment\Observer\AdyenCcDataAssignObserver;
class CcAuthorizationDataBuilder implements BuilderInterface class CcAuthorizationDataBuilder implements BuilderInterface
{ {
...@@ -57,9 +56,14 @@ class CcAuthorizationDataBuilder implements BuilderInterface ...@@ -57,9 +56,14 @@ class CcAuthorizationDataBuilder implements BuilderInterface
// retrieve payments response which we already got and saved in the // retrieve payments response which we already got and saved in the
// Adyen\Payment\Plugin\PaymentInformationManagement::afterSavePaymentInformation // Adyen\Payment\Plugin\PaymentInformationManagement::afterSavePaymentInformation
if ($response = $payment->getAdditionalInformation("paymentsResponse")) { if ($response = $payment->getAdditionalInformation("paymentsResponse")) {
// the payments response needs to be passed to the next process because after this point we don't have
// access to the payment object therefore to the additionalInformation array
$request = $response; $request = $response;
// Remove from additional data // Remove from additional data
$payment->unsAdditionalInformation("paymentsResponse"); $payment->unsAdditionalInformation("paymentsResponse");
// TODO check if qoupte needs to be saved or not
} else { } else {
$errorMsg = __('Error with payment method please select different payment method.'); $errorMsg = __('Error with payment method please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg)); throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
......
...@@ -27,22 +27,14 @@ use Magento\Payment\Gateway\Validator\AbstractValidator; ...@@ -27,22 +27,14 @@ use Magento\Payment\Gateway\Validator\AbstractValidator;
class ThreeDS2ResponseValidator extends AbstractValidator class ThreeDS2ResponseValidator extends AbstractValidator
{ {
/**
* @var \Adyen\Payment\Logger\AdyenLogger
*/
private $adyenLogger;
/** /**
* GeneralResponseValidator constructor. * GeneralResponseValidator constructor.
* *
* @param \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory * @param \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
* @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger
*/ */
public function __construct( public function __construct(
\Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory, \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
\Adyen\Payment\Logger\AdyenLogger $adyenLogger
) { ) {
$this->adyenLogger = $adyenLogger;
parent::__construct($resultFactory); parent::__construct($resultFactory);
} }
...@@ -93,4 +85,4 @@ class ThreeDS2ResponseValidator extends AbstractValidator ...@@ -93,4 +85,4 @@ class ThreeDS2ResponseValidator extends AbstractValidator
return $this->createResult($isValid, $errorMessages); return $this->createResult($isValid, $errorMessages);
} }
} }
\ No newline at end of file
...@@ -35,8 +35,8 @@ class Data extends AbstractHelper ...@@ -35,8 +35,8 @@ class Data extends AbstractHelper
const LIVE = 'live'; const LIVE = 'live';
const CHECKOUT_CONTEXT_URL_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/'; const CHECKOUT_CONTEXT_URL_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/';
const CHECKOUT_CONTEXT_URL_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/'; const CHECKOUT_CONTEXT_URL_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/';
const CHECKOUT_COMPONENT_JS_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/2.2.0/adyen.js'; const CHECKOUT_COMPONENT_JS_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/2.2.1/adyen.js';
const CHECKOUT_COMPONENT_JS_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/2.2.0/adyen.js'; const CHECKOUT_COMPONENT_JS_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/2.2.1/adyen.js';
/** /**
* @var \Magento\Framework\Encryption\EncryptorInterface * @var \Magento\Framework\Encryption\EncryptorInterface
...@@ -118,6 +118,9 @@ class Data extends AbstractHelper ...@@ -118,6 +118,9 @@ class Data extends AbstractHelper
*/ */
private $agreementResourceModel; private $agreementResourceModel;
/**
* @var \Magento\Framework\Locale\ResolverInterface
*/
private $localeResolver; private $localeResolver;
/** /**
...@@ -442,7 +445,7 @@ class Data extends AbstractHelper ...@@ -442,7 +445,7 @@ class Data extends AbstractHelper
* Gives back adyen_cc_vault configuration values as flag * Gives back adyen_cc_vault configuration values as flag
* *
* @param $field * @param $field
* @param null $storeId * @param int|null $storeId
* @return mixed * @return mixed
*/ */
public function getAdyenCcVaultConfigDataFlag($field, $storeId = null) public function getAdyenCcVaultConfigDataFlag($field, $storeId = null)
......
...@@ -155,8 +155,7 @@ class Requests extends AbstractHelper ...@@ -155,8 +155,7 @@ class Requests extends AbstractHelper
// Save the defaults for later to compare if anything has changed // Save the defaults for later to compare if anything has changed
$requestBilling = $requestBillingDefaults; $requestBilling = $requestBillingDefaults;
// Parse address into street and house number where possible $address = $this->getStreetStringFromBillingAddress($billingAddress);
$address = $this->adyenHelper->getStreetFromString($billingAddress->getStreetFull());
if (!empty($address["name"])) { if (!empty($address["name"])) {
$requestBilling["street"] = $address["name"]; $requestBilling["street"] = $address["name"];
...@@ -290,7 +289,7 @@ class Requests extends AbstractHelper ...@@ -290,7 +289,7 @@ class Requests extends AbstractHelper
$request['browserInfo']['colorDepth'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::SCREEN_COLOR_DEPTH); $request['browserInfo']['colorDepth'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::SCREEN_COLOR_DEPTH);
$request['browserInfo']['timeZoneOffset'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::TIMEZONE_OFFSET); $request['browserInfo']['timeZoneOffset'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::TIMEZONE_OFFSET);
$request['browserInfo']['language'] = $this->adyenHelper->getCurrentLocaleCode($store); $request['browserInfo']['language'] = $this->adyenHelper->getCurrentLocaleCode($store);
$request['browserInfo']['javaEnabled'] = true; //$payment->getAdditionalInformation(AdyenCcDataAssignObserver::JAVA_ENABLED); $request['browserInfo']['javaEnabled'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::JAVA_ENABLED);
// uset browser related data from additional information // uset browser related data from additional information
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::SCREEN_WIDTH); $payment->unsAdditionalInformation(AdyenCcDataAssignObserver::SCREEN_WIDTH);
...@@ -416,4 +415,24 @@ class Requests extends AbstractHelper ...@@ -416,4 +415,24 @@ class Requests extends AbstractHelper
return $request; return $request;
} }
/**
* The billing address retrieved from the Quote and the one retrieved from the Order has some differences
* Therefore we need to check if the getStreetFull function exists and use that if yes, otherwise use the more
* commont getStreetLine1
*
* @param $billingAddress
* @return array
*/
private function getStreetStringFromBillingAddress($billingAddress)
{
if (method_exists($billingAddress, 'getStreetFull')) {
// Parse address into street and house number where possible
$address = $this->adyenHelper->getStreetFromString($billingAddress->getStreetFull());
} else {
$address = $this->adyenHelper->getStreetFromString($billingAddress->getStreetLine1());
}
return $address;
}
} }
...@@ -54,14 +54,15 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface ...@@ -54,14 +54,15 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
/** /**
* @api * @api
* @param mixed $payload * @param string $payload
* @return mixed * @return string
*/ */
public function initiate($payload) public function initiate($payload)
{ {
// Decode payload from frontend // Decode payload from frontend
$payload = json_decode($payload, true); $payload = json_decode($payload, true);
// Validate JSON that has just been parsed if it was in a valid format
if (json_last_error() !== JSON_ERROR_NONE) { if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed because the request was not a valid JSON')); throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed because the request was not a valid JSON'));
} }
...@@ -71,12 +72,19 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface ...@@ -71,12 +72,19 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
$payment = $quote->getPayment(); $payment = $quote->getPayment();
// Init payments/details request // Init payments/details request
$request = [ $result = [];
"paymentData" => $payment->getAdditionalInformation("threeDS2PaymentData")
];
// unset payment data from additional information if ($paymentData = $payment->getAdditionalInformation("threeDS2PaymentData")) {
$payment->unsAdditionalInformation("threeDS2PaymentData"); // Add payment data into the request object
$request = [
"paymentData" => $payment->getAdditionalInformation("threeDS2PaymentData")
];
// unset payment data from additional information
$payment->unsAdditionalInformation("threeDS2PaymentData");
} else {
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed, payment data not found'));
}
// Depends on the component's response we send a fingerprint or the challenge result // Depends on the component's response we send a fingerprint or the challenge result
if (!empty($payload['details']['threeds2.fingerprint'])) { if (!empty($payload['details']['threeds2.fingerprint'])) {
...@@ -109,8 +117,15 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface ...@@ -109,8 +117,15 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
} }
// Payment can get back to the original flow // Payment can get back to the original flow
// Save the payments response because we are going to need it during the place order flow
$payment->setAdditionalInformation("paymentsResponse", $result); $payment->setAdditionalInformation("paymentsResponse", $result);
// Setting the placeOrder to true enables the process to skip the payments call because the paymentsResponse
// is already in place - only set placeOrder to true when you have the paymentsResponse
$payment->setAdditionalInformation('placeOrder', true); $payment->setAdditionalInformation('placeOrder', true);
// To actually save the additional info changes into the quote
$quote->save(); $quote->save();
// 3DS2 flow is done, original place order flow can continue from frontend // 3DS2 flow is done, original place order flow can continue from frontend
......
...@@ -29,15 +29,58 @@ use Magento\Vault\Model\Ui\VaultConfigProvider; ...@@ -29,15 +29,58 @@ use Magento\Vault\Model\Ui\VaultConfigProvider;
class PaymentInformationManagement class PaymentInformationManagement
{ {
/**
* @var \Magento\Checkout\Model\Session
*/
private $checkoutSession; private $checkoutSession;
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper; private $adyenHelper;
/**
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenRequestHelper; private $adyenRequestHelper;
/**
* @var \Magento\Framework\Model\Context
*/
private $context; private $context;
/**
* @var \Adyen\Payment\Gateway\Http\TransferFactory
*/
private $transferFactory; private $transferFactory;
/**
* @var \Adyen\Payment\Gateway\Http\Client\TransactionPayment
*/
private $transactionPayment; private $transactionPayment;
/**
* @var \Adyen\Payment\Gateway\Validator\CheckoutResponseValidator
*/
private $checkoutResponseValidator; private $checkoutResponseValidator;
/**
* @var \Adyen\Payment\Gateway\Validator\ThreeDS2ResponseValidator
*/
private $threeDS2ResponseValidator; private $threeDS2ResponseValidator;
/**
* PaymentInformationManagement constructor.
*
* @param \Magento\Checkout\Model\Session $checkoutSession
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Adyen\Payment\Helper\Requests $adyenRequestHelper
* @param \Magento\Framework\Model\Context $context
* @param \Adyen\Payment\Gateway\Http\TransferFactory $transferFactory
* @param \Adyen\Payment\Gateway\Http\Client\TransactionPayment $transactionPayment
* @param \Adyen\Payment\Gateway\Validator\CheckoutResponseValidator $checkoutResponseValidator
* @param \Adyen\Payment\Gateway\Validator\ThreeDS2ResponseValidator $threeDS2ResponseValidator
*/
public function __construct( public function __construct(
\Magento\Checkout\Model\Session $checkoutSession, \Magento\Checkout\Model\Session $checkoutSession,
\Adyen\Payment\Helper\Data $adyenHelper, \Adyen\Payment\Helper\Data $adyenHelper,
...@@ -77,7 +120,12 @@ class PaymentInformationManagement ...@@ -77,7 +120,12 @@ class PaymentInformationManagement
if ($payment->getAdditionalInformation('placeOrder')) { if ($payment->getAdditionalInformation('placeOrder')) {
$payment->unsAdditionalInformation('placeOrder'); $payment->unsAdditionalInformation('placeOrder');
$quote->save(); $quote->save();
return true;
return json_encode(
array(
'threeDS2' => false
)
);
} }
// Init request array // Init request array
...@@ -148,16 +196,19 @@ class PaymentInformationManagement ...@@ -148,16 +196,19 @@ class PaymentInformationManagement
"token" => $payment->getAdditionalInformation('threeDS2Token') "token" => $payment->getAdditionalInformation('threeDS2Token')
) )
); );
} else {
// TODO Handle error
} }
} else {
$payment->setAdditionalInformation('paymentsResponse', $paymentsResponse);
$quote->save();
} }
// Save the payments response because we are going to need it during the place order flow
$payment->setAdditionalInformation("paymentsResponse", $paymentsResponse);
// Setting the placeOrder to true enables the process to skip the payments call because the paymentsResponse
// is already in place - only set placeOrder to true when you have the paymentsResponse
$payment->setAdditionalInformation('placeOrder', true); $payment->setAdditionalInformation('placeOrder', true);
// To actually save the additional info changes into the quote
$quote->save(); $quote->save();
// Original flow can continue, return to frontend and place the order // Original flow can continue, return to frontend and place the order
return json_encode( return json_encode(
array( array(
......
!function(e,n){"object"===typeof exports&&"object"===typeof module?module.exports=n():"function"===typeof define&&define.amd?define([],n):"object"===typeof exports?exports.ThreedDS2Utils=n():e.ThreedDS2Utils=n()}(this,function(){return function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=0)}([function(e,n,t){"use strict";t.r(n);var r={container:void 0},o={"01":["250px","400px"],"02":["390px","400px"],"03":["500px","600px"],"04":["600px","400px"],"05":["100%","100%"]};function a(e){return o.hasOwnProperty(e)?e:"01"}var i={createIframe:function(e,n){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"0",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"0",a=arguments.length>4?arguments[4]:void 0;if(!n||0===n.length)throw new Error("Name parameter missing for iframe");e instanceof HTMLElement?r.container=e:r.container=document.body;var i=document.createElement("iframe");i.classList.add(n+"Class"),i.width=t,i.height=o,i.name=n,i.setAttribute("frameborder","0"),i.setAttribute("border","0");var d=document.createTextNode("<p>Your browser does not support iframes.</p>");return i.appendChild(d),r.container.appendChild(i),function(e,n){e.attachEvent?e.attachEvent("onload",function(){n&&"function"===typeof n&&n(e.contentWindow)}):e.onload=function(){n&&"function"===typeof n&&n(e.contentWindow)}}(i,a),i},createForm:function(e,n,t,r,o){if(!e||!n||!t||!r||!o)throw new Error("Not all required parameters provided for form creation");if(0===e.length||0===n.length||0===t.length||0===r.length||0===o.length)throw new Error("Not all required parameters have suitable values");var a=document.createElement("form");a.style.display="none",a.name=e,a.action=n,a.method="POST",a.target=t;var i=document.createElement("input");return i.name=r,i.value=o,a.appendChild(i),a},getBrowserInfo:function(){var e=window&&window.screen?window.screen.width:"",n=window&&window.screen?window.screen.height:"",t=window&&window.screen?window.screen.colorDepth:"",r=window&&window.navigator?window.navigator.userAgent:"",o=!(!window||!window.navigator)&&navigator.javaEnabled(),a="";return window&&window.navigator&&(a=window.navigator.language?window.navigator.language:window.navigator.browserLanguage),{screenWidth:e,screenHeight:n,colorDepth:t,userAgent:r,timeZoneOffset:(new Date).getTimezoneOffset(),language:a,javaEnabled:o}},base64Url:{encode:function(e){var n=window.btoa(e).split("=")[0];return n=(n=n.replace("/+/g","-")).replace("///g","_")},decode:function(e){var n=e;switch((n=(n=n.replace("/-/g","+")).replace("/_/g","/")).length%4){case 0:break;case 2:n+="==";break;case 3:n+="=";break;default:window.console&&window.console.log&&window.console.log("### base64url::decodeBase64URL:: Illegal base64url string!")}try{return window.atob(n)}catch(e){throw new Error(e)}}},config:{challengeWindowSizes:o,validateChallengeWindowSize:a,getChallengeWindowSize:function(e){return o[a(e)]},THREEDS_METHOD_TIMEOUT:1e4,CHALLENGE_TIMEOUT:6e5}};n.default=i}]).default});
\ No newline at end of file
...@@ -35,9 +35,10 @@ define( ...@@ -35,9 +35,10 @@ define(
'mage/storage', 'mage/storage',
'Magento_Checkout/js/model/full-screen-loader', 'Magento_Checkout/js/model/full-screen-loader',
'Magento_Paypal/js/action/set-payment-method', 'Magento_Paypal/js/action/set-payment-method',
'Magento_Checkout/js/action/select-payment-method' 'Magento_Checkout/js/action/select-payment-method',
'Adyen_Payment/js/threeds2-js-utils'
], ],
function ($, ko, Component, customer, creditCardData, additionalValidators, quote, installments, url, VaultEnabler, urlBuilder, storage, fullScreenLoader, setPaymentMethodAction, selectPaymentMethodAction) { function ($, ko, Component, customer, creditCardData, additionalValidators, quote, installments, url, VaultEnabler, urlBuilder, storage, fullScreenLoader, setPaymentMethodAction, selectPaymentMethodAction, threeDS2Utils) {
'use strict'; 'use strict';
...@@ -48,7 +49,7 @@ define( ...@@ -48,7 +49,7 @@ define(
defaults: { defaults: {
template: 'Adyen_Payment/payment/cc-form', template: 'Adyen_Payment/payment/cc-form',
creditCardOwner: '', creditCardOwner: '',
setStoreCc: false, storeCc: false,
installment: '', installment: '',
creditCardDetailsValid: false creditCardDetailsValid: false
}, },
...@@ -121,7 +122,7 @@ define( ...@@ -121,7 +122,7 @@ define(
onChange: function (state, component) { onChange: function (state, component) {
if (!!state.isValid && !component.state.errors.encryptedSecurityCode) { if (!!state.isValid && !component.state.errors.encryptedSecurityCode) {
self.setStoreCc = !!state.data.storeDetails; self.storeCc = !!state.data.storeDetails;
self.variant(state.brand); self.variant(state.brand);
self.creditCardNumber(state.data.encryptedCardNumber); self.creditCardNumber(state.data.encryptedCardNumber);
self.expiryMonth(state.data.encryptedExpiryMonth); self.expiryMonth(state.data.encryptedExpiryMonth);
...@@ -190,6 +191,11 @@ define( ...@@ -190,6 +191,11 @@ define(
}, },
/** /**
* Rendering the 3DS2.0 components * Rendering the 3DS2.0 components
* To do the device fingerprint at the response of IdentifyShopper render the threeDS2DeviceFingerprint
* component
* To render the challenge for the customer at the response of ChallengeShopper render the
* threeDS2Challenge component
* Both of them is going to be rendered in a Magento dialog popup
* *
* @param type * @param type
* @param token * @param token
...@@ -205,7 +211,7 @@ define( ...@@ -205,7 +211,7 @@ define(
fingerprintToken: token, fingerprintToken: token,
onComplete: function(result) { onComplete: function(result) {
self.processThreeDS2(result.data); self.processThreeDS2(result.data);
$('#modal_content').modal("closeModal"); $('#threeDS2Modal').modal("closeModal");
}, },
onError: function(result) { onError: function(result) {
// TODO error handling show error message // TODO error handling show error message
...@@ -223,7 +229,7 @@ define( ...@@ -223,7 +229,7 @@ define(
challengeToken: token, challengeToken: token,
onComplete: function(result) { onComplete: function(result) {
self.processThreeDS2(result.data); self.processThreeDS2(result.data);
$('#modal_content').modal("closeModal"); $('#threeDS2Modal').modal("closeModal");
}, },
onError: function(result) { onError: function(result) {
// TODO error handling show error message // TODO error handling show error message
...@@ -235,7 +241,9 @@ define( ...@@ -235,7 +241,9 @@ define(
self.threeDS2Component.mount(threeDS2Node); self.threeDS2Component.mount(threeDS2Node);
}, },
/** /**
* * The results that the 3DS2 components returns in the onComplete callback needs to be sent to the
* backend to the /adyen/threeDS2Process endpoint and based on the response render a new threeDS2
* component or place the order (validateThreeDS2OrPlaceOrder)
* @param response * @param response
*/ */
processThreeDS2: function(data) { processThreeDS2: function(data) {
...@@ -264,6 +272,8 @@ define( ...@@ -264,6 +272,8 @@ define(
* @returns {{method: *, additional_data: {cc_type: *, number: *, cvc, expiryMonth: *, expiryYear: *, holderName: *, store_cc: *, number_of_installments: *}}} * @returns {{method: *, additional_data: {cc_type: *, number: *, cvc, expiryMonth: *, expiryYear: *, holderName: *, store_cc: *, number_of_installments: *}}}
*/ */
getData: function () { getData: function () {
var browserInfo = threeDS2Utils.getBrowserInfo();
var data = { var data = {
'method': this.item.method, 'method': this.item.method,
additional_data: { additional_data: {
...@@ -274,13 +284,13 @@ define( ...@@ -274,13 +284,13 @@ define(
'expiryMonth': this.expiryMonth(), 'expiryMonth': this.expiryMonth(),
'expiryYear': this.expiryYear(), 'expiryYear': this.expiryYear(),
'holderName': this.creditCardOwner(), 'holderName': this.creditCardOwner(),
'store_cc': this.setStoreCc, 'store_cc': this.storeCc,
'number_of_installments': this.installment(), 'number_of_installments': this.installment(),
'java_enabled': navigator.javaEnabled().toString(), 'java_enabled': browserInfo.javaEnabled,
'screen_color_depth': screen.colorDepth, 'screen_color_depth': browserInfo.colorDepth,
'screen_width': screen.width, 'screen_width': browserInfo.screenWidth,
'screen_height': screen.height, 'screen_height': browserInfo.screenHeight,
'timezone_offset': new Date().getTimezoneOffset() 'timezone_offset': browserInfo.timeZoneOffset
} }
}; };
this.vaultEnabler.visitAdditionalData(data); this.vaultEnabler.visitAdditionalData(data);
...@@ -310,15 +320,20 @@ define( ...@@ -310,15 +320,20 @@ define(
} }
if (this.validate() && additionalValidators.validate()) { if (this.validate() && additionalValidators.validate()) {
//this.isPlaceOrderActionAllowed(false);
fullScreenLoader.startLoader(); fullScreenLoader.startLoader();
self.isPlaceOrderActionAllowed(false);
//update payment method information if additional data was changed //update payment method information if additional data was changed
selectPaymentMethodAction(this.getData()); selectPaymentMethodAction(this.getData());
// here I can remove all the data collected from the card component
// OR I should create a new getData function which just retrieves the data necessary for the 3ds2 flow
setPaymentMethodAction(this.messageContainer).done( setPaymentMethodAction(this.messageContainer).done(
function (responseJSON) { function (responseJSON) {
fullScreenLoader.stopLoader(); fullScreenLoader.stopLoader();
self.isPlaceOrderActionAllowed(true);
self.validateThreeDS2OrPlaceOrder(responseJSON); self.validateThreeDS2OrPlaceOrder(responseJSON);
}); });
return false; return false;
...@@ -327,26 +342,24 @@ define( ...@@ -327,26 +342,24 @@ define(
return false; return false;
}, },
/** /**
* * Based on the response we can start a 3DS2 validation or place the order
* @param responseJSON * @param responseJSON
*/ */
validateThreeDS2OrPlaceOrder: function(responseJSON) { validateThreeDS2OrPlaceOrder: function(responseJSON) {
var self = this; var self = this;
console.log(responseJSON);
var response = JSON.parse(responseJSON); var response = JSON.parse(responseJSON);
if (!!response.threeDS2) { if (!!response.threeDS2) {
$('#modal_content').modal({ $('#threeDS2Modal').modal({
// disable user to hide popup // disable user to hide popup
clickableOverlay: false, clickableOverlay: false,
// empty buttons, we don't need that // empty buttons, we don't need that
buttons: [] buttons: []
}); });
$('#modal_content').modal("openModal"); $('#threeDS2Modal').modal("openModal");
// render component // render component
self.renderThreeDS2Component(response.type, response.token); self.renderThreeDS2Component(response.type, response.token);
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
<div afterRender="renderSecureFields()" data-bind="attr: { id: 'cardContainer'}"></div> <div afterRender="renderSecureFields()" data-bind="attr: { id: 'cardContainer'}"></div>
</div> </div>
<div id="modal_content"> <div id="threeDS2Modal">
<div id="threeDS2Container"></div> <div id="threeDS2Container"></div>
</div> </div>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment