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 5bc78129 authored by attilak's avatar attilak Committed by Rik ter Beek

PW-634 frontend

- Remove CSE library at One click
- Add Card components (CVC) instead of CSE
- Move to new beta card components
- Remove expiry date update from the template and the js
parent 724c84b3
......@@ -35,6 +35,7 @@ class Data extends AbstractHelper
const LIVE = 'live';
const CHECKOUT_CONTEXT_URL_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/';
const CHECKOUT_CONTEXT_URL_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/';
const CHECKOUT_COMPONENT_JS = 'https://checkoutshopper-beta.adyen.com/checkoutshopper/sdk/2.0.0-beta.4/adyen.js';
/**
* @var \Magento\Framework\Encryption\EncryptorInterface
......@@ -1427,4 +1428,11 @@ class Data extends AbstractHelper
{
return new \Adyen\Service\CheckoutUtility($client);
}
/**
* @return string
*/
public function getCheckoutCardComponentJs() {
return self::CHECKOUT_COMPONENT_JS;
}
}
......@@ -58,6 +58,9 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
} else {
$config['payment']['adyen']['showLogo'] = false;
}
$config['payment']['checkoutCardComponentSource'] = $this->_adyenHelper->getCheckoutCardComponentJs();
return $config;
}
/**
......
......@@ -72,16 +72,17 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
*/
private $ccConfig;
/**
* AdyenOneclickConfigProvider constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\App\RequestInterface $request
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Checkout\Model\Session $session
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\UrlInterface $urlBuilder
*/
/**
* AdyenOneclickConfigProvider constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\App\RequestInterface $request
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Checkout\Model\Session $session
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\UrlInterface $urlBuilder
* @param \Magento\Payment\Model\CcConfig $ccConfig
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\App\RequestInterface $request,
......@@ -132,6 +133,11 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
]
]);
$config['payment']['adyenOneclick']['methodCode'] = self::CODE;
$config['payment']['adyenOneclick']['originKey'] = $this->_adyenHelper->getOriginKeyForBaseUrl();
$config['payment']['adyenOneclick']['checkoutUrl'] = $this->_adyenHelper->getCheckoutContextUrl($this->_storeManager->getStore()->getId());
$config['payment']['adyenOneclick']['locale'] = $this->_adyenHelper->getStoreLocale($this->_storeManager->getStore()->getId());
$recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
......@@ -175,6 +181,7 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
$recurringType
);
}
return $billingAgreements;
}
......
......@@ -445,7 +445,7 @@
<arguments>
<argument name="requestBuilder" xsi:type="object">AdyenPaymentOneclickAuthorizeRequest</argument>
<argument name="transferFactory" xsi:type="object">Adyen\Payment\Gateway\Http\TransferFactory</argument>
<argument name="client" xsi:type="object">Adyen\Payment\Gateway\Http\Client\TransactionAuthorization</argument>
<argument name="client" xsi:type="object">Adyen\Payment\Gateway\Http\Client\TransactionPayment</argument>
<argument name="validator" xsi:type="object">GeneralResponseValidator</argument>
<argument name="handler" xsi:type="object">AdyenPaymentCcResponseHandlerComposite</argument>
</arguments>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -66,6 +66,22 @@ define(
}
);
/** Add view logic here if needed */
return Component.extend({});
return Component.extend({
initialize: function () {
var self = this;
this._super();
// include checkout card component javascript
var checkoutCardComponentScriptTag = document.getElementById('AdyenCheckoutCardComponentScript');
checkoutCardComponentScriptTag = document.createElement('script');
checkoutCardComponentScriptTag.id = "AdyenCheckoutCardComponentScript";
checkoutCardComponentScriptTag.src = self.getCheckoutCardComponentSource();
checkoutCardComponentScriptTag.type = "text/javascript";
document.body.appendChild(checkoutCardComponentScriptTag);
},
getCheckoutCardComponentSource: function() {
return window.checkoutConfig.payment.checkoutCardComponentSource;
},
});
}
);
\ No newline at end of file
......@@ -29,8 +29,7 @@ define(
'Magento_Checkout/js/model/payment/additional-validators',
'Magento_Checkout/js/model/quote',
'Adyen_Payment/js/model/installments',
'mage/url',
'Adyen_Payment/js/adyen.2.0.0'
'mage/url'
],
function ($, ko, Component, customer, creditCardData, additionalValidators, quote, installments, url) {
......@@ -80,13 +79,13 @@ define(
var allInstallments = self.getAllInstallments();
var cardNode = document.getElementById('cardContainer');
var checkout = new Adyen.Checkout({
locale: window.checkoutConfig.payment.adyenCc.locale
var checkout = new AdyenCheckout({
locale: self.getLocale()
});
var card = checkout.create('card', {
originKey: window.checkoutConfig.payment.adyenCc.originKey,
loadingContext: window.checkoutConfig.payment.adyenCc.checkoutUrl,
originKey: self.getOriginKey(),
loadingContext: self.getLoadingContext(),
type: 'card',
groupTypes: self.getAvailableCardTypeAltCodes(),
......@@ -96,7 +95,7 @@ define(
var creditCardType = self.getCcCodeByAltCode(state.brand);
if (creditCardType) {
/* If the credit card type is already set, check if it changed or not */
// If the credit card type is already set, check if it changed or not
if (!self.creditCardType() || self.creditCardType() && self.creditCardType() != creditCardType) {
if (creditCardType in allInstallments) {
......@@ -310,6 +309,15 @@ define(
getCode: function () {
return window.checkoutConfig.payment.adyenCc.methodCode;
},
getOriginKey: function () {
return window.checkoutConfig.payment.adyenCc.originKey;
},
getLoadingContext: function () {
return window.checkoutConfig.payment.adyenCc.checkoutUrl;
},
getLocale: function () {
return window.checkoutConfig.payment.adyenCc.locale;
},
isActive: function () {
return true;
},
......
......@@ -36,19 +36,20 @@ define(
'mage/url'
],
function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction, layout, Messages, placeOrderAction, url) {
'use strict';
var updatedExpiryDate = false;
var messageComponents;
var recurringDetailReference = 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: '',
numberOfInstallments: ''
},
......@@ -58,7 +59,6 @@ define(
'recurringDetailReference',
'creditCardType',
'creditCardVerificationNumber',
'encryptedData',
'variant',
'numberOfInstallments'
]);
......@@ -90,39 +90,20 @@ define(
});
this.messageComponents = messageComponents;
},
placeOrderHandler: null,
validateHandler: null,
setPlaceOrderHandler: function (handler) {
this.placeOrderHandler = handler;
},
setValidateHandler: function (handler) {
this.validateHandler = handler;
},
getCode: function () {
return 'adyen_oneclick';
},
isActive: function () {
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;
},
/**
* List all Adyen billing agreements
* Set up installments
*
* @returns {Array}
*/
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;
......@@ -130,10 +111,10 @@ define(
// pre-define installments if they are set
var i, installments = [];
var grandTotal = quote.totals().grand_total;
var dividedString = "";
var dividedAmount = 0;
if (value.number_of_installments) {
for (i = 0; i < value.number_of_installments.length; i++) {
dividedAmount = (grandTotal / value.number_of_installments[i]).toFixed(quote.getPriceFormat().precision);
......@@ -149,28 +130,19 @@ define(
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),
'encryptedCreditCardVerificationNumber': '',
'creditCardExpMonth': ko.observable(creditCardExpMonth),
'creditCardExpYear': ko.observable(creditCardExpYear),
'getInstallments': ko.observableArray(installments),
getGenerationTime: function () {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
/**
* @override
*/
......@@ -189,24 +161,10 @@ define(
}
}
// only use CSE and installments for cards
// only use 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()) {
if (self.hasVerification()) {
var options = {enableValidations: false};
var cseInstance = adyen.createEncryption(options);
var encryptedDataResult = cseInstance.encrypt(cardData);
encryptedData(encryptedDataResult)
}
// set payment method to adyen_hpp
......@@ -234,28 +192,74 @@ define(
}
return false;
},
/**
* Renders the secure CVC field,
* creates the card component,
* sets up the callbacks for card components
*/
renderSecureCVC: function() {
var self = this;
var oneClickCardNode = document.getElementById('cvcContainer-' + self.value);
var checkout = new AdyenCheckout({
locale: self.getLocale()
});
var oneClickCard = checkout
.create('card', {
originKey: self.getOriginKey(),
loadingContext: self.getLoadingContext(),
type: self.agreement_data.variant,
oneClick: true,
// Specific for oneClick cards
details: [
{
"key": "cardDetails.cvc",
"type": "cvc"
}
],
storedDetails: {
"card": {
"expiryMonth": self.agreement_data.card.expiryMonth,
"expiryYear": self.agreement_data.card.expiryYear,
"holderName": self.agreement_data.card.holderName,
"number": self.agreement_data.card.number
}
},
onChange: function(state) {
if (state.isValid) {
self.encryptedCreditCardVerificationNumber = state.data.encryptedSecurityCode;
} else {
self.encryptedCreditCardVerificationNumber = '';
}
}
})
.mount(oneClickCardNode);
},
/**
* Builds the payment details part of the payment information reqeust
*
* @returns {{method: *, additional_data: {variant: *, recurring_detail_reference: *, number_of_installments: *, cvc: (string|*), expiryMonth: *, expiryYear: *, generationtime: *}}}
*/
getData: function () {
var self = this;
return {
"method": self.item.method,
"method": self.method,
"additional_data": {
variant: variant(),
recurring_detail_reference: recurringDetailReference(),
number_of_installments: numberOfInstallments(),
encrypted_data: encryptedData()
cvc: self.encryptedCreditCardVerificationNumber,
expiryMonth: self.creditCardExpMonth(),
expiryYear: self.creditCardExpYear(),
generationtime: self.getGenerationTime()
}
};
},
isPlaceOrderActionAllowed: function () {
return self.isPlaceOrderActionAllowed(); // needed for placeOrder method
},
afterPlaceOrder: function () {
return self.afterPlaceOrder(); // needed for placeOrder method
},
getPlaceOrderDeferredObject: function () {
return $.when(
placeOrderAction(this.getData(), this.getMessageContainer())
);
},
validate: function () {
var code = self.item.method;
......@@ -266,34 +270,38 @@ define(
var validate = $(form).validation() && $(form).validation('isValid');
// if oneclick or recurring is a card do validation on expiration date
// if oneclick or recurring is a card check CVC validity
var cid = true;
if (this.agreement_data.card) {
// add extra validation because jquery validation will not work on non name attributes
var expiration = Boolean($(form + ' #' + codeValue + '_expiration').valid());
var expiration_yr = Boolean($(form + ' #' + codeValue + '_expiration_yr').valid());
// only check if recurring type is set to oneclick
var cid = true;
if (this.hasVerification()) {
var cid = Boolean($(form + ' #' + codeValue + '_cc_cid').valid());
// if encrypted cvc is empty the request is not valid
if (this.encryptedCreditCardVerificationNumber.length === 0) {
cid = false;
}
} else {
var expiration = true;
var expiration_yr = true;
var cid = true;
}
if (!validate || !expiration || !expiration_yr || !cid) {
if (!validate || !cid) {
return false;
}
return true;
},
selectExpiry: function () {
updatedExpiryDate = true;
var self = this;
self.expiry(true);
return true;
getCode: function () {
return self.item.method;
},
getLocale: function () {
return window.checkoutConfig.payment.adyenOneclick.locale;
},
getOriginKey: function () {
return window.checkoutConfig.payment.adyenOneclick.originKey;
},
getLoadingContext: function () {
return window.checkoutConfig.payment.adyenOneclick.checkoutUrl;
},
getGenerationTime: function () {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
getMessageName: function () {
return 'messages-' + value.reference_id;
......@@ -301,14 +309,29 @@ define(
getMessageContainer: function () {
return messageContainer;
},
isPlaceOrderActionAllowed: function () {
return self.isPlaceOrderActionAllowed(); // needed for placeOrder method
},
afterPlaceOrder: function () {
return self.afterPlaceOrder(); // needed for placeOrder method
},
getPlaceOrderDeferredObject: function () {
return $.when(
placeOrderAction(this.getData(), this.getMessageContainer())
);
},
}
});
return paymentList;
},
/**
* Select a billing agreement (stored one click payment method) from the list
*
* @returns {boolean}
*/
selectBillingAgreement: function () {
var self = this;
self.expiry(false);
updatedExpiryDate = false;
// set payment method data
var data = {
......@@ -340,13 +363,38 @@ define(
if (quote.paymentMethod().method == paymentMethod()) {
return recurringDetailReference();
}
return null;
}),
placeOrderHandler: null,
validateHandler: null,
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;
},
isActive: function () {
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;
}
});
}
);
......@@ -86,90 +86,8 @@
</div>
</div>
<div class="field number expire-update" data-bind="css: {'_disable': (true == expiry())}">
<label class="label">
<span><!-- ko text: $t('Expiration Date')--><!-- /ko --></span>
</label>
<div class="control">
<span data-bind="text: agreement_data.card.expiryMonth + '/' + agreement_data.card.expiryYear"></span>
<a class="" data-bind="click: selectExpiry"
><!-- ko text: $t('Update') --><!-- /ko --></a>
</div>
</div>
<div class="field date required changable-card-expiry" data-bind="attr: {id: getCode() + '_' + value + '_cc_type_exp_div'}, css: {'_active': (true == expiry())}">
<label data-bind="attr: {for: getCode() + '_' + value + '_expiration'}" class="label">
<span><!-- ko text: $t('Expiration Date')--><!-- /ko --></span>
</label>
<div class="control">
<div class="fields group group-2">
<div class="field no-label month">
<div class="control">
<select class="select select-month"
data-encrypted-name="expiryMonth"
data-bind="attr: {id: getCode() + '_' + value + '_expiration', 'data-container': getCode() + '-' + value + '-cc-month', 'data-validate': JSON.stringify({required:true, 'validate-cc-exp':'#' + getCode() + '_expiration_yr'})},
enable: $parent.isActive($parents),
options: $parent.getCcMonthsValues(),
optionsValue: 'value',
optionsText: 'month',
optionsCaption: $t('Month'),
value: creditCardExpMonth"
data-validate="{required:true}">
</select>
</div>
</div>
<div class="field no-label year">
<div class="control">
<select class="select select-year"
data-encrypted-name="expiryYear"
data-bind="attr: {id: getCode() + '_' + value + '_expiration_yr', 'data-container': getCode() + '-' + value + '-cc-year', 'data-validate': JSON.stringify({required:true})},
enable: $parent.isActive($parents),
options: $parent.getCcYearsValues(),
optionsValue: 'value',
optionsText: 'year',
optionsCaption: $t('Year'),
value: creditCardExpYear"
data-validate="{required:true}">
</select>
</div>
</div>
</div>
</div>
</div>
<!-- ko if: hasVerification()-->
<div class="field cvv required" data-bind="attr: {id: getCode() + '_' + value + '_cc_type_cvv_div'}">
<label data-bind="attr: {for: getCode() + '_' + value + '_cc_cid'}" class="label">
<span><!-- ko text: $t('Card Verification Number')--><!-- /ko --></span>
</label>
<div class="control _with-tooltip">
<input type="number"
autocomplete="off"
class="input-text cvv"
data-encrypted-name="cvc"
value=""
data-bind="attr: {id: getCode() + '_' + value + '_cc_cid',
title: $t('Card Verification Number'),
'data-container': getCode() + '-' + value + '-cc-cvv',
'data-validate': JSON.stringify({'required-number':true})},
enable: $parent.isActive($parents),
value: creditCardVerificationNumber"
data-validate="{required:true}"/>
<div class="field-tooltip toggle">
<span class="field-tooltip-action action-cvv"
tabindex="0"
data-toggle="dropdown"
data-bind="attr: {title: $t('What is this?')}, mageInit: {'dropdown':{'activeClass': '_active'}}">
<span><!-- ko text: $t('What is this?')--><!-- /ko --></span>
</span>
<div class="field-tooltip-content"
data-target="dropdown"
data-bind="html: $parent.getCvvImageHtml()"></div>
</div>
</div>
</div>
<div afterRender="renderSecureCVC()" data-bind="attr: { id: 'cvcContainer-' + value}" ></div>
<!-- /ko -->
<!--/ko-->
......
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