Commit c6bdeeec authored by Attila Kiss's avatar Attila Kiss Committed by GitHub

Merge pull request #729 from Adyen/PW-2398

[PW-2398] Implement generic component for alternative payment methods
parents 495edf80 3bb32de1
...@@ -76,12 +76,8 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -76,12 +76,8 @@ class CheckoutDataBuilder implements BuilderInterface
$order->setCanSendNewEmailFlag(false); $order->setCanSendNewEmailFlag(false);
$componentStateData = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::STATE_DATA); $componentStateData = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::STATE_DATA);
$this->adyenHelper->adyenLogger->addAdyenDebug(json_encode($componentStateData));
$requestBody = array_merge($requestBody, $componentStateData); $requestBody = array_merge($requestBody, $componentStateData);
$this->adyenHelper->adyenLogger->addAdyenDebug(json_encode($requestBody));
/*foreach ($componentStateData as $key => $data) {
}*/
if (empty($requestBody['paymentMethod']['type']) && !empty( if (empty($requestBody['paymentMethod']['type']) && !empty(
$payment->getAdditionalInformation( $payment->getAdditionalInformation(
......
<?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\Observer;
use Magento\Framework\DataObject;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface;
abstract class AdyenAbstractDataAssignObserver extends AbstractDataAssignObserver
{
const BRAND_CODE = 'brand_code';
const STATE_DATA = 'state_data';
const BROWSER_INFO = 'browserInfo';
const PAYMENT_METHOD = 'paymentMethod';
const RISK_DATA = 'riskData';
const STORE_PAYMENT_METHOD = 'storePaymentMethod';
const CC_TYPE = 'cc_type';
const NUMBER_OF_INSTALLMENTS = 'number_of_installments';
const COMBO_CARD_TYPE = 'combo_card_type';
/**
* @param DataObject $data
* @return array
*/
protected function getValidatedAdditionalData(DataObject $data)
{
// Get additional data array
$additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
if (!is_array($additionalData)) {
return [];
}
// Get a validated additional data array
$additionalData = $this->getArrayOnlyWithApprovedKeys($additionalData, $this->approvedAdditionalDataKeys);
// json decode state data
$stateData = [];
if (!empty($additionalData[self::STATE_DATA])) {
$stateData = json_decode($additionalData[self::STATE_DATA], true);
}
// Get validated state data array
if (!empty($stateData)) {
$stateData = $this->getArrayOnlyWithApprovedKeys($stateData, $this->approvedStateDataKeys);
}
// Replace state data with the decoded and validated state data
$additionalData[self::STATE_DATA] = $stateData;
return $additionalData;
}
/**
* Returns an array with only the approved keys
*
* @param array $array
* @param array $approvedKeys
* @return array
*/
private function getArrayOnlyWithApprovedKeys($array, $approvedKeys)
{
$result = [];
foreach ($approvedKeys as $approvedKey) {
if (isset($array[$approvedKey])) {
$result[$approvedKey] = $array[$approvedKey];
}
}
return $result;
}
}
...@@ -24,32 +24,19 @@ ...@@ -24,32 +24,19 @@
namespace Adyen\Payment\Observer; namespace Adyen\Payment\Observer;
use Magento\Framework\Event\Observer; use Magento\Framework\Event\Observer;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface; use Magento\Quote\Api\Data\PaymentInterface;
/** /**
* Class DataAssignObserver * Class DataAssignObserver
*/ */
class AdyenCcDataAssignObserver extends AbstractDataAssignObserver class AdyenCcDataAssignObserver extends AdyenAbstractDataAssignObserver
{ {
//TODO do we need these?
const VARIANT = 'variant';
const STATE_DATA = 'state_data';
const STORE_PAYMENT_METHOD = 'storePaymentMethod';
const CC_TYPE = 'cc_type';
const NUMBER_OF_INSTALLMENTS = 'number_of_installments';
const COMBO_CARD_TYPE = 'combo_card_type';
const BROWSER_INFO = 'browserInfo';
const PAYMENT_METHOD = 'paymentMethod';
const RISK_DATA = 'riskData';
/** /**
* Approved root level keys from additional data array * Approved root level keys from additional data array
* *
* @var array * @var array
*/ */
private static $approvedAdditionalDataKeys = [ protected $approvedAdditionalDataKeys = [
self::STATE_DATA, self::STATE_DATA,
self::COMBO_CARD_TYPE, self::COMBO_CARD_TYPE,
self::NUMBER_OF_INSTALLMENTS self::NUMBER_OF_INSTALLMENTS
...@@ -60,7 +47,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver ...@@ -60,7 +47,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
* *
* @var array * @var array
*/ */
private static $approvedStateDataKeys = [ protected $approvedStateDataKeys = [
self::BROWSER_INFO, self::BROWSER_INFO,
self::PAYMENT_METHOD, self::PAYMENT_METHOD,
self::RISK_DATA, self::RISK_DATA,
...@@ -76,28 +63,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver ...@@ -76,28 +63,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
// Get request fields // Get request fields
$data = $this->readDataArgument($observer); $data = $this->readDataArgument($observer);
// Get additional data array $additionalData = $this->getValidatedAdditionalData($data);
$additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
if (!is_array($additionalData)) {
return;
}
// Get a validated additional data array
$additionalData = $this->getArrayOnlyWithApprovedKeys($additionalData, self::$approvedAdditionalDataKeys);
// json decode state data
$stateData = [];
if (!empty($additionalData[self::STATE_DATA])) {
$stateData = json_decode($additionalData[self::STATE_DATA], true);
}
// Get validated state data array
if (!empty($stateData)) {
$stateData = $this->getArrayOnlyWithApprovedKeys($stateData, self::$approvedStateDataKeys);
}
// Replace state data with the decoded and validated state data
$additionalData[self::STATE_DATA] = $stateData;
// Set additional data in the payment // Set additional data in the payment
$paymentInfo = $this->readPaymentModelArgument($observer); $paymentInfo = $this->readPaymentModelArgument($observer);
...@@ -110,24 +76,4 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver ...@@ -110,24 +76,4 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
$paymentInfo->setCcType($additionalData[self::CC_TYPE]); $paymentInfo->setCcType($additionalData[self::CC_TYPE]);
} }
} }
/**
* Returns an array with only the approved keys
*
* @param array $array
* @param array $approvedKeys
* @return array
*/
private function getArrayOnlyWithApprovedKeys($array, $approvedKeys)
{
$result = [];
foreach ($approvedKeys as $approvedKey) {
if (isset($array[$approvedKey])) {
$result[$approvedKey] = $array[$approvedKey];
}
}
return $result;
}
} }
...@@ -23,44 +23,32 @@ ...@@ -23,44 +23,32 @@
namespace Adyen\Payment\Observer; namespace Adyen\Payment\Observer;
use Magento\Framework\Event\Observer; use Magento\Framework\Event\Observer;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface; use Magento\Quote\Api\Data\PaymentInterface;
/** /**
* Class DataAssignObserver * Class DataAssignObserver
*/ */
class AdyenHppDataAssignObserver extends AbstractDataAssignObserver class AdyenHppDataAssignObserver extends AdyenAbstractDataAssignObserver
{ {
const BRAND_CODE = 'brand_code'; /**
const ISSUER_ID = 'issuer_id'; * Approved root level keys from additional data array
const GENDER = 'gender'; *
const DOB = 'dob'; * @var array
const TELEPHONE = 'telephone'; */
const DF_VALUE = 'df_value'; protected $approvedAdditionalDataKeys = [
const SSN = 'ssn'; self::STATE_DATA,
const OWNER_NAME = 'ownerName'; self::BRAND_CODE
const BANK_ACCOUNT_OWNER_NAME = 'bankAccountOwnerName'; ];
const IBAN_NUMBER = 'ibanNumber';
const BANK_ACCOUNT_NUMBER = 'bankAccountNumber';
const BANK_LOCATIONID = 'bankLocationId';
/** /**
* Approved root level keys from the checkout component's state data object
*
* @var array * @var array
*/ */
protected $additionalInformationList = [ protected $approvedStateDataKeys = [
self::BRAND_CODE, self::BROWSER_INFO,
self::ISSUER_ID, self::PAYMENT_METHOD,
self::GENDER, self::RISK_DATA
self::DOB,
self::TELEPHONE,
self::DF_VALUE,
self::SSN,
self::OWNER_NAME,
self::BANK_ACCOUNT_OWNER_NAME,
self::IBAN_NUMBER,
self::BANK_ACCOUNT_NUMBER,
self::BANK_LOCATIONID
]; ];
/** /**
...@@ -69,26 +57,20 @@ class AdyenHppDataAssignObserver extends AbstractDataAssignObserver ...@@ -69,26 +57,20 @@ class AdyenHppDataAssignObserver extends AbstractDataAssignObserver
*/ */
public function execute(Observer $observer) public function execute(Observer $observer)
{ {
// Get request fields
$data = $this->readDataArgument($observer); $data = $this->readDataArgument($observer);
$additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA); $additionalData = $this->getValidatedAdditionalData($data);
if (!is_array($additionalData)) {
return;
}
// Set additional data in the payment
$paymentInfo = $this->readPaymentModelArgument($observer); $paymentInfo = $this->readPaymentModelArgument($observer);
foreach ($additionalData as $key => $data) {
if (isset($additionalData[self::BRAND_CODE])) { $paymentInfo->setAdditionalInformation($key, $data);
$paymentInfo->setCcType($additionalData[self::BRAND_CODE]);
} }
foreach ($this->additionalInformationList as $additionalInformationKey) { // Set BrandCode into CCType
if (isset($additionalData[$additionalInformationKey])) { if (isset($additionalData[self::BRAND_CODE])) {
$paymentInfo->setAdditionalInformation( $paymentInfo->setCcType($additionalData[self::BRAND_CODE]);
$additionalInformationKey,
$additionalData[$additionalInformationKey]
);
}
} }
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
define( define(
[ [
'ko',
'underscore', 'underscore',
'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/quote',
'Magento_Customer/js/model/customer', 'Magento_Customer/js/model/customer',
...@@ -11,9 +12,10 @@ define( ...@@ -11,9 +12,10 @@ define(
'mage/storage', 'mage/storage',
'Adyen_Payment/js/bundle', 'Adyen_Payment/js/bundle',
], ],
function (_, quote, customer, urlBuilder, storage, adyenComponent) { function (ko, _, quote, customer, urlBuilder, storage, adyenComponent) {
'use strict'; 'use strict';
var checkoutComponent = {}; var checkoutComponent = {};
var paymentMethods = ko.observable({})
return { return {
/** /**
* Retrieve the list of available payment methods from the server * Retrieve the list of available payment methods from the server
...@@ -73,10 +75,22 @@ define( ...@@ -73,10 +75,22 @@ define(
originKey: originKey, originKey: originKey,
environment: environment, environment: environment,
paymentMethodsResponse: paymentMethodsResponse, paymentMethodsResponse: paymentMethodsResponse,
consentCheckbox: false,
visibility: {
personalDetails: 'editable',
billingAddress: 'editable',
separateDeliveryAddress: 'hidden',
deliveryAddress: 'hidden'
}
}); });
paymentMethods(paymentMethodsResponse.paymentMethods);
}, },
getCheckoutComponent: function() { getCheckoutComponent: function() {
return checkoutComponent; return checkoutComponent;
},
getPaymentMethodsObservable: function() {
return paymentMethods;
} }
}; };
} }
......
...@@ -26,13 +26,17 @@ define( ...@@ -26,13 +26,17 @@ define(
'uiComponent', 'uiComponent',
'Magento_Checkout/js/model/payment/renderer-list', 'Magento_Checkout/js/model/payment/renderer-list',
'Adyen_Payment/js/model/adyen-payment-service', 'Adyen_Payment/js/model/adyen-payment-service',
'Adyen_Payment/js/model/adyen-configuration' 'Adyen_Payment/js/model/adyen-configuration',
'Magento_Checkout/js/model/quote',
'Magento_Customer/js/model/customer'
], ],
function ( function (
Component, Component,
rendererList, rendererList,
adyenPaymentService, adyenPaymentService,
adyenConfiguration adyenConfiguration,
quote,
customer
) { ) {
'use strict'; 'use strict';
rendererList.push( rendererList.push(
...@@ -67,14 +71,37 @@ define( ...@@ -67,14 +71,37 @@ define(
); );
/** Add view logic here if needed */ /** Add view logic here if needed */
return Component.extend({ return Component.extend({
defaults: {
countryCode: ""
},
initialize: function () { initialize: function () {
var self = this;
this._super(); this._super();
adyenPaymentService.retrieveAvailablePaymentMethods().done(function (response) { if (this.isGooglePayEnabled()) {
var googlepayscript = document.createElement('script');
googlepayscript.src = "https://pay.google.com/gp/p/js/pay.js";
googlepayscript.type = "text/javascript";
document.head.appendChild(googlepayscript);
}
if (customer.isLoggedIn()) {
self.setAdyenPaymentMethods();
}
quote.shippingAddress.subscribe(function() {
if (!!quote.shippingAddress().countryId && self.countryCode !== quote.shippingAddress().countryId) {
self.countryCode = quote.shippingAddress().countryId;
self.setAdyenPaymentMethods();
}
})
},
setAdyenPaymentMethods: function() {
adyenPaymentService.retrieveAvailablePaymentMethods().done(function (response) {
var responseJson = JSON.parse(response); var responseJson = JSON.parse(response);
var paymentMethodsResponse = responseJson.paymentMethodsResponse; var paymentMethodsResponse = responseJson.paymentMethodsResponse;
// TODO check if this is still required or if can be outsourced for the generic component, or checkout can create a ratepay component // TODO check if this is still required or if can be outsourced for the generic component, or checkout can create a ratepay component
/*if (!!window.checkoutConfig.payment.adyenHpp) { /*if (!!window.checkoutConfig.payment.adyenHpp) {
if (JSON.stringify(paymentMethods).indexOf("ratepay") > -1) { if (JSON.stringify(paymentMethods).indexOf("ratepay") > -1) {
...@@ -104,13 +131,6 @@ define( ...@@ -104,13 +131,6 @@ define(
adyenConfiguration.getCheckoutEnvironment() adyenConfiguration.getCheckoutEnvironment()
); );
}) })
if (this.isGooglePayEnabled()) {
var googlepayscript = document.createElement('script');
googlepayscript.src = "https://pay.google.com/gp/p/js/pay.js";
googlepayscript.type = "text/javascript";
document.head.appendChild(googlepayscript);
}
}, },
isGooglePayEnabled: function() { isGooglePayEnabled: function() {
return window.checkoutConfig.payment.adyenGooglePay.active; return window.checkoutConfig.payment.adyenGooglePay.active;
......
...@@ -145,8 +145,6 @@ define( ...@@ -145,8 +145,6 @@ define(
var agreementLabel = storedPayment.name + ', ' + storedPayment.holderName + ', **** ' + storedPayment.lastFour; var agreementLabel = storedPayment.name + ', ' + storedPayment.holderName + ', **** ' + storedPayment.lastFour;
console.log(self.checkoutComponent);
return { return {
'label': agreementLabel, 'label': agreementLabel,
'value': storedPayment.storedPaymentMethodId, 'value': storedPayment.storedPaymentMethodId,
......
...@@ -23,14 +23,14 @@ ...@@ -23,14 +23,14 @@
--> -->
<!-- ko foreach: getAdyenHppPaymentMethods() --> <!-- ko foreach: getAdyenHppPaymentMethods() -->
<div class="payment-method" data-bind="css: {'_active': (value == $parent.isBrandCodeChecked())}"> <div class="payment-method" data-bind="css: {'_active': (brandCode == $parent.isBrandCodeChecked())}">
<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]"
class="radio" class="radio"
data-bind="attr: {'id': value}, value: value, checked: $parent.isBrandCodeChecked, click: $parent.selectPaymentMethodBrandCode"/> data-bind="attr: {'id': 'adyen_' + brandCode}, value: 'adyen_' + brandCode, checked: brandCode == $parent.isBrandCodeChecked, click: $parent.selectPaymentMethodBrandCode"/>
<label data-bind="attr: {'for': value}" class="label"> <label data-bind="attr: {'for': 'adyen_' + brandCode}" class="label">
<!-- ko if: name.icon --> <!-- ko if: name.icon -->
<img data-bind="attr: { <img data-bind="attr: {
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
}"> }">
<!--/ko--> <!--/ko-->
<span data-bind="text: name.title"></span> <span data-bind="text: name"></span>
</label> </label>
</div> </div>
<div class="payment-method-content"> <div class="payment-method-content">
...@@ -51,9 +51,10 @@ ...@@ -51,9 +51,10 @@
<!--/ko--> <!--/ko-->
</div> </div>
<form class="form" data-role="adyen-hpp-form" action="#" method="post" data-bind="mageInit: { 'validation':[]}, attr: {id: 'payment_form_' + $parent.getCode() + '_' + value}"> <form class="form" data-role="adyen-hpp-form" action="#" method="post" data-bind="mageInit: { 'validation':[]}, attr: {id: 'payment_form_' + $parent.getCode() + '_' + brandCode}">
<fieldset class="fieldset" data-bind='attr: {id: "payment_fieldset_" + $parent.getCode() + "_" + value}'> <fieldset class="fieldset" data-bind='attr: {id: "payment_fieldset_" + $parent.getCode() + "_" + brandCode}'>
<div class="adyen-alternative-payment-container"></div> <div data-bind='attr: {id: "adyen-alternative-payment-container-" + brandCode}'
afterRender="renderCheckoutComponent()"></div>
</fieldset> </fieldset>
...@@ -64,7 +65,7 @@ ...@@ -64,7 +65,7 @@
</div> </div>
<div> <div>
<span class="message message-error error hpp-message" data-bind="attr: {id: 'messages-' + value}"></span> <span class="message message-error error hpp-message" data-bind="attr: {id: 'messages-' + brandCode}"></span>
</div> </div>
<div class="actions-toolbar"> <div class="actions-toolbar">
...@@ -73,7 +74,7 @@ ...@@ -73,7 +74,7 @@
type="submit" type="submit"
data-bind=" data-bind="
click: $parent.continueToAdyenBrandCode, click: $parent.continueToAdyenBrandCode,
enable: placeOrderAllowed() && (value == $parent.isBrandCodeChecked()), enable: placeOrderAllowed() && (brandCode == $parent.isBrandCodeChecked()),
css: {disabled: !$parent.isPlaceOrderActionAllowed()}" css: {disabled: !$parent.isPlaceOrderActionAllowed()}"
disabled> disabled>
<span data-bind="text: $t('Place Order')"></span> <span data-bind="text: $t('Place Order')"></span>
......
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