We will be off from 27/1 (Monday) to 31/1 (Friday) (GMT +7) for our Tet Holiday (Lunar New Year) 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);
} }
......
...@@ -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
$result = [];
if ($paymentData = $payment->getAdditionalInformation("threeDS2PaymentData")) {
// Add payment data into the request object
$request = [ $request = [
"paymentData" => $payment->getAdditionalInformation("threeDS2PaymentData") "paymentData" => $payment->getAdditionalInformation("threeDS2PaymentData")
]; ];
// unset payment data from additional information // unset payment data from additional information
$payment->unsAdditionalInformation("threeDS2PaymentData"); $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