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 ce8b167f authored by Rik ter Beek's avatar Rik ter Beek

Fix 3D secure, for oneclick show error message in the payment method rather then on top

parent c0c23405
......@@ -26,10 +26,12 @@ define(
'Magento_Payment/js/view/payment/cc-form',
'Magento_Customer/js/model/customer',
'Magento_Payment/js/model/credit-card-validation/credit-card-data',
'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/model/quote',
'Adyen_Payment/js/model/installments'
'Adyen_Payment/js/model/installments',
'mage/url'
],
function ($, ko, Component, customer, creditCardData, quote, installments) {
function ($, ko, Component, customer, creditCardData, additionalValidators, quote, installments, url) {
'use strict';
var cvcLength = ko.observable(4);
......@@ -138,6 +140,8 @@ define(
* @override
*/
placeOrder: function (data, event) {
var self = this;
if (event) {
event.preventDefault();
}
......@@ -158,8 +162,29 @@ define(
var data = cseInstance.encrypt(cardData);
this.encryptedData(data);
// rest is default placeOrder logic
return this._super();
if (this.validate() && additionalValidators.validate()) {
this.isPlaceOrderActionAllowed(false);
this.getPlaceOrderDeferredObject()
.fail(
function () {
self.isPlaceOrderActionAllowed(true);
}
).done(
function () {
self.afterPlaceOrder();
if (self.redirectAfterPlaceOrder) {
// use custom redirect Link for supporting 3D secure
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
}
}
);
return true;
}
return false;
},
getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
......
......@@ -29,20 +29,28 @@ 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'
'Magento_Checkout/js/action/redirect-on-success',
'uiLayout',
'Magento_Ui/js/model/messages',
'Magento_Checkout/js/action/place-order',
'mage/url'
],
function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction) {
function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction, layout, Messages, placeOrderAction, url) {
'use strict';
var updatedExpiryDate = false;
var recurringDetailReference = ko.observable(null);
var variant = ko.observable(null);
var variant = ko.observable(null);
var paymentMethod = ko.observable(null);
var encryptedData = ko.observable(null);
var numberOfInstallments = ko.observable(null);
var messageComponents;
return Component.extend({
defaults: {
template: 'Adyen_Payment/payment/oneclick-form',
recurringDetailReference: '',
encryptedData: '',
variant: ''
variant: '',
numberOfInstallments: ''
},
initObservable: function () {
this._super()
......@@ -51,10 +59,37 @@ define(
'creditCardType',
'creditCardVerificationNumber',
'encryptedData',
'variant'
'variant',
'numberOfInstallments'
]);
return this;
},
initialize: function () {
var self = this;
this._super();
// create component needs to be in initialize method
var messageComponents = {};
_.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function (value) {
var messageContainer = new Messages();
var name = 'messages-' + value.reference_id;
var messagesComponent = {
parent: self.name,
name: 'messages-' + value.reference_id,
// name: self.name + '.messages',
displayArea: 'messages-' + value.reference_id,
component: 'Magento_Ui/js/view/messages',
config: {
messageContainer: messageContainer
}
};
layout([messagesComponent]);
messageComponents[name] = messageContainer;
});
this.messageComponents = messageComponents;
},
placeOrderHandler: null,
validateHandler: null,
setPlaceOrderHandler: function (handler) {
......@@ -69,77 +104,6 @@ define(
isActive: function () {
return true;
},
/**
* @override
*/
placeOrder: function (data, event) {
var self = this;
if (event) {
event.preventDefault();
}
var data = {
"method": self.method,
"additional_data": {
variant: self.agreement_data.variant,
recurring_detail_reference: self.value
}
}
// only use CSE and installments for cards
if (self.agreement_data.card) {
var generationtime = self.getGenerationTime();
var cardData = {
cvc: self.creditCardVerificationNumber,
expiryMonth: self.creditCardExpMonth(),
expiryYear: self.creditCardExpYear(),
generationtime: generationtime
};
if (updatedExpiryDate || self.hasVerification()) {
var options = {enableValidations: false};
var cseInstance = adyen.createEncryption(options);
var encryptedData = cseInstance.encrypt(cardData);
data.additional_data.encrypted_data = encryptedData;
}
// set payment method to adyen_hpp
data.additional_data.number_of_installments = self.installment;
}
// in different context so need custom place order logic
if (this.validate() && additionalValidators.validate()) {
self.isPlaceOrderActionAllowed(false);
this.getPlaceOrderDeferredObject()
.fail(
function () {
self.isPlaceOrderActionAllowed(true);
}
).done(
function () {
self.afterPlaceOrder();
redirectOnSuccessAction.execute();
}
);
return true;
}
return false;
},
getData: function () {
debugger;;
return {
"method": this.item.method,
"additional_data": {
variant: variant(),
recurring_detail_reference: recurringDetailReference()
}
};
},
getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
},
......@@ -174,6 +138,8 @@ define(
}
}
var messageContainer = self.messageComponents['messages-' + value.reference_id];
return {
'expiry': ko.observable(false),
'label': value.agreement_label,
......@@ -196,14 +162,92 @@ define(
hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
isPlaceOrderActionAllowed: function() {
return self.isPlaceOrderActionAllowed(); // needed for placeOrder method
/**
* @override
*/
placeOrder: function (data, event) {
var self = this;
if (event) {
event.preventDefault();
}
var data = {
"method": self.method,
"additional_data": {
variant: self.agreement_data.variant,
recurring_detail_reference: self.value
}
}
// only use CSE and installments for cards
if (self.agreement_data.card) {
var generationtime = self.getGenerationTime();
var cardData = {
cvc: self.creditCardVerificationNumber,
expiryMonth: self.creditCardExpMonth(),
expiryYear: self.creditCardExpYear(),
generationtime: generationtime
};
if (updatedExpiryDate || self.hasVerification()) {
var options = {enableValidations: false};
var cseInstance = adyen.createEncryption(options);
var encryptedDataResult = cseInstance.encrypt(cardData);
encryptedData(encryptedDataResult)
}
// set payment method to adyen_hpp
// TODO can observer in front-end this not needed
numberOfInstallments(self.installment);
}
// in different context so need custom place order logic
if (this.validate() && additionalValidators.validate()) {
self.isPlaceOrderActionAllowed(false);
this.getPlaceOrderDeferredObject()
.fail(
function () {
self.isPlaceOrderActionAllowed(true);
}
).done(
function () {
self.afterPlaceOrder();
// use custom redirect Link for supporting 3D secure
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
}
);
// debugger;;
return true;
}
return false;
},
afterPlaceOrder: function() {
getData: function () {
return {
"method": self.item.method,
"additional_data": {
variant: variant(),
recurring_detail_reference: recurringDetailReference(),
number_of_installments: numberOfInstallments(),
encrypted_data: encryptedData()
}
};
},
isPlaceOrderActionAllowed: function () {
return self.isPlaceOrderActionAllowed(); // needed for placeOrder method
},
afterPlaceOrder: function () {
return self.afterPlaceOrder(); // needed for placeOrder method
},
getPlaceOrderDeferredObject: function() {
return self.getPlaceOrderDeferredObject();
getPlaceOrderDeferredObject: function () {
// debugger;;
return $.when(
placeOrderAction(this.getData(), this.getMessageContainer())
);
},
validate: function () {
......@@ -243,6 +287,21 @@ define(
var self = this;
self.expiry(true);
return true;
},
getRegion: function (name) {
self.getRegion(name);
},
getMessageName: function () {
return 'messages-' + value.reference_id;
},
getMessageContainer: function () {
return messageContainer;
},
/**
* @return {String}
*/
getBillingAddressFormName: function () {
return 'billing-address-form-' + self.item.method + '-' + value.reference_id;
}
}
});
......
......@@ -55,6 +55,10 @@
'orderSaveUrl':getPlaceOrderUrl(),
}, 'validation':[]}">
<!-- ko foreach: getRegion('messages') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<fieldset data-bind="attr: {class: 'fieldset payment items adyen_boleto ' + getCode(), id: 'payment_form_' + getCode()}">
<!-- ko if: (isShowLegend())-->
......
......@@ -38,8 +38,9 @@
</div>
<div class="payment-method-content">
<div class="payment-method-billing-address">
<!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
<!-- ko foreach: getRegion(getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
......@@ -53,6 +54,11 @@
}, 'validation':[]}">
<!-- ko foreach: getRegion('messages') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<fieldset
data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}">
<!-- ko if: (isShowLegend())-->
......@@ -266,6 +272,8 @@
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<div class="actions-toolbar">
<div class="primary">
<button class="action primary checkout"
......
......@@ -23,9 +23,11 @@
-->
<!-- ko foreach: getAdyenBillingAgreements() -->
<!-- ko foreach: getAdyenBillingAgreements() -->
<div class="payment-method" data-bind="css: {'_active': (value == $parent.isBillingAgreementChecked())}">
<div class="payment-method-title field choice">
<input type="radio"
name="payment[method]"
......@@ -50,12 +52,18 @@
</div>
<div class="payment-method-content">
<!-- ko foreach: $parent.getRegion(getMessageName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<div class="payment-method-billing-address">
<!-- ko foreach: $parents[1].getRegion($parent.getBillingAddressFormName()) -->
<!-- ko foreach: $parents[1].getRegion(getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<form class="form" action="#" method="post" data-bind="
attr: {'id': 'adyen_oneclick_' + value, 'data-role': 'adyen_oneclick_' + value },
mageInit: {
......@@ -221,9 +229,6 @@
<!-- /ko -->
</fieldset>
<div class="checkout-agreements-block">
<!-- ko foreach: $parents[1].getRegion('before-place-order') -->
......@@ -235,7 +240,7 @@
<button class="action primary checkout"
type="submit"
data-bind="
click: $parent.placeOrder,
click: placeOrder,
attr: {title: $t('Place Order')},
enable: (value == $parent.isBillingAgreementChecked())
"
......
......@@ -45,6 +45,11 @@
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>
<!-- ko foreach: getRegion('messages') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<fieldset class="fieldset" data-bind='attr: {id: "payment_form_" + getCode()}'>
<div class="payment-method-note">
<!-- ko text: $t('You will be redirected to the Adyen App.') --><!-- /ko -->
......
......@@ -46,7 +46,9 @@
<!--/ko-->
</div>
<!-- ko foreach: getRegion('messages') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<form class="form" id="adyen-sepa-form" data-role="adyen-sepa-form" action="#" method="post" data-bind="mageInit: {
'transparent':{
......
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