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 8da089ce authored by Attila Kiss's avatar Attila Kiss Committed by GitHub

[PW-3130] Use the generic component for stored payment methods (#919)

* Tokenize payment methods in payment response handler

Do not save recurring details "manually" for /payments/details response

* Standardise Oneclick Observer

* Use generic component for recurring payments

* sonarcloud suggestions

* Remove unused div
parent 3f7ebc9e
......@@ -55,20 +55,6 @@ class OneclickAuthorizationDataBuilder implements BuilderInterface
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
// If ccType is set use this. For bcmc you need bcmc otherwise it will fail
$requestBody['paymentMethod']['type'] = "scheme";
if ($variant = $payment->getAdditionalInformation(AdyenOneclickDataAssignObserver::VARIANT)) {
$requestBody['paymentMethod']['type'] = $variant;
}
if ($securityCode = $payment->getAdditionalInformation(
AdyenOneclickDataAssignObserver::ENCRYPTED_SECURITY_CODE
)) {
$requestBody['paymentMethod']['encryptedSecurityCode'] = $securityCode;
}
$payment->unsAdditionalInformation(AdyenOneclickDataAssignObserver::ENCRYPTED_SECURITY_CODE);
if ($payment->getAdditionalInformation('customer_interaction')) {
$shopperInteraction = "Ecommerce";
} else {
......@@ -76,9 +62,7 @@ class OneclickAuthorizationDataBuilder implements BuilderInterface
}
$requestBody['shopperInteraction'] = $shopperInteraction;
$requestBody['paymentMethod']['recurringDetailReference'] = $payment->getAdditionalInformation(
AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE
);
// if it is a sepadirectdebit set selectedBrand to sepadirectdebit in the case of oneclick
if ($payment->getCcType() == "sepadirectdebit") {
......
......@@ -1713,7 +1713,7 @@ class Data extends AbstractHelper
$billingAgreement->getAgreementId(),
$order->getId()
)) {
// save into sales_billing_agreement_order
// save into billing_agreement_order
$billingAgreement->addOrderRelation($order);
}
// add to order to save agreement
......@@ -1733,6 +1733,7 @@ class Data extends AbstractHelper
$comment = $order->addStatusHistoryComment($message);
$order->addRelatedObject($comment);
$order->save();
}
}
......
......@@ -27,6 +27,7 @@ use Adyen\Payment\Logger\AdyenLogger;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\Data\OrderPaymentInterface;
use Magento\Sales\Model\Order;
use Adyen\Payment\Helper\Vault;
class PaymentResponseHandler
{
......@@ -41,12 +42,36 @@ class PaymentResponseHandler
const ERROR = 'Error';
const CANCELLED = 'Cancelled';
/**
* @var AdyenLogger
*/
private $adyenLogger;
/**
* @var Data
*/
private $adyenHelper;
/**
* @var Vault
*/
private $vaultHelper;
/**
* PaymentResponseHandler constructor.
*
* @param AdyenLogger $adyenLogger
* @param Data $adyenHelper
* @param \Adyen\Payment\Helper\Vault $vaultHelper
*/
public function __construct(
AdyenLogger $adyenLogger
AdyenLogger $adyenLogger,
Data $adyenHelper,
Vault $vaultHelper
) {
$this->adyenLogger = $adyenLogger;
$this->adyenHelper = $adyenHelper;
$this->vaultHelper = $vaultHelper;
}
public function formatPaymentResponse($resultCode, $action = null, $additionalData = null)
......@@ -144,6 +169,24 @@ class PaymentResponseHandler
}
break;
case self::AUTHORISED:
if (!empty($paymentsResponse['pspReference'])) {
// set pspReference as transactionId
$payment->setCcTransId($paymentsResponse['pspReference']);
$payment->setLastTransId($paymentsResponse['pspReference']);
// set transaction
$payment->setTransactionId($paymentsResponse['pspReference']);
}
if (!empty($paymentsResponse['additionalData']['recurring.recurringDetailReference']) &&
$payment->getMethodInstance()->getCode() !== \Adyen\Payment\Model\Ui\AdyenOneclickConfigProvider::CODE) {
if ($this->adyenHelper->isCreditCardVaultEnabled()) {
$this->vaultHelper->saveRecurringDetails($payment, $paymentsResponse['additionalData']);
} else {
$order = $payment->getOrder();
$this->adyenHelper->createAdyenBillingAgreement($order, $paymentsResponse['additionalData']);
}
}
case self::IDENTIFY_SHOPPER:
case self::CHALLENGE_SHOPPER:
break;
......
......@@ -27,7 +27,6 @@ use Adyen\AdyenException;
use Adyen\Payment\Api\AdyenPaymentDetailsInterface;
use Adyen\Payment\Helper\Data;
use Adyen\Payment\Helper\PaymentResponseHandler;
use Adyen\Payment\Helper\Vault;
use Adyen\Payment\Logger\AdyenLogger;
use Magento\Checkout\Model\Session;
use Magento\Framework\Exception\LocalizedException;
......@@ -50,11 +49,6 @@ class AdyenPaymentDetails implements AdyenPaymentDetailsInterface
*/
private $adyenLogger;
/**
* @var Vault
*/
private $vaultHelper;
/**
* @var OrderRepositoryInterface
*/
......@@ -71,7 +65,6 @@ class AdyenPaymentDetails implements AdyenPaymentDetailsInterface
* @param Session $checkoutSession
* @param Data $adyenHelper
* @param AdyenLogger $adyenLogger
* @param Vault $vaultHelper
* @param OrderRepositoryInterface $orderRepository
* @param PaymentResponseHandler $paymentResponseHandler
*/
......@@ -79,14 +72,12 @@ class AdyenPaymentDetails implements AdyenPaymentDetailsInterface
Session $checkoutSession,
Data $adyenHelper,
AdyenLogger $adyenLogger,
Vault $vaultHelper,
OrderRepositoryInterface $orderRepository,
PaymentResponseHandler $paymentResponseHandler
) {
$this->checkoutSession = $checkoutSession;
$this->adyenHelper = $adyenHelper;
$this->adyenLogger = $adyenLogger;
$this->vaultHelper = $vaultHelper;
$this->orderRepository = $orderRepository;
$this->paymentResponseHandler = $paymentResponseHandler;
}
......@@ -139,14 +130,7 @@ class AdyenPaymentDetails implements AdyenPaymentDetailsInterface
throw new LocalizedException(__('Payment details call failed'));
}
//TODO test this with payments that return additionalData
//TODO check for Authorized result code and move to the handler
if (!empty($paymentDetails['additionalData'])) {
$this->vaultHelper->saveRecurringDetails($payment, $paymentDetails['additionalData']);
}
//TODO check if order save is necessary to save additionalData
// Handle response
if (!$this->paymentResponseHandler->handlePaymentResponse($paymentDetails, $payment, $order)) {
$this->checkoutSession->restoreQuote();
throw new LocalizedException(__('The payment is REFUSED.'));
......
......@@ -37,6 +37,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
const GUEST_EMAIL = 'guestEmail';
const COMBO_CARD_TYPE = 'combo_card_type';
const STATE_DATA = 'stateData';
const STORE_PAYMENT_METHOD = 'storePaymentMethod';
/**
* Approved root level keys from additional data array
......@@ -113,5 +114,10 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
if (!empty($additionalData[self::CC_TYPE])) {
$paymentInfo->setCcType($additionalData[self::CC_TYPE]);
}
// set storeCc
if (!empty($stateData[self::STORE_PAYMENT_METHOD])) {
$paymentInfo->setAdditionalInformation(self::STORE_CC, $stateData[self::STORE_PAYMENT_METHOD]);
}
}
}
......@@ -23,39 +23,34 @@
namespace Adyen\Payment\Observer;
use Adyen\Service\Validator\CheckoutStateDataValidator;
use Adyen\Service\Validator\DataArrayValidator;
use Magento\Framework\Event\Observer;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface;
class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
{
const RECURRING_DETAIL_REFERENCE = 'recurring_detail_reference';
const ENCRYPTED_SECURITY_CODE = 'cvc';
const CC_TYPE = 'cc_type';
const BRAND = 'brand';
const NUMBER_OF_INSTALLMENTS = 'number_of_installments';
const VARIANT = 'variant';
const JAVA_ENABLED = 'java_enabled';
const SCREEN_COLOR_DEPTH = 'screen_color_depth';
const SCREEN_WIDTH = 'screen_width';
const SCREEN_HEIGHT = 'screen_height';
const TIMEZONE_OFFSET = 'timezone_offset';
const LANGUAGE = 'language';
const STATE_DATA = 'stateData';
/**
* Approved root level keys from additional data array
*
* @var array
*/
protected $additionalInformationList = [
self::RECURRING_DETAIL_REFERENCE,
self::ENCRYPTED_SECURITY_CODE,
private static $approvedAdditionalDataKeys = [
self::STATE_DATA,
self::NUMBER_OF_INSTALLMENTS,
self::VARIANT,
self::JAVA_ENABLED,
self::SCREEN_COLOR_DEPTH,
self::SCREEN_WIDTH,
self::SCREEN_HEIGHT,
self::TIMEZONE_OFFSET,
self::LANGUAGE
];
/**
* @var CheckoutStateDataValidator
*/
private $checkoutStateDataValidator;
/**
* @var \Adyen\Payment\Helper\Data
*/
......@@ -72,9 +67,11 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
CheckoutStateDataValidator $checkoutStateDataValidator,
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context
) {
$this->checkoutStateDataValidator = $checkoutStateDataValidator;
$this->adyenHelper = $adyenHelper;
$this->appState = $context->getAppState();
}
......@@ -85,27 +82,47 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
*/
public function execute(Observer $observer)
{
// Get request fields
$data = $this->readDataArgument($observer);
// Get additional data array
$additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
if (!is_array($additionalData)) {
return;
}
$paymentInfo = $this->readPaymentModelArgument($observer);
// Get a validated additional data array
$additionalData = DataArrayValidator::getArrayOnlyWithApprovedKeys(
$additionalData,
self::$approvedAdditionalDataKeys
);
// set ccType
$variant = $additionalData['variant'];
$ccType = $this->adyenHelper->getMagentoCreditCartType($variant);
$paymentInfo->setCcType($ccType);
// json decode state data
$stateData = [];
if (!empty($additionalData[self::STATE_DATA])) {
$stateData = json_decode($additionalData[self::STATE_DATA], true);
}
foreach ($this->additionalInformationList as $additionalInformationKey) {
if (isset($additionalData[$additionalInformationKey])) {
$paymentInfo->setAdditionalInformation(
$additionalInformationKey,
$additionalData[$additionalInformationKey]
// Get validated state data array
if (!empty($stateData)) {
$stateData = $this->checkoutStateDataValidator->getValidatedAdditionalData(
$stateData
);
}
// Replace state data with the decoded and validated state data
$additionalData[self::STATE_DATA] = $stateData;
// Set additional data in the payment
$paymentInfo = $this->readPaymentModelArgument($observer);
foreach ($additionalData as $key => $data) {
$paymentInfo->setAdditionalInformation($key, $data);
}
// set ccType
if (!empty($stateData[self::BRAND])) {
$ccType = $this->adyenHelper->getMagentoCreditCartType($stateData[self::BRAND]);
$paymentInfo->setCcType($ccType);
}
// set customerInteraction
......@@ -115,11 +132,6 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
} else {
$paymentInfo->setAdditionalInformation('customer_interaction', false);
}
// set ccType
$variant = $additionalData['variant'];
$ccType = $this->adyenHelper->getMagentoCreditCartType($variant);
$paymentInfo->setAdditionalInformation('cc_type', $ccType);
}
/**
......
......@@ -29,21 +29,17 @@ define(
'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/checkout-data',
'Magento_Checkout/js/action/redirect-on-success',
'uiLayout',
'Magento_Ui/js/model/messages',
'mage/url',
'Magento_Checkout/js/model/full-screen-loader',
'Magento_Paypal/js/action/set-payment-method',
'Magento_Checkout/js/model/url-builder',
'mage/storage',
'Magento_Checkout/js/action/place-order',
'Magento_Checkout/js/model/error-processor',
'Adyen_Payment/js/model/adyen-payment-service',
'Adyen_Payment/js/bundle',
],
function(
'Adyen_Payment/js/model/adyen-configuration',
],
function(
ko,
_,
$,
......@@ -52,19 +48,16 @@ function(
additionalValidators,
quote,
checkoutData,
redirectOnSuccessAction,
layout,
Messages,
url,
fullScreenLoader,
setPaymentMethodAction,
urlBuilder,
storage,
placeOrderAction,
errorProcessor,
adyenPaymentService,
AdyenComponent
) {
AdyenComponent,
adyenConfiguration,
) {
'use strict';
......@@ -77,7 +70,8 @@ function(
var isValid = ko.observable(false);
return Component.extend({
isPlaceOrderActionAllowed: ko.observable(quote.billingAddress() != null),
isPlaceOrderActionAllowed: ko.observable(
quote.billingAddress() != null),
defaults: {
template: 'Adyen_Payment/payment/oneclick-form',
recurringDetailReference: '',
......@@ -87,29 +81,29 @@ function(
initObservable: function() {
this._super().observe([
'recurringDetailReference',
'creditCardType',
'encryptedCreditCardVerificationNumber',
'variant',
'numberOfInstallments',
]);
return this;
},
initialize: function() {
var self = this;
let self = this;
this._super();
// create component needs to be in initialize method
var messageComponents = {};
_.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements,
function(value) {
let messageComponents = {};
_.map(
window.checkoutConfig.payment.adyenOneclick.billingAgreements,
function(billingAgreement) {
var messageContainer = new Messages();
var name = 'messages-' + value.reference_id;
var messagesComponent = {
let messageContainer = new Messages();
let name = 'messages-' + billingAgreement.reference_id;
let messagesComponent = {
parent: self.name,
name: 'messages-' + value.reference_id,
name: 'messages-' + billingAgreement.reference_id,
// name: self.name + '.messages',
displayArea: 'messages-' + value.reference_id,
displayArea: 'messages-' +
billingAgreement.reference_id,
component: 'Magento_Ui/js/view/messages',
config: {
messageContainer: messageContainer,
......@@ -120,6 +114,80 @@ function(
messageComponents[name] = messageContainer;
});
this.messageComponents = messageComponents;
let paymentMethodsObserver = adyenPaymentService.getPaymentMethods();
let paymentMethodsResponse = paymentMethodsObserver();
if (!!paymentMethodsResponse) {
this.checkoutComponent = new AdyenCheckout({
locale: adyenConfiguration.getLocale(),
originKey: adyenConfiguration.getOriginKey(),
environment: adyenConfiguration.getCheckoutEnvironment(),
paymentMethodsResponse: paymentMethodsResponse.paymentMethodsResponse,
onAdditionalDetails: this.handleOnAdditionalDetails.bind(this),
},
);
}
},
handleOnAdditionalDetails: function(result) {
var self = this;
var request = result.data;
request.orderId = self.orderId;
fullScreenLoader.stopLoader();
// TODO outsource creating the modal
var popupModal = $('#oneclick_actionModal').modal({
// disable user to hide popup
clickableOverlay: false,
responsive: true,
innerScroll: false,
// empty buttons, we don't need that
buttons: [],
modalClass: 'oneclick_actionModal',
});
popupModal.modal('openModal');
adyenPaymentService.paymentDetails(request).
done(function(responseJSON) {
self.handleAdyenResult(responseJSON,
self.orderId);
}).
fail(function(response) {
errorProcessor.process(response,
self.messageContainer);
self.isPlaceOrderActionAllowed(true);
fullScreenLoader.stopLoader();
});
},
/**
* Based on the response we can start a 3DS2 validation or place the order
* @param responseJSON
*/
handleAdyenResult: function(responseJSON, orderId) {
var self = this;
var response = JSON.parse(responseJSON);
if (!!response.isFinal) {
// Status is final redirect to the redirectUrl
window.location.replace(url.build(
window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl,
));
} else {
// Handle action
self.handleAction(response.action, orderId);
}
},
handleAction: function(action, orderId) {
try {
this.checkoutComponent.createFromAction(
action).
mount('#oneclick_actionContainer');
} catch (e) {
console.log(e);
}
},
/**
* List all Adyen billing agreements
......@@ -130,26 +198,16 @@ function(
getAdyenBillingAgreements: function() {
var self = this;
// shareable adyen checkout component
var checkout = new AdyenCheckout({
locale: self.getLocale(),
originKey: self.getOriginKey(),
environment: self.getCheckoutEnvironment(),
risk: {
enabled: false,
},
});
// convert to list so you can iterate
var paymentList = _.map(
window.checkoutConfig.payment.adyenOneclick.billingAgreements,
function(value) {
function(billingAgreement) {
var creditCardExpMonth, creditCardExpYear = false;
if (value.agreement_data.card) {
creditCardExpMonth = value.agreement_data.card.expiryMonth;
creditCardExpYear = value.agreement_data.card.expiryYear;
if (billingAgreement.agreement_data.card) {
creditCardExpMonth = billingAgreement.agreement_data.card.expiryMonth;
creditCardExpYear = billingAgreement.agreement_data.card.expiryYear;
}
// pre-define installments if they are set
......@@ -158,23 +216,26 @@ function(
var dividedString = '';
var dividedAmount = 0;
if (value.number_of_installments) {
for (i = 0; i < value.number_of_installments.length; i++) {
if (billingAgreement.number_of_installments) {
for (i = 0; i <
billingAgreement.number_of_installments.length; i++) {
dividedAmount = (grandTotal /
value.number_of_installments[i]).toFixed(
billingAgreement.number_of_installments[i]).toFixed(
quote.getPriceFormat().precision);
dividedString = value.number_of_installments[i] + ' x ' +
dividedAmount + ' ' + quote.totals().quote_currency_code;
dividedString = billingAgreement.number_of_installments[i] +
' x ' +
dividedAmount + ' ' +
quote.totals().quote_currency_code;
installments.push({
key: [dividedString],
value: value.number_of_installments[i],
value: billingAgreement.number_of_installments[i],
});
}
}
var messageContainer = self.messageComponents['messages-' +
value.reference_id];
billingAgreement.reference_id];
// for recurring enable the placeOrder button at all times
var placeOrderAllowed = true;
......@@ -186,21 +247,24 @@ function(
}
return {
'label': value.agreement_label,
'value': value.reference_id,
'agreement_data': value.agreement_data,
'logo': value.logo,
'label': billingAgreement.agreement_label,
'value': billingAgreement.reference_id,
'agreement_data': billingAgreement.agreement_data,
'logo': billingAgreement.logo,
'installment': '',
'number_of_installments': value.number_of_installments,
'number_of_installments': billingAgreement.number_of_installments,
'method': self.item.method,
'encryptedCreditCardVerificationNumber': '',
'creditCardExpMonth': ko.observable(creditCardExpMonth),
'creditCardExpYear': ko.observable(creditCardExpYear),
'creditCardExpMonth': ko.observable(
creditCardExpMonth),
'creditCardExpYear': ko.observable(
creditCardExpYear),
'getInstallments': ko.observableArray(installments),
'placeOrderAllowed': ko.observable(placeOrderAllowed),
'placeOrderAllowed': ko.observable(
placeOrderAllowed),
isButtonActive: function() {
return self.isActive() && this.getCode() == self.isChecked() &&
return self.isActive() && this.getCode() ==
self.isChecked() &&
self.isBillingAgreementChecked() &&
this.placeOrderAllowed() &&
self.isPlaceOrderActionAllowed();
......@@ -215,34 +279,40 @@ function(
* @returns {boolean}
*/
placeOrder: function(data, event) {
var self = this;
var innerSelf = this;
if (event) {
event.preventDefault();
}
// only use installments for cards
if (self.agreement_data.card) {
if (self.hasVerification()) {
if (this.agreement_data.card) {
if (this.hasVerification()) {
var options = {enableValidations: false};
}
numberOfInstallments(self.installment);
numberOfInstallments(this.installment);
}
if (this.validate() && additionalValidators.validate()) {
if (this.validate() &&
additionalValidators.validate()) {
fullScreenLoader.startLoader();
self.isPlaceOrderActionAllowed(false);
this.isPlaceOrderActionAllowed(false);
self.getPlaceOrderDeferredObject().fail(
this.getPlaceOrderDeferredObject().fail(
function() {
fullScreenLoader.stopLoader();
self.isPlaceOrderActionAllowed(true);
innerSelf.isPlaceOrderActionAllowed(
true);
},
).done(
function(orderId) {
self.afterPlaceOrder();
adyenPaymentService.getOrderPaymentStatus(orderId).
innerSelf.afterPlaceOrder();
self.orderId = orderId;
adyenPaymentService.getOrderPaymentStatus(
orderId).
done(function(responseJSON) {
self.validateThreeDS2OrPlaceOrder(responseJSON,
self.handleAdyenResult(
responseJSON,
orderId);
});
},
......@@ -257,13 +327,9 @@ function(
* sets up the callbacks for card components
*/
renderSecureCVC: function() {
var self = this;
if (!self.getOriginKey()) {
if (!this.getOriginKey()) {
return;
}
var oneClickCardNode = document.getElementById(
'cvcContainer-' + self.value);
var hideCVC = false;
// hide cvc if contract has been stored as recurring
......@@ -271,136 +337,27 @@ function(
hideCVC = true;
}
var oneClickCard = checkout.create('card', {
try {
this.component = self.checkoutComponent.create(
'card', {
hideCVC: hideCVC,
brand: self.agreement_data.variant,
brand: this.agreement_data.variant,
storedPaymentMethodId: this.value,
expiryMonth: self.agreement_data.card.expiryMonth,
expiryYear: self.agreement_data.card.expiryYear,
holderName: self.agreement_data.card.holderName,
onChange: function(state, component) {
if (state.isValid) {
self.placeOrderAllowed(true);
isValid(true);
if (typeof state.data !== 'undefined' &&
typeof state.data.paymentMethod !== 'undefined' &&
typeof state.data.paymentMethod.encryptedSecurityCode !==
'undefined'
) {
self.encryptedCreditCardVerificationNumber = state.data.paymentMethod.encryptedSecurityCode;
}
} else {
self.encryptedCreditCardVerificationNumber = '';
if (self.agreement_data.variant != 'maestro') {
self.placeOrderAllowed(false);
isValid(false);
}
}
},
}).mount(oneClickCardNode);
window.adyencheckout = oneClickCard;
},
/**
* Based on the response we can start a 3DS2 validation or place the order
* @param responseJSON
*/
validateThreeDS2OrPlaceOrder: function(responseJSON, orderId) {
var self = this;
var response = JSON.parse(responseJSON);
if (!!response.threeDS2) {
// render component
self.renderThreeDS2Component(response.type, response.token,
orderId);
} else {
window.location.replace(url.build(
window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
expiryMonth: this.agreement_data.card.expiryMonth,
expiryYear: this.agreement_data.card.expiryYear,
holderName: this.agreement_data.card.holderName,
onChange: this.handleOnChange.bind(this)
}).mount('#cvcContainer-' + this.value);
} catch (err) {
console.log(err);
// The component does not exist yet
}
},
/**
* 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 token
*/
renderThreeDS2Component: function(type, token, orderId) {
var self = this;
var threeDS2Node = document.getElementById(
'threeDS2ContainerOneClick');
if (type == 'IdentifyShopper') {
self.threeDS2Component = checkout.create(
'threeDS2DeviceFingerprint', {
fingerprintToken: token,
onComplete: function(result) {
var request = result.data;
request.orderId = orderId;
adyenPaymentService.paymentDetails(request).
done(function(responseJSON) {
self.validateThreeDS2OrPlaceOrder(responseJSON,
orderId);
}).
fail(function(result) {
errorProcessor.process(result,
self.getMessageContainer());
self.isPlaceOrderActionAllowed(true);
fullScreenLoader.stopLoader();
});
},
onError: function(error) {
console.log(JSON.stringify(error));
},
});
} else if (type == 'ChallengeShopper') {
fullScreenLoader.stopLoader();
var popupModal = $('#threeDS2ModalOneClick').modal({
// disable user to hide popup
clickableOverlay: false,
responsive: true,
innerScroll: false,
// empty buttons, we don't need that
buttons: [],
modalClass: 'threeDS2Modal',
});
popupModal.modal('openModal');
self.threeDS2Component = checkout.create('threeDS2Challenge',
{
challengeToken: token,
onComplete: function(result) {
popupModal.modal('closeModal');
fullScreenLoader.startLoader();
var request = result.data;
request.orderId = orderId;
adyenPaymentService.paymentDetails(request).
done(function(responseJSON) {
self.validateThreeDS2OrPlaceOrder(responseJSON,
orderId);
}).
fail(function(result) {
errorProcessor.process(result,
self.getMessageContainer());
self.isPlaceOrderActionAllowed(true);
fullScreenLoader.stopLoader();
});
},
onError: function(error) {
console.log(JSON.stringify(error));
},
});
}
self.threeDS2Component.mount(threeDS2Node);
handleOnChange: function(state, component) {
this.placeOrderAllowed(
!!state.isValid);
isValid(!!state.isValid);
},
/**
* Builds the payment details part of the payment information reqeust
......@@ -409,23 +366,17 @@ function(
*/
getData: function() {
var self = this;
// todo use state.data
var browserInfo = [];
let stateData;
if ('component' in self) {
stateData = self.component.data;
}
return {
'method': self.method,
additional_data: {
variant: variant(),
recurring_detail_reference: recurringDetailReference(),
store_cc: true,
number_of_installments: numberOfInstallments(),
cvc: self.encryptedCreditCardVerificationNumber,
java_enabled: browserInfo.javaEnabled,
screen_color_depth: browserInfo.colorDepth,
screen_width: browserInfo.screenWidth,
screen_height: browserInfo.screenHeight,
timezone_offset: browserInfo.timeZoneOffset,
language: browserInfo.language,
stateData: JSON.stringify(stateData),
},
};
},
......@@ -442,7 +393,8 @@ function(
// bcmc does not have any cvc
if (!validate ||
(isValid() == false && variant() != 'bcmc' && variant() !=
(isValid() == false && variant() !=
'bcmc' && variant() !=
'maestro')) {
return false;
}
......@@ -456,13 +408,14 @@ function(
return self.hasVerification();
},
getMessageName: function() {
return 'messages-' + value.reference_id;
return 'messages-' +
billingAgreement.reference_id;
},
getMessageContainer: function() {
return messageContainer;
},
getOriginKey: function() {
return self.getOriginKey();
return adyenConfiguration.getOriginKey();
},
isPlaceOrderActionAllowed: function() {
return self.isPlaceOrderActionAllowed(); // needed for placeOrder method
......@@ -472,7 +425,8 @@ function(
},
getPlaceOrderDeferredObject: function() {
return $.when(
placeOrderAction(this.getData(), this.getMessageContainer()),
placeOrderAction(this.getData(),
this.getMessageContainer()),
);
},
};
......@@ -509,6 +463,7 @@ function(
return true;
},
isBillingAgreementChecked: ko.computed(function() {
if (!quote.paymentMethod()) {
......@@ -520,17 +475,20 @@ function(
}
return null;
}),
placeOrderHandler: null,
validateHandler: null,
getPlaceOrderUrl: function() {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()];
},
hasVerification: function() {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
setPlaceOrderHandler: function(handler) {
this.placeOrderHandler = handler;
},
setValidateHandler: function(handler) {
this.validateHandler = handler;
},
getPlaceOrderUrl: function() {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()];
},
getCode: function() {
return window.checkoutConfig.payment.adyenOneclick.methodCode;
},
......@@ -543,26 +501,9 @@ function(
context: function() {
return this;
},
canCreateBillingAgreement: function() {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
},
isShowLegend: function() {
return true;
},
hasVerification: function() {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
getLocale: function() {
return window.checkoutConfig.payment.adyenOneclick.locale;
},
getOriginKey: function() {
return window.checkoutConfig.payment.adyen.originKey;
},
getCheckoutEnvironment: function() {
return window.checkoutConfig.payment.adyen.checkoutEnvironment;
},
});
}
)
;
},
);
......@@ -71,6 +71,12 @@
<fieldset
data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + $parent.getCode() + '_' + value}">
<div id="oneclick_actionModalWrapper">
<div id="oneclick_actionModal">
<div id="oneclick_actionContainer"></div>
</div>
</div>
<!-- ko if: agreement_data.card -->
<div class="field number">
<label class="label">
......@@ -135,10 +141,6 @@
</div>
<!-- /ko -->
<div id="threeDS2ModalOneClick">
<div id="threeDS2ContainerOneClick"></div>
</div>
</fieldset>
<div class="checkout-agreements-block">
......
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