We will work on Apr 26th (Saturday) and will be off from Apr 30th (Wednesday) until May 2nd (Friday) for public holiday in our country

Commit 002899f9 authored by cyattilakiss's avatar cyattilakiss Committed by GitHub

Merge pull request #334 from Adyen/PW-634

PW-634 Secure Fields integration for stored methods (oneclick & recurring)
parents 6d2c0b75 e77f961f
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2015 Adyen BV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface;
/**
* Payment Data Builder
*/
class Authorize3DSecureDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* PaymentDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(\Adyen\Payment\Helper\Data $adyenHelper)
{
$this->adyenHelper = $adyenHelper;
}
/**
* @param array $buildSubject
* @return array
*/
public function build(array $buildSubject)
{
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$md = $payment->getAdditionalInformation('md');
$paResponse = $payment->getAdditionalInformation('paResponse');
return [
"md" => $md,
"paResponse" => $paResponse,
];
}
}
\ No newline at end of file
......@@ -38,11 +38,6 @@ class CcAuthorizationDataBuilder implements BuilderInterface
*/
private $appState;
/**
* @var \Adyen\Payment\Logger\AdyenLogger
*/
protected $_adyenLogger;
/**
* CcAuthorizationDataBuilder constructor.
*
......@@ -51,13 +46,11 @@ class CcAuthorizationDataBuilder implements BuilderInterface
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger
\Magento\Framework\Model\Context $context
)
{
$this->adyenHelper = $adyenHelper;
$this->appState = $context->getAppState();
$this->_adyenLogger = $adyenLogger;
}
/**
......@@ -74,11 +67,26 @@ class CcAuthorizationDataBuilder implements BuilderInterface
$request = [];
$request['paymentMethod']['type'] = "scheme";
$request['paymentMethod']['encryptedCardNumber'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::CREDIT_CARD_NUMBER);
$request['paymentMethod']['encryptedExpiryMonth'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::EXPIRY_MONTH);
$request['paymentMethod']['encryptedExpiryYear'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::EXPIRY_YEAR);
$request['paymentMethod']['encryptedSecurityCode'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::SECURITY_CODE);
$request['paymentMethod']['holderName'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::HOLDER_NAME);
if ($cardNumber = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::CREDIT_CARD_NUMBER)) {
$request['paymentMethod']['encryptedCardNumber'] = $cardNumber;
}
if ($expiryMonth = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::EXPIRY_MONTH)) {
$request['paymentMethod']['encryptedExpiryMonth'] = $expiryMonth;
}
if ($expiryYear = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::EXPIRY_YEAR)) {
$request['paymentMethod']['encryptedExpiryYear'] = $expiryYear;
}
if ($holderName = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::HOLDER_NAME)) {
$request['paymentMethod']['holderName'] = $holderName;
}
if ($securityCode = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::SECURITY_CODE)) {
$request['paymentMethod']['encryptedSecurityCode'] = $securityCode;
}
// Remove from additional data
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::CREDIT_CARD_NUMBER);
......
......@@ -23,6 +23,7 @@
namespace Adyen\Payment\Gateway\Request;
use Adyen\Payment\Observer\AdyenOneclickDataAssignObserver;
use Magento\Payment\Gateway\Request\BuilderInterface;
class OneclickAuthorizationDataBuilder implements BuilderInterface
......@@ -53,7 +54,6 @@ class OneclickAuthorizationDataBuilder implements BuilderInterface
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$recurringDetailReference = $payment->getAdditionalInformation("recurring_detail_reference");
if ($payment->getAdditionalInformation('customer_interaction')) {
$shopperInteraction = "Ecommerce";
......@@ -61,8 +61,8 @@ class OneclickAuthorizationDataBuilder implements BuilderInterface
$shopperInteraction = "ContAuth";
}
$request['selectedRecurringDetailReference'] = $recurringDetailReference;
$request['shopperInteraction'] = $shopperInteraction;
$request['paymentMethod']['recurringDetailReference'] = $payment->getAdditionalInformation(AdyenOneclickDataAssignObserver::RECURRING_DETAIL_REFERENCE);
// if it is a sepadirectdebit set selectedBrand to sepadirectdebit in the case of oneclick
if ($payment->getCcType() == "sepadirectdebit") {
......
......@@ -38,17 +38,11 @@ class SepaAuthorizationDataBuilder implements BuilderInterface
$payment = $paymentDataObject->getPayment();
$request = [];
// set brand to sepa
$request['selectedBrand'] = "sepadirectdebit";
// add bankDetails into request
$bankAccount = [
'iban' => $payment->getAdditionalInformation("iban"),
'ownerName' => $payment->getAdditionalInformation("account_name"),
'countryCode' => $payment->getAdditionalInformation("country")
];
$request['bankAccount'] = $bankAccount;
$request['paymentMethod']['type'] = "sepadirectdebit";
$request['paymentMethod']['sepa.ibanNumber'] = $payment->getAdditionalInformation("iban");
$request['paymentMethod']['sepa.ownerName'] = $payment->getAdditionalInformation("account_name");
$request['paymentMethod']['countryCode'] = $payment->getAdditionalInformation("country");
return $request;
}
......
......@@ -35,6 +35,8 @@ 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_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/2.0.0-beta.4/adyen.js';
const CHECKOUT_COMPONENT_JS_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/2.0.0-beta.4/adyen.js';
/**
* @var \Magento\Framework\Encryption\EncryptorInterface
......@@ -1283,4 +1285,16 @@ class Data extends AbstractHelper
{
return new \Adyen\Service\CheckoutUtility($client);
}
/**
* @param int|null $storeId
* @return string
*/
public function getCheckoutCardComponentJs($storeId = null) {
if ($this->isDemoMode($storeId)) {
return self::CHECKOUT_COMPONENT_JS_TEST;
}
return self::CHECKOUT_COMPONENT_JS_LIVE;
}
}
......@@ -140,7 +140,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
$config['payment']['adyenCc']['locale'] = $this->_adyenHelper->getStoreLocale($this->storeManager->getStore()->getId());
$config['payment']['adyenCc']['generationTime'] = date("c");
$config['payment']['adyenCc']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
$config['payment']['adyenCc']['icons'] = $this->getIcons();
......
......@@ -33,13 +33,20 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
*/
protected $_adyenHelper;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* AdyenGenericConfigProvider constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(\Adyen\Payment\Helper\Data $adyenHelper) {
public function __construct(\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Store\Model\StoreManagerInterface $storeManager) {
$this->_adyenHelper = $adyenHelper;
$this->storeManager = $storeManager;
}
/**
* Define foreach payment methods the RedirectUrl
......@@ -57,6 +64,9 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
} else {
$config['payment']['adyen']['showLogo'] = false;
}
$config['payment']['checkoutCardComponentSource'] = $this->_adyenHelper->getCheckoutCardComponentJs($this->storeManager->getStore()->getId());
return $config;
}
/**
......
......@@ -81,6 +81,7 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
* @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,
......@@ -131,15 +132,17 @@ 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") {
$canCreateBillingAgreement = true;
}
// Commented out otherwise would break the checkoutsince the getLibrarySource is removed
//$config['payment'] ['adyenOneclick']['librarySource'] = $this->_adyenHelper->getLibrarySource();
$config['payment']['adyenOneclick']['generationTime'] = date("c");
$config['payment']['adyenOneclick']['canCreateBillingAgreement'] = $canCreateBillingAgreement;
$recurringContractType = $this->_getRecurringContractType();
......@@ -174,6 +177,7 @@ class AdyenOneclickConfigProvider implements ConfigProviderInterface
$recurringType
);
}
return $billingAgreements;
}
......
......@@ -32,7 +32,7 @@ use Magento\Quote\Api\Data\PaymentInterface;
class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
{
const RECURRING_DETAIL_REFERENCE = 'recurring_detail_reference';
const ENCRYPTED_DATA = 'encrypted_data';
const SECURITY_CODE = 'cvc';
const NUMBER_OF_INSTALLMENTS = 'number_of_installments';
/**
......@@ -40,7 +40,7 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
*/
protected $additionalInformationList = [
self::RECURRING_DETAIL_REFERENCE,
self::ENCRYPTED_DATA,
self::SECURITY_CODE,
self::NUMBER_OF_INSTALLMENTS
];
......
......@@ -288,7 +288,6 @@
<arguments>
<argument name="commands" xsi:type="array">
<item name="authorize" xsi:type="string">AdyenPaymentCcAuthorizeCommand</item>
<item name="authorize_3d" xsi:type="string">AdyenPaymentAuthorize3DCommand</item>
<item name="capture" xsi:type="string">AdyenPaymentCaptureCommand</item>
<item name="void" xsi:type="string">AdyenPaymentCancelCommand</item>
<item name="refund" xsi:type="string">AdyenPaymentRefundCommand</item>
......@@ -301,7 +300,6 @@
<arguments>
<argument name="commands" xsi:type="array">
<item name="authorize" xsi:type="string">AdyenPaymentOneclickAuthorizeCommand</item>
<item name="authorize_3d" xsi:type="string">AdyenPaymentAuthorize3DCommand</item>
<item name="capture" xsi:type="string">AdyenPaymentCaptureCommand</item>
<item name="void" xsi:type="string">AdyenPaymentCancelCommand</item>
<item name="refund" xsi:type="string">AdyenPaymentRefundCommand</item>
......@@ -392,22 +390,13 @@
<argument name="handler" xsi:type="object">AdyenPaymentCcResponseHandlerComposite</argument>
</arguments>
</virtualType>
<virtualType name="AdyenPaymentAuthorize3DCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<arguments>
<argument name="requestBuilder" xsi:type="object">AdyenPaymentAuthorize3DRequest</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="validator" xsi:type="object">GeneralResponseValidator</argument>
<argument name="handler" xsi:type="object">AdyenPaymentCcResponseHandlerComposite</argument>
</arguments>
</virtualType>
<virtualType name="AdyenPaymentOneclickAuthorizeCommand" type="Magento\Payment\Gateway\Command\GatewayCommand">
<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="validator" xsi:type="object">GeneralResponseValidator</argument>
<argument name="client" xsi:type="object">Adyen\Payment\Gateway\Http\Client\TransactionPayment</argument>
<argument name="validator" xsi:type="object">CheckoutResponseValidator</argument>
<argument name="handler" xsi:type="object">AdyenPaymentCcResponseHandlerComposite</argument>
</arguments>
</virtualType>
......@@ -416,8 +405,8 @@
<arguments>
<argument name="requestBuilder" xsi:type="object">AdyenPaymentSepaAuthorizeRequest</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="validator" xsi:type="object">GeneralResponseValidator</argument>
<argument name="client" xsi:type="object">Adyen\Payment\Gateway\Http\Client\TransactionPayment</argument>
<argument name="validator" xsi:type="object">CheckoutResponseValidator</argument>
<argument name="handler" xsi:type="object">AdyenPaymentSepaResponseHandlerComposite</argument>
</arguments>
</virtualType>
......@@ -489,18 +478,6 @@
</arguments>
</virtualType>
<virtualType name="AdyenPaymentAuthorize3DRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
<argument name="builders" xsi:type="array">
<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item>
<item name="browserinfo" xsi:type="string">Adyen\Payment\Gateway\Request\BrowserInfoDataBuilder</item>
<item name="customerip" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerIpDataBuilder</item>
<item name="3dsecure" xsi:type="string">Adyen\Payment\Gateway\Request\Authorize3DSecureDataBuilder</item>
</argument>
</arguments>
</virtualType>
<virtualType name="AdyenPaymentOneclickAuthorizeRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
<argument name="builders" xsi:type="array">
......
......@@ -112,10 +112,6 @@ echo $code; ?>"
<?php endforeach ?>
</select>
<input type="hidden" id="<?php echo $code ?>_encrypted_form_expiry_generationtime"
value="<?php echo date("c"); ?>" data-encrypted-name="generationtime"/>
</div>
</div>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -62,6 +62,21 @@ 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.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) {
......@@ -159,7 +158,7 @@ define(
/**
* Builds the payment details part of the payment information reqeust
*
* @returns {{method: *, additional_data: {cc_type: *, number: *, cvc, expiryMonth: *, expiryYear: *, holderName: *, generationtime: *, store_cc: *, number_of_installments: *}}}
* @returns {{method: *, additional_data: {cc_type: *, number: *, cvc, expiryMonth: *, expiryYear: *, holderName: *, store_cc: *, number_of_installments: *}}}
*/
getData: function () {
return {
......@@ -171,7 +170,6 @@ define(
'expiryMonth': this.expiryMonth(),
'expiryYear': this.expiryYear(),
'holderName': this.creditCardOwner(),
'generationtime': this.getGenerationTime(),
'store_cc': this.setStoreCc(),
'number_of_installments': this.installment()
}
......@@ -310,6 +308,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;
},
......@@ -319,9 +326,6 @@ define(
getPlaceOrderUrl: function () {
return window.checkoutConfig.payment.iframe.placeOrderUrl[this.getCode()];
},
getGenerationTime: function () {
return window.checkoutConfig.payment.adyenCc.generationTime;
},
canCreateBillingAgreement: function () {
if (customer.isLoggedIn()) {
return window.checkoutConfig.payment.adyenCc.canCreateBillingAgreement;
......
......@@ -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
*/
......@@ -181,32 +153,10 @@ define(
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
// 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 +184,73 @@ 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: *}}}
*/
getData: function () {
var self = this;
return {
"method": self.item.method,
"additional_data": {
"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()
}
};
},
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 +261,35 @@ define(
var validate = $(form).validation() && $(form).validation('isValid');
// if oneclick or recurring is a card do validation on expiration date
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
// if oneclick or recurring is a card check CVC validity
var cid = true;
if (this.hasVerification()) {
var cid = Boolean($(form + ' #' + codeValue + '_cc_cid').valid());
if (this.agreement_data.card) {
// if encrypted cvc is empty the request is not valid
if (this.hasVerification() && 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;
},
hasVerification: function () {
return window.checkoutConfig.payment.adyenOneclick.hasCustomerInteraction;
},
getMessageName: function () {
return 'messages-' + value.reference_id;
......@@ -301,14 +297,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 +351,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;
}
});
}
);
......@@ -172,15 +172,6 @@
<!-- /ko -->
<input type="hidden"
name="payment[generationtime]"
class="input-text"
value=""
data-encrypted-name="generationtime"
data-bind="attr: {id: getCode() + '_generationtime', 'data-container': getCode() + '-generationtime'},
value: getGenerationTime()"
/>
</fieldset>
</form>
......
......@@ -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