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 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