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,6 +104,64 @@ define( ...@@ -69,6 +104,64 @@ define(
isActive: function () { isActive: function () {
return true; return true;
}, },
getControllerName: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
},
context: function () {
return this;
},
canCreateBillingAgreement: function () {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
},
isShowLegend: function () {
return true;
},
getAdyenBillingAgreements: function () {
var self = this;
// convert to list so you can iterate
var paymentList = _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function (value) {
var creditCardExpMonth, creditCardExpYear = false;
if (value.agreement_data.card) {
creditCardExpMonth = value.agreement_data.card.expiryMonth;
creditCardExpYear = value.agreement_data.card.expiryYear;
}
// pre-define installments if they are set
var i, installments = [];
if (value.number_of_installments > 0) {
for (i = 1; i <= value.number_of_installments; i++) {
installments.push({
key: i,
value: i
});
}
}
var messageContainer = self.messageComponents['messages-' + value.reference_id];
return {
'expiry': ko.observable(false),
'label': value.agreement_label,
'value': value.reference_id,
'agreement_data': value.agreement_data,
'logo': value.logo,
'installment': '',
'number_of_installments': value.number_of_installments,
getInstallments: ko.observableArray(installments),
'method': self.item.method,
getCode: function () {
return self.item.method;
},
creditCardVerificationNumber: '',
creditCardExpMonth: ko.observable(creditCardExpMonth),
creditCardExpYear: ko.observable(creditCardExpYear),
getGenerationTime: function () {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
/** /**
* @override * @override
*/ */
...@@ -103,12 +196,13 @@ define( ...@@ -103,12 +196,13 @@ define(
var options = {enableValidations: false}; var options = {enableValidations: false};
var cseInstance = adyen.createEncryption(options); var cseInstance = adyen.createEncryption(options);
var encryptedData = cseInstance.encrypt(cardData); var encryptedDataResult = cseInstance.encrypt(cardData);
data.additional_data.encrypted_data = encryptedData; encryptedData(encryptedDataResult)
} }
// set payment method to adyen_hpp // set payment method to adyen_hpp
data.additional_data.number_of_installments = self.installment; // TODO can observer in front-end this not needed
numberOfInstallments(self.installment);
} }
// in different context so need custom place order logic // in different context so need custom place order logic
...@@ -123,87 +217,37 @@ define( ...@@ -123,87 +217,37 @@ define(
).done( ).done(
function () { function () {
self.afterPlaceOrder(); self.afterPlaceOrder();
redirectOnSuccessAction.execute(); // use custom redirect Link for supporting 3D secure
window.location.replace(url.build(window.checkoutConfig.payment[quote.paymentMethod().method].redirectUrl));
} }
); );
// debugger;;
return true; return true;
} }
return false; return false;
}, },
getData: function () { getData: function () {
debugger;;
return { return {
"method": this.item.method, "method": self.item.method,
"additional_data": { "additional_data": {
variant: variant(), variant: variant(),
recurring_detail_reference: recurringDetailReference() recurring_detail_reference: recurringDetailReference(),
number_of_installments: numberOfInstallments(),
encrypted_data: encryptedData()
} }
}; };
}, },
getControllerName: function () { isPlaceOrderActionAllowed: function () {
return window.checkoutConfig.payment.iframe.controllerName[this.getCode()];
},
context: function () {
return this;
},
canCreateBillingAgreement: function () {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
},
isShowLegend: function () {
return true;
},
getAdyenBillingAgreements: function () {
var self = this;
// convert to list so you can iterate
var paymentList = _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function (value) {
var creditCardExpMonth, creditCardExpYear = false;
if (value.agreement_data.card) {
creditCardExpMonth = value.agreement_data.card.expiryMonth;
creditCardExpYear = value.agreement_data.card.expiryYear;
}
// pre-define installments if they are set
var i, installments = [];
if (value.number_of_installments > 0) {
for (i = 1; i <= value.number_of_installments; i++) {
installments.push({
key: i,
value: i
});
}
}
return {
'expiry': ko.observable(false),
'label': value.agreement_label,
'value': value.reference_id,
'agreement_data': value.agreement_data,
'logo': value.logo,
'installment': '',
'number_of_installments': value.number_of_installments,
getInstallments: ko.observableArray(installments),
'method': self.item.method,
getCode: function () {
return self.item.method;
},
creditCardVerificationNumber: '',
creditCardExpMonth: ko.observable(creditCardExpMonth),
creditCardExpYear: ko.observable(creditCardExpYear),
getGenerationTime: function () {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
isPlaceOrderActionAllowed: function() {
return self.isPlaceOrderActionAllowed(); // needed for placeOrder method return self.isPlaceOrderActionAllowed(); // needed for placeOrder method
}, },
afterPlaceOrder: function() { 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