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 ...@@ -35,6 +35,7 @@ class Data extends AbstractHelper
const LIVE = 'live'; const LIVE = 'live';
const CHECKOUT_CONTEXT_URL_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/'; const CHECKOUT_CONTEXT_URL_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/';
const CHECKOUT_CONTEXT_URL_TEST = 'https://checkoutshopper-test.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 * @var \Magento\Framework\Encryption\EncryptorInterface
...@@ -1427,4 +1428,11 @@ class Data extends AbstractHelper ...@@ -1427,4 +1428,11 @@ class Data extends AbstractHelper
{ {
return new \Adyen\Service\CheckoutUtility($client); return new \Adyen\Service\CheckoutUtility($client);
} }
/**
* @return string
*/
public function getCheckoutCardComponentJs() {
return self::CHECKOUT_COMPONENT_JS;
}
} }
...@@ -58,6 +58,9 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface ...@@ -58,6 +58,9 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
} else { } else {
$config['payment']['adyen']['showLogo'] = false; $config['payment']['adyen']['showLogo'] = false;
} }
$config['payment']['checkoutCardComponentSource'] = $this->_adyenHelper->getCheckoutCardComponentJs();
return $config; return $config;
} }
/** /**
......
...@@ -72,16 +72,17 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface ...@@ -72,16 +72,17 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
*/ */
private $ccConfig; private $ccConfig;
/** /**
* AdyenOneclickConfigProvider constructor. * AdyenOneclickConfigProvider constructor.
* *
* @param \Adyen\Payment\Helper\Data $adyenHelper * @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\App\RequestInterface $request * @param \Magento\Framework\App\RequestInterface $request
* @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Checkout\Model\Session $session * @param \Magento\Checkout\Model\Session $session
* @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\UrlInterface $urlBuilder * @param \Magento\Framework\UrlInterface $urlBuilder
*/ * @param \Magento\Payment\Model\CcConfig $ccConfig
*/
public function __construct( public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper, \Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\App\RequestInterface $request, \Magento\Framework\App\RequestInterface $request,
...@@ -132,6 +133,11 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface ...@@ -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'); $recurringType = $this->_adyenHelper->getAdyenAbstractConfigData('recurring_type');
$canCreateBillingAgreement = false; $canCreateBillingAgreement = false;
if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") { if ($recurringType == "ONECLICK" || $recurringType == "ONECLICK,RECURRING") {
...@@ -175,6 +181,7 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface ...@@ -175,6 +181,7 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
$recurringType $recurringType
); );
} }
return $billingAgreements; return $billingAgreements;
} }
......
...@@ -445,7 +445,7 @@ ...@@ -445,7 +445,7 @@
<arguments> <arguments>
<argument name="requestBuilder" xsi:type="object">AdyenPaymentOneclickAuthorizeRequest</argument> <argument name="requestBuilder" xsi:type="object">AdyenPaymentOneclickAuthorizeRequest</argument>
<argument name="transferFactory" xsi:type="object">Adyen\Payment\Gateway\Http\TransferFactory</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="validator" xsi:type="object">GeneralResponseValidator</argument>
<argument name="handler" xsi:type="object">AdyenPaymentCcResponseHandlerComposite</argument> <argument name="handler" xsi:type="object">AdyenPaymentCcResponseHandlerComposite</argument>
</arguments> </arguments>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -66,6 +66,22 @@ define( ...@@ -66,6 +66,22 @@ define(
} }
); );
/** Add view logic here if needed */ /** 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( ...@@ -29,8 +29,7 @@ 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',
'Adyen_Payment/js/model/installments', 'Adyen_Payment/js/model/installments',
'mage/url', 'mage/url'
'Adyen_Payment/js/adyen.2.0.0'
], ],
function ($, ko, Component, customer, creditCardData, additionalValidators, quote, installments, url) { function ($, ko, Component, customer, creditCardData, additionalValidators, quote, installments, url) {
...@@ -80,13 +79,13 @@ define( ...@@ -80,13 +79,13 @@ define(
var allInstallments = self.getAllInstallments(); var allInstallments = self.getAllInstallments();
var cardNode = document.getElementById('cardContainer'); var cardNode = document.getElementById('cardContainer');
var checkout = new Adyen.Checkout({ var checkout = new AdyenCheckout({
locale: window.checkoutConfig.payment.adyenCc.locale locale: self.getLocale()
}); });
var card = checkout.create('card', { var card = checkout.create('card', {
originKey: window.checkoutConfig.payment.adyenCc.originKey, originKey: self.getOriginKey(),
loadingContext: window.checkoutConfig.payment.adyenCc.checkoutUrl, loadingContext: self.getLoadingContext(),
type: 'card', type: 'card',
groupTypes: self.getAvailableCardTypeAltCodes(), groupTypes: self.getAvailableCardTypeAltCodes(),
...@@ -96,7 +95,7 @@ define( ...@@ -96,7 +95,7 @@ define(
var creditCardType = self.getCcCodeByAltCode(state.brand); var creditCardType = self.getCcCodeByAltCode(state.brand);
if (creditCardType) { 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 (!self.creditCardType() || self.creditCardType() && self.creditCardType() != creditCardType) {
if (creditCardType in allInstallments) { if (creditCardType in allInstallments) {
...@@ -310,6 +309,15 @@ define( ...@@ -310,6 +309,15 @@ define(
getCode: function () { getCode: function () {
return window.checkoutConfig.payment.adyenCc.methodCode; 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 () { isActive: function () {
return true; return true;
}, },
......
...@@ -36,19 +36,20 @@ define( ...@@ -36,19 +36,20 @@ define(
'mage/url' 'mage/url'
], ],
function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction, layout, Messages, placeOrderAction, url) { function (ko, _, $, Component, selectPaymentMethodAction, additionalValidators, quote, checkoutData, redirectOnSuccessAction, layout, Messages, placeOrderAction, url) {
'use strict'; 'use strict';
var updatedExpiryDate = false;
var messageComponents;
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 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: '',
variant: '', variant: '',
numberOfInstallments: '' numberOfInstallments: ''
}, },
...@@ -58,7 +59,6 @@ define( ...@@ -58,7 +59,6 @@ define(
'recurringDetailReference', 'recurringDetailReference',
'creditCardType', 'creditCardType',
'creditCardVerificationNumber', 'creditCardVerificationNumber',
'encryptedData',
'variant', 'variant',
'numberOfInstallments' 'numberOfInstallments'
]); ]);
...@@ -90,39 +90,20 @@ define( ...@@ -90,39 +90,20 @@ define(
}); });
this.messageComponents = messageComponents; this.messageComponents = messageComponents;
}, },
placeOrderHandler: null, /**
validateHandler: null, * List all Adyen billing agreements
setPlaceOrderHandler: function (handler) { * Set up installments
this.placeOrderHandler = handler; *
}, * @returns {Array}
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;
},
getAdyenBillingAgreements: function () { getAdyenBillingAgreements: function () {
var self = this; var self = this;
// convert to list so you can iterate // convert to list so you can iterate
var paymentList = _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function (value) { var paymentList = _.map(window.checkoutConfig.payment.adyenOneclick.billingAgreements, function (value) {
var creditCardExpMonth, creditCardExpYear = false; var creditCardExpMonth, creditCardExpYear = false;
if (value.agreement_data.card) { if (value.agreement_data.card) {
creditCardExpMonth = value.agreement_data.card.expiryMonth; creditCardExpMonth = value.agreement_data.card.expiryMonth;
creditCardExpYear = value.agreement_data.card.expiryYear; creditCardExpYear = value.agreement_data.card.expiryYear;
...@@ -130,10 +111,10 @@ define( ...@@ -130,10 +111,10 @@ define(
// pre-define installments if they are set // pre-define installments if they are set
var i, installments = []; var i, installments = [];
var grandTotal = quote.totals().grand_total; var grandTotal = quote.totals().grand_total;
var dividedString = ""; var dividedString = "";
var dividedAmount = 0; var dividedAmount = 0;
if (value.number_of_installments) { if (value.number_of_installments) {
for (i = 0; i < value.number_of_installments.length; i++) { for (i = 0; i < value.number_of_installments.length; i++) {
dividedAmount = (grandTotal / value.number_of_installments[i]).toFixed(quote.getPriceFormat().precision); dividedAmount = (grandTotal / value.number_of_installments[i]).toFixed(quote.getPriceFormat().precision);
...@@ -149,28 +130,19 @@ define( ...@@ -149,28 +130,19 @@ define(
var messageContainer = self.messageComponents['messages-' + value.reference_id]; var messageContainer = self.messageComponents['messages-' + value.reference_id];
return { return {
'expiry': ko.observable(false),
'label': value.agreement_label, 'label': value.agreement_label,
'value': value.reference_id, 'value': value.reference_id,
'agreement_data': value.agreement_data, 'agreement_data': value.agreement_data,
'logo': value.logo, 'logo': value.logo,
'installment': '', 'installment': '',
'number_of_installments': value.number_of_installments, 'number_of_installments': value.number_of_installments,
getInstallments: ko.observableArray(installments),
'method': self.item.method, 'method': self.item.method,
getCode: function () { 'encryptedCreditCardVerificationNumber': '',
return self.item.method; 'creditCardExpMonth': ko.observable(creditCardExpMonth),
}, 'creditCardExpYear': ko.observable(creditCardExpYear),
creditCardVerificationNumber: '', 'getInstallments': ko.observableArray(installments),
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
*/ */
...@@ -189,24 +161,10 @@ define( ...@@ -189,24 +161,10 @@ define(
} }
} }
// only use CSE and installments for cards // only use installments for cards
if (self.agreement_data.card) { if (self.agreement_data.card) {
if (self.hasVerification()) {
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 options = {enableValidations: false};
var cseInstance = adyen.createEncryption(options);
var encryptedDataResult = cseInstance.encrypt(cardData);
encryptedData(encryptedDataResult)
} }
// set payment method to adyen_hpp // set payment method to adyen_hpp
...@@ -234,28 +192,74 @@ define( ...@@ -234,28 +192,74 @@ define(
} }
return false; 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 () { getData: function () {
var self = this;
return { return {
"method": self.item.method, "method": self.method,
"additional_data": { "additional_data": {
variant: variant(), variant: variant(),
recurring_detail_reference: recurringDetailReference(), recurring_detail_reference: recurringDetailReference(),
number_of_installments: numberOfInstallments(), 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 () { validate: function () {
var code = self.item.method; var code = self.item.method;
...@@ -266,34 +270,38 @@ define( ...@@ -266,34 +270,38 @@ define(
var validate = $(form).validation() && $(form).validation('isValid'); 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) { if (this.agreement_data.card) {
// add extra validation because jquery validation will not work on non name attributes // if encrypted cvc is empty the request is not valid
var expiration = Boolean($(form + ' #' + codeValue + '_expiration').valid()); if (this.encryptedCreditCardVerificationNumber.length === 0) {
var expiration_yr = Boolean($(form + ' #' + codeValue + '_expiration_yr').valid()); cid = false;
// only check if recurring type is set to oneclick
var cid = true;
if (this.hasVerification()) {
var cid = Boolean($(form + ' #' + codeValue + '_cc_cid').valid());
} }
} else {
var expiration = true;
var expiration_yr = true;
var cid = true;
} }
if (!validate || !expiration || !expiration_yr || !cid) { if (!validate || !cid) {
return false; return false;
} }
return true; return true;
}, },
selectExpiry: function () { getCode: function () {
updatedExpiryDate = true; return self.item.method;
var self = this; },
self.expiry(true); getLocale: function () {
return true; 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 () { getMessageName: function () {
return 'messages-' + value.reference_id; return 'messages-' + value.reference_id;
...@@ -301,14 +309,29 @@ define( ...@@ -301,14 +309,29 @@ define(
getMessageContainer: function () { getMessageContainer: function () {
return messageContainer; 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; return paymentList;
}, },
/**
* Select a billing agreement (stored one click payment method) from the list
*
* @returns {boolean}
*/
selectBillingAgreement: function () { selectBillingAgreement: function () {
var self = this; var self = this;
self.expiry(false);
updatedExpiryDate = false;
// set payment method data // set payment method data
var data = { var data = {
...@@ -340,13 +363,38 @@ define( ...@@ -340,13 +363,38 @@ define(
if (quote.paymentMethod().method == paymentMethod()) { if (quote.paymentMethod().method == paymentMethod()) {
return recurringDetailReference(); return recurringDetailReference();
} }
return null; return null;
}), }),
placeOrderHandler: null,
validateHandler: null,
setPlaceOrderHandler: function (handler) {
this.placeOrderHandler = handler;
},
setValidateHandler: function (handler) {
this.validateHandler = handler;
},
getPlaceOrderUrl: function () { getPlaceOrderUrl: function () {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()]; 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 @@ ...@@ -86,90 +86,8 @@
</div> </div>
</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()--> <!-- ko if: hasVerification()-->
<div class="field cvv required" data-bind="attr: {id: getCode() + '_' + value + '_cc_type_cvv_div'}"> <div afterRender="renderSecureCVC()" data-bind="attr: { id: 'cvcContainer-' + value}" ></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>
<!-- /ko --> <!-- /ko -->
<!--/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