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( ...@@ -26,10 +26,12 @@ define(
'Magento_Payment/js/view/payment/cc-form', 'Magento_Payment/js/view/payment/cc-form',
'Magento_Customer/js/model/customer', 'Magento_Customer/js/model/customer',
'Magento_Payment/js/model/credit-card-validation/credit-card-data', 'Magento_Payment/js/model/credit-card-validation/credit-card-data',
'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/model/quote', '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'; 'use strict';
var cvcLength = ko.observable(4); var cvcLength = ko.observable(4);
...@@ -138,6 +140,8 @@ define( ...@@ -138,6 +140,8 @@ define(
* @override * @override
*/ */
placeOrder: function (data, event) { placeOrder: function (data, event) {
var self = this;
if (event) { if (event) {
event.preventDefault(); event.preventDefault();
} }
...@@ -158,8 +162,29 @@ define( ...@@ -158,8 +162,29 @@ define(
var data = cseInstance.encrypt(cardData); var data = cseInstance.encrypt(cardData);
this.encryptedData(data); this.encryptedData(data);
// rest is default placeOrder logic if (this.validate() && additionalValidators.validate()) {
return this._super(); 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 () { getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()]; return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
......
...@@ -29,20 +29,28 @@ define( ...@@ -29,20 +29,28 @@ define(
'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/checkout-data', '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'; 'use strict';
var updatedExpiryDate = false; var updatedExpiryDate = false;
var recurringDetailReference = ko.observable(null); var recurringDetailReference = ko.observable(null);
var variant = ko.observable(null); var variant = ko.observable(null);
var paymentMethod = ko.observable(null); var paymentMethod = ko.observable(null);
var encryptedData = ko.observable(null);
var numberOfInstallments = ko.observable(null);
var messageComponents;
return Component.extend({ return Component.extend({
defaults: { defaults: {
template: 'Adyen_Payment/payment/oneclick-form', template: 'Adyen_Payment/payment/oneclick-form',
recurringDetailReference: '', recurringDetailReference: '',
encryptedData: '', encryptedData: '',
variant: '' variant: '',
numberOfInstallments: ''
}, },
initObservable: function () { initObservable: function () {
this._super() this._super()
...@@ -51,10 +59,37 @@ define( ...@@ -51,10 +59,37 @@ define(
'creditCardType', 'creditCardType',
'creditCardVerificationNumber', 'creditCardVerificationNumber',
'encryptedData', 'encryptedData',
'variant' 'variant',
'numberOfInstallments'
]); ]);
return this; 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, placeOrderHandler: null,
validateHandler: null, validateHandler: null,
setPlaceOrderHandler: function (handler) { setPlaceOrderHandler: function (handler) {
...@@ -69,77 +104,6 @@ define( ...@@ -69,77 +104,6 @@ define(
isActive: function () { isActive: function () {
return true; 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 () { getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()]; return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
}, },
...@@ -174,6 +138,8 @@ define( ...@@ -174,6 +138,8 @@ define(
} }
} }
var messageContainer = self.messageComponents['messages-' + value.reference_id];
return { return {
'expiry': ko.observable(false), 'expiry': ko.observable(false),
'label': value.agreement_label, 'label': value.agreement_label,
...@@ -196,14 +162,92 @@ define( ...@@ -196,14 +162,92 @@ define(
hasVerification: function () { hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction; 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 return self.afterPlaceOrder(); // needed for placeOrder method
}, },
getPlaceOrderDeferredObject: function() { getPlaceOrderDeferredObject: function () {
return self.getPlaceOrderDeferredObject(); // debugger;;
return $.when(
placeOrderAction(this.getData(), this.getMessageContainer())
);
}, },
validate: function () { validate: function () {
...@@ -243,6 +287,21 @@ define( ...@@ -243,6 +287,21 @@ define(
var self = this; var self = this;
self.expiry(true); self.expiry(true);
return 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 @@ ...@@ -55,6 +55,10 @@
'orderSaveUrl':getPlaceOrderUrl(), 'orderSaveUrl':getPlaceOrderUrl(),
}, 'validation':[]}"> }, '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()}"> <fieldset data-bind="attr: {class: 'fieldset payment items adyen_boleto ' + getCode(), id: 'payment_form_' + getCode()}">
<!-- ko if: (isShowLegend())--> <!-- ko if: (isShowLegend())-->
......
...@@ -38,8 +38,9 @@ ...@@ -38,8 +38,9 @@
</div> </div>
<div class="payment-method-content"> <div class="payment-method-content">
<div class="payment-method-billing-address"> <div class="payment-method-billing-address">
<!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) --> <!-- ko foreach: getRegion(getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko --> <!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko--> <!--/ko-->
</div> </div>
...@@ -53,6 +54,11 @@ ...@@ -53,6 +54,11 @@
}, 'validation':[]}"> }, 'validation':[]}">
<!-- ko foreach: getRegion('messages') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<fieldset <fieldset
data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}"> data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}">
<!-- ko if: (isShowLegend())--> <!-- ko if: (isShowLegend())-->
...@@ -266,6 +272,8 @@ ...@@ -266,6 +272,8 @@
<!-- ko template: getTemplate() --><!-- /ko --> <!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko--> <!--/ko-->
</div> </div>
<div class="actions-toolbar"> <div class="actions-toolbar">
<div class="primary"> <div class="primary">
<button class="action primary checkout" <button class="action primary checkout"
......
...@@ -23,9 +23,11 @@ ...@@ -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" data-bind="css: {'_active': (value == $parent.isBillingAgreementChecked())}">
<div class="payment-method-title field choice"> <div class="payment-method-title field choice">
<input type="radio" <input type="radio"
name="payment[method]" name="payment[method]"
...@@ -50,12 +52,18 @@ ...@@ -50,12 +52,18 @@
</div> </div>
<div class="payment-method-content"> <div class="payment-method-content">
<!-- ko foreach: $parent.getRegion(getMessageName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<div class="payment-method-billing-address"> <div class="payment-method-billing-address">
<!-- ko foreach: $parents[1].getRegion($parent.getBillingAddressFormName()) --> <!-- ko foreach: $parents[1].getRegion(getBillingAddressFormName()) -->
<!-- ko template: getTemplate() --><!-- /ko --> <!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko--> <!--/ko-->
</div> </div>
<form class="form" action="#" method="post" data-bind=" <form class="form" action="#" method="post" data-bind="
attr: {'id': 'adyen_oneclick_' + value, 'data-role': 'adyen_oneclick_' + value }, attr: {'id': 'adyen_oneclick_' + value, 'data-role': 'adyen_oneclick_' + value },
mageInit: { mageInit: {
...@@ -221,9 +229,6 @@ ...@@ -221,9 +229,6 @@
<!-- /ko --> <!-- /ko -->
</fieldset> </fieldset>
<div class="checkout-agreements-block"> <div class="checkout-agreements-block">
<!-- ko foreach: $parents[1].getRegion('before-place-order') --> <!-- ko foreach: $parents[1].getRegion('before-place-order') -->
...@@ -235,7 +240,7 @@ ...@@ -235,7 +240,7 @@
<button class="action primary checkout" <button class="action primary checkout"
type="submit" type="submit"
data-bind=" data-bind="
click: $parent.placeOrder, click: placeOrder,
attr: {title: $t('Place Order')}, attr: {title: $t('Place Order')},
enable: (value == $parent.isBillingAgreementChecked()) enable: (value == $parent.isBillingAgreementChecked())
" "
......
...@@ -45,6 +45,11 @@ ...@@ -45,6 +45,11 @@
<!-- ko template: getTemplate() --><!-- /ko --> <!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko--> <!--/ko-->
</div> </div>
<!-- ko foreach: getRegion('messages') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<fieldset class="fieldset" data-bind='attr: {id: "payment_form_" + getCode()}'> <fieldset class="fieldset" data-bind='attr: {id: "payment_form_" + getCode()}'>
<div class="payment-method-note"> <div class="payment-method-note">
<!-- ko text: $t('You will be redirected to the Adyen App.') --><!-- /ko --> <!-- ko text: $t('You will be redirected to the Adyen App.') --><!-- /ko -->
......
...@@ -46,7 +46,9 @@ ...@@ -46,7 +46,9 @@
<!--/ko--> <!--/ko-->
</div> </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: { <form class="form" id="adyen-sepa-form" data-role="adyen-sepa-form" action="#" method="post" data-bind="mageInit: {
'transparent':{ '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