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 ed625243 authored by attilak's avatar attilak

Merge branch 'PW-2212' into feature/generic-component

# Conflicts:
#	Block/Form/Cc.php
#	Gateway/Request/CcAuthorizationDataBuilder.php
#	Gateway/Request/CheckoutDataBuilder.php
#	Gateway/Request/RecurringDataBuilder.php
#	Gateway/Validator/CheckoutResponseValidator.php
#	Helper/PaymentMethods.php
#	Helper/Requests.php
#	Model/AdyenThreeDS2Process.php
#	Model/Ui/AdyenGenericConfigProvider.php
#	Observer/AdyenCcDataAssignObserver.php
#	Observer/AdyenHppDataAssignObserver.php
#	view/frontend/web/js/model/adyen-method-list.js
#	view/frontend/web/js/model/adyen-payment-service.js
#	view/frontend/web/js/view/payment/adyen-methods.js
#	view/frontend/web/js/view/payment/method-renderer/adyen-cc-method.js
#	view/frontend/web/js/view/payment/method-renderer/adyen-hpp-method.js
#	view/frontend/web/js/view/payment/method-renderer/adyen-oneclick-method.js
parents 7ee6f945 c6bdeeec
...@@ -67,14 +67,6 @@ class Cc extends \Magento\Payment\Block\Form\Cc ...@@ -67,14 +67,6 @@ class Cc extends \Magento\Payment\Block\Form\Cc
$this->checkoutSession = $checkoutSession; $this->checkoutSession = $checkoutSession;
} }
/**
* @return string
*/
public function getCheckoutCardComponentJs()
{
return $this->adyenHelper->getCheckoutCardComponentJs($this->checkoutSession->getQuote()->getStore()->getId());
}
/** /**
* @return string * @return string
* @throws \Adyen\AdyenException * @throws \Adyen\AdyenException
......
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2019 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;
use Adyen\Payment\Observer\AdyenCcDataAssignObserver;
class CcAuthorizationDataBuilder implements BuilderInterface
{
/**
* @param array $buildSubject
* @return mixed
*/
public function build(array $buildSubject)
{
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$requestBody = [];
// If ccType is set use this. For bcmc you need bcmc otherwise it will fail
$requestBody['paymentMethod']['type'] = "scheme";
if ($cardNumber = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER)) {
$requestBody['paymentMethod']['encryptedCardNumber'] = $cardNumber;
}
if ($expiryMonth = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH)) {
$requestBody['paymentMethod']['encryptedExpiryMonth'] = $expiryMonth;
}
if ($expiryYear = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR)) {
$requestBody['paymentMethod']['encryptedExpiryYear'] = $expiryYear;
}
if ($holderName = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::HOLDER_NAME)) {
$requestBody['paymentMethod']['holderName'] = $holderName;
}
if ($securityCode = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE)) {
$requestBody['paymentMethod']['encryptedSecurityCode'] = $securityCode;
}
// Remove from additional data
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER);
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH);
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR);
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE);
$payment->unsAdditionalInformation(AdyenCcDataAssignObserver::HOLDER_NAME);
// if installments is set and card type is credit card add it into the request
$numberOfInstallments = $payment->getAdditionalInformation(
AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS
) ?: 0;
$comboCardType = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::COMBO_CARD_TYPE) ?: 'credit';
if ($numberOfInstallments > 0) {
$requestBody['installments']['value'] = $numberOfInstallments;
}
// if card type is debit then change the issuer type and unset the installments field
if ($comboCardType == 'debit') {
if ($selectedDebitBrand = $this->getSelectedDebitBrand($payment->getAdditionalInformation('cc_type'))) {
$requestBody['additionalData']['overwriteBrand'] = true;
$requestBody['selectedBrand'] = $selectedDebitBrand;
$requestBody['paymentMethod']['type'] = $selectedDebitBrand;
}
unset($requestBody['installments']);
}
$request['body'] = $requestBody;
return $request;
}
/**
* @param string $brand
* @return string
*/
private function getSelectedDebitBrand($brand)
{
if ($brand == 'VI') {
return 'electron';
}
if ($brand == 'MC') {
return 'maestro';
}
return null;
}
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
namespace Adyen\Payment\Gateway\Request; namespace Adyen\Payment\Gateway\Request;
use Adyen\Payment\Observer\AdyenCcDataAssignObserver;
use Magento\Payment\Gateway\Request\BuilderInterface; use Magento\Payment\Gateway\Request\BuilderInterface;
use Adyen\Payment\Observer\AdyenHppDataAssignObserver; use Adyen\Payment\Observer\AdyenHppDataAssignObserver;
...@@ -82,14 +83,17 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -82,14 +83,17 @@ class CheckoutDataBuilder implements BuilderInterface
// do not send email // do not send email
$order->setCanSendNewEmailFlag(false); $order->setCanSendNewEmailFlag(false);
$requestBodyPaymentMethod['type'] = $payment->getAdditionalInformation( $componentStateData = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::STATE_DATA);
AdyenHppDataAssignObserver::BRAND_CODE $requestBody = array_merge($requestBody, $componentStateData);
);
// Additional data for payment methods with issuer list if (empty($requestBody['paymentMethod']['type']) && !empty(
if ($payment->getAdditionalInformation(AdyenHppDataAssignObserver::ISSUER_ID)) { $payment->getAdditionalInformation(
$requestBodyPaymentMethod['issuer'] = $payment->getAdditionalInformation( AdyenHppDataAssignObserver::BRAND_CODE
AdyenHppDataAssignObserver::ISSUER_ID )
)) {
$requestBody['paymentMethod']['type'] = $payment->getAdditionalInformation(
AdyenHppDataAssignObserver::BRAND_CODE
); );
} }
...@@ -97,59 +101,24 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -97,59 +101,24 @@ class CheckoutDataBuilder implements BuilderInterface
\Magento\Framework\UrlInterface::URL_TYPE_LINK \Magento\Framework\UrlInterface::URL_TYPE_LINK
) . 'adyen/process/result'; ) . 'adyen/process/result';
// Additional data for ACH // TODO set order payment extra data -> mapping required
if ($payment->getAdditionalInformation("bankAccountNumber")) {
$requestBody['bankAccount']['bankAccountNumber'] = $payment->getAdditionalInformation("bankAccountNumber");
}
if ($payment->getAdditionalInformation("bankLocationId")) {
$requestBody['bankAccount']['bankLocationId'] = $payment->getAdditionalInformation("bankLocationId");
}
if ($payment->getAdditionalInformation("bankAccountOwnerName")) {
$requestBody['bankAccount']['ownerName'] = $payment->getAdditionalInformation("bankAccountOwnerName");
}
// Additional data for open invoice payment
if ($payment->getAdditionalInformation("gender")) { if ($payment->getAdditionalInformation("gender")) {
$order->setCustomerGender( $order->setCustomerGender(
$this->gender->getMagentoGenderFromAdyenGender( \Adyen\Payment\Model\Gender::getMagentoGenderFromAdyenGender(
$payment->getAdditionalInformation("gender") $payment->getAdditionalInformation("gender")
) )
); );
$requestBodyPaymentMethod['personalDetails']['gender'] = $payment->getAdditionalInformation("gender");
} }
if ($payment->getAdditionalInformation("dob")) { if ($payment->getAdditionalInformation("dob")) {
$order->setCustomerDob($payment->getAdditionalInformation("dob")); $order->setCustomerDob($payment->getAdditionalInformation("dob"));
$requestBodyPaymentMethod['personalDetails']['dateOfBirth'] = $this->adyenHelper->formatDate(
$payment->getAdditionalInformation("dob"),
'Y-m-d'
);
} }
if ($payment->getAdditionalInformation("telephone")) { if ($payment->getAdditionalInformation("telephone")) {
$order->getBillingAddress()->setTelephone($payment->getAdditionalInformation("telephone")); $order->getBillingAddress()->setTelephone($payment->getAdditionalInformation("telephone"));
$requestBodyPaymentMethod['personalDetails']['telephoneNumber'] = $payment->getAdditionalInformation(
"telephone"
);
}
if ($payment->getAdditionalInformation("ssn")) {
$requestBodyPaymentMethod['personalDetails']['socialSecurityNumber'] =
$payment->getAdditionalInformation("ssn");
}
// Additional data for sepa direct debit
if ($payment->getAdditionalInformation("ownerName")) {
$requestBodyPaymentMethod['sepa.ownerName'] = $payment->getAdditionalInformation("ownerName");
}
if ($payment->getAdditionalInformation("ibanNumber")) {
$requestBodyPaymentMethod['sepa.ibanNumber'] = $payment->getAdditionalInformation("ibanNumber");
} }
// TODO new function isOpenInvoiceLineItemNeeded
if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod( if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE) $payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
) || $this->adyenHelper->isPaymentMethodAfterpayTouchMethod( ) || $this->adyenHelper->isPaymentMethodAfterpayTouchMethod(
...@@ -163,6 +132,7 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -163,6 +132,7 @@ class CheckoutDataBuilder implements BuilderInterface
} }
// Ratepay specific Fingerprint // Ratepay specific Fingerprint
// TODO check if this is still necessary or if there is a component that can handle this
if ($payment->getAdditionalInformation("df_value") && $this->adyenHelper->isPaymentMethodRatepayMethod( if ($payment->getAdditionalInformation("df_value") && $this->adyenHelper->isPaymentMethodRatepayMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE) $payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
)) { )) {
...@@ -183,16 +153,17 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -183,16 +153,17 @@ class CheckoutDataBuilder implements BuilderInterface
} }
if ($payment->getMethod() == \Adyen\Payment\Model\Ui\AdyenBoletoConfigProvider::CODE) { if ($payment->getMethod() == \Adyen\Payment\Model\Ui\AdyenBoletoConfigProvider::CODE) {
$boletoTypes = $this->adyenHelper->getAdyenBoletoConfigData('boletotypes'); // TODO check if this is coming from the component now
/*$boletoTypes = $this->adyenHelper->getAdyenBoletoConfigData('boletotypes');
$boletoTypes = explode(',', $boletoTypes); $boletoTypes = explode(',', $boletoTypes);
if (count($boletoTypes) == 1) { if (count($boletoTypes) == 1) {
$requestBody['selectedBrand'] = $boletoTypes[0]; $requestBody['selectedBrand'] = $boletoTypes[0];
$requestBodyPaymentMethod['type'] = $boletoTypes[0]; $requestBody['paymentMethod']['type'] = $boletoTypes[0];
} else { } else {
$requestBody['selectedBrand'] = $payment->getAdditionalInformation("boleto_type"); $requestBody['selectedBrand'] = $payment->getAdditionalInformation("boleto_type");
$requestBodyPaymentMethod['type'] = $payment->getAdditionalInformation("boleto_type"); $requestBody['paymentMethod']['type'] = $payment->getAdditionalInformation("boleto_type");
} }*/
$deliveryDays = (int)$this->adyenHelper->getAdyenBoletoConfigData("delivery_days", $storeId); $deliveryDays = (int)$this->adyenHelper->getAdyenBoletoConfigData("delivery_days", $storeId);
$deliveryDays = (!empty($deliveryDays)) ? $deliveryDays : 5; $deliveryDays = (!empty($deliveryDays)) ? $deliveryDays : 5;
...@@ -213,7 +184,23 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -213,7 +184,23 @@ class CheckoutDataBuilder implements BuilderInterface
$order->setCanSendNewEmailFlag(true); $order->setCanSendNewEmailFlag(true);
} }
$requestBody['paymentMethod'] = $requestBodyPaymentMethod; // if installments is set and card type is credit card add it into the request
$numberOfInstallments = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS) ?: 0;
$comboCardType = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::COMBO_CARD_TYPE) ?: 'credit';
if ($numberOfInstallments > 0) {
$requestBody['installments']['value'] = $numberOfInstallments;
}
// if card type is debit then change the issuer type and unset the installments field
if ($comboCardType == 'debit') {
if ($selectedDebitBrand = $this->getSelectedDebitBrand($payment->getAdditionalInformation('cc_type'))) {
$requestBody['additionalData']['overwriteBrand'] = true;
$requestBody['selectedBrand'] = $selectedDebitBrand;
$requestBody['paymentMethod']['type'] = $selectedDebitBrand;
}
unset($requestBody['installments']);
}
$request['body'] = $requestBody; $request['body'] = $requestBody;
return $request; return $request;
...@@ -312,4 +299,19 @@ class CheckoutDataBuilder implements BuilderInterface ...@@ -312,4 +299,19 @@ class CheckoutDataBuilder implements BuilderInterface
return $formFields; return $formFields;
} }
/**
* @param string $brand
* @return string
*/
private function getSelectedDebitBrand($brand)
{
if ($brand == 'VI') {
return 'electron';
}
if ($brand == 'MC') {
return 'maestro';
}
return null;
}
} }
...@@ -63,13 +63,7 @@ class RecurringDataBuilder implements BuilderInterface ...@@ -63,13 +63,7 @@ class RecurringDataBuilder implements BuilderInterface
$payment = $paymentDataObject->getPayment(); $payment = $paymentDataObject->getPayment();
$storeId = $payment->getOrder()->getStoreId(); $storeId = $payment->getOrder()->getStoreId();
$areaCode = $this->appState->getAreaCode(); $areaCode = $this->appState->getAreaCode();
$additionalInformation = $payment->getAdditionalInformation(); $request['body'] = $this->adyenRequestsHelper->buildRecurringData([], $areaCode, $storeId);
$request['body'] = $this->adyenRequestsHelper->buildRecurringData(
$areaCode,
$storeId,
$additionalInformation,
[]
);
return $request; return $request;
} }
} }
...@@ -69,21 +69,9 @@ class CheckoutResponseValidator extends AbstractValidator ...@@ -69,21 +69,9 @@ class CheckoutResponseValidator extends AbstractValidator
// validate result // validate result
if (!empty($response['resultCode'])) { if (!empty($response['resultCode'])) {
switch ($response['resultCode']) { switch ($response['resultCode']) {
case "IdentifyShopper":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
$payment->setAdditionalInformation(
'threeDS2Token',
$response['authentication']['threeds2.fingerprintToken']
);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
break;
case "ChallengeShopper": case "ChallengeShopper":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']); case "IdentifyShopper":
$payment->setAdditionalInformation( $payment->setAdditionalInformation('action', $response['action']);
'threeDS2Token',
$response['authentication']['threeds2.challengeToken']
);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
break; break;
case "Authorised": case "Authorised":
case "Received": case "Received":
......
...@@ -39,11 +39,6 @@ class InstallmentValidator extends AbstractValidator ...@@ -39,11 +39,6 @@ class InstallmentValidator extends AbstractValidator
*/ */
private $adyenHelper; private $adyenHelper;
/**
* @var \Magento\Framework\Serialize\SerializerInterface
*/
private $serializer;
/** /**
* @var \Magento\Quote\Model\QuoteRepository * @var \Magento\Quote\Model\QuoteRepository
*/ */
...@@ -55,19 +50,16 @@ class InstallmentValidator extends AbstractValidator ...@@ -55,19 +50,16 @@ class InstallmentValidator extends AbstractValidator
* @param \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory * @param \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
* @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger * @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger
* @param \Adyen\Payment\Helper\Data $adyenHelper * @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\Serialize\SerializerInterface $serializer
* @param \Magento\Quote\Model\QuoteRepository $quoteRepository * @param \Magento\Quote\Model\QuoteRepository $quoteRepository
*/ */
public function __construct( public function __construct(
\Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory, \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger, \Adyen\Payment\Logger\AdyenLogger $adyenLogger,
\Adyen\Payment\Helper\Data $adyenHelper, \Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Serialize\SerializerInterface $serializer,
\Magento\Quote\Model\QuoteRepository $quoteRepository \Magento\Quote\Model\QuoteRepository $quoteRepository
) { ) {
$this->adyenLogger = $adyenLogger; $this->adyenLogger = $adyenLogger;
$this->adyenHelper = $adyenHelper; $this->adyenHelper = $adyenHelper;
$this->serializer = $serializer;
$this->quoteRepository = $quoteRepository; $this->quoteRepository = $quoteRepository;
parent::__construct($resultFactory); parent::__construct($resultFactory);
} }
...@@ -87,27 +79,14 @@ class InstallmentValidator extends AbstractValidator ...@@ -87,27 +79,14 @@ class InstallmentValidator extends AbstractValidator
$installmentsEnabled = $this->adyenHelper->getAdyenCcConfigData('enable_installments'); $installmentsEnabled = $this->adyenHelper->getAdyenCcConfigData('enable_installments');
if ($quote && $installmentsEnabled) { if ($quote && $installmentsEnabled) {
$grandTotal = $quote->getGrandTotal(); $grandTotal = $quote->getGrandTotal();
$installmentsAvailable = $this->adyenHelper->getAdyenCcConfigData('installments'); $installments = $this->adyenHelper->getAdyenCcConfigData('installments');
$installmentSelected = $payment->getAdditionalInformation('number_of_installments'); $installmentSelected = $payment->getAdditionalInformation('number_of_installments');
$ccType = $payment->getAdditionalInformation('cc_type'); $ccType = $payment->getAdditionalInformation('cc_type');
if ($installmentsAvailable) {
$installments = $this->serializer->unserialize($installmentsAvailable);
}
if ($installmentSelected && $installmentsAvailable) { if ($installmentSelected && $installmentsAvailable) {
$isValid = false; $isValid = false;
$fails[] = __('Installments not valid.'); $fails[] = __('Installments not valid.');
if ($installments) { if ($installments) {
foreach ($installments as $ccTypeInstallment => $installment) { //TODO how implement custom validation of generated installments code against selected value?
if ($ccTypeInstallment == $ccType) {
foreach ($installment as $amount => $installmentsData) {
if ($installmentSelected == $installmentsData) {
if ($grandTotal >= $amount) {
$isValid = true;
}
}
}
}
}
} }
} }
} }
......
...@@ -34,8 +34,6 @@ class Data extends AbstractHelper ...@@ -34,8 +34,6 @@ class Data extends AbstractHelper
const MODULE_NAME = 'adyen-magento2'; const MODULE_NAME = 'adyen-magento2';
const TEST = 'test'; const TEST = 'test';
const LIVE = 'live'; const LIVE = 'live';
const CHECKOUT_COMPONENT_JS_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/3.2.0/adyen.js';
const CHECKOUT_COMPONENT_JS_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/3.2.0/adyen.js';
/** /**
* @var \Magento\Framework\Encryption\EncryptorInterface * @var \Magento\Framework\Encryption\EncryptorInterface
...@@ -1626,19 +1624,6 @@ class Data extends AbstractHelper ...@@ -1626,19 +1624,6 @@ class Data extends AbstractHelper
return new \Adyen\Service\CheckoutUtility($client); 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;
}
/** /**
* @param $order * @param $order
* @param $additionalData * @param $additionalData
...@@ -1827,27 +1812,6 @@ class Data extends AbstractHelper ...@@ -1827,27 +1812,6 @@ class Data extends AbstractHelper
return $timeStamp->format($format); return $timeStamp->format($format);
} }
/**
* @param string|null $type
* @param string|null $token
* @return string
*/
public function buildThreeDS2ProcessResponseJson($type = null, $token = null)
{
$response = ['threeDS2' => false];
if (!empty($type)) {
$response['type'] = $type;
}
if ($type && $token) {
$response['threeDS2'] = true;
$response['token'] = $token;
}
return json_encode($response);
}
/** /**
* @param int $storeId * @param int $storeId
* @return mixed|string * @return mixed|string
......
...@@ -90,6 +90,11 @@ class PaymentMethods extends AbstractHelper ...@@ -90,6 +90,11 @@ class PaymentMethods extends AbstractHelper
*/ */
protected $quote; protected $quote;
/**
* @var \Magento\Checkout\Model\PaymentDetailsFactory
*/
protected $paymentDetailsFactory;
/** /**
* PaymentMethods constructor. * PaymentMethods constructor.
* *
...@@ -104,6 +109,7 @@ class PaymentMethods extends AbstractHelper ...@@ -104,6 +109,7 @@ class PaymentMethods extends AbstractHelper
* @param \Magento\Framework\View\Asset\Source $assetSource * @param \Magento\Framework\View\Asset\Source $assetSource
* @param \Magento\Framework\View\DesignInterface $design * @param \Magento\Framework\View\DesignInterface $design
* @param \Magento\Framework\View\Design\Theme\ThemeProviderInterface $themeProvider * @param \Magento\Framework\View\Design\Theme\ThemeProviderInterface $themeProvider
* @param \Magento\Checkout\Model\PaymentDetailsFactory $paymentDetailsFactory
*/ */
public function __construct( public function __construct(
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository, \Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
...@@ -116,7 +122,8 @@ class PaymentMethods extends AbstractHelper ...@@ -116,7 +122,8 @@ class PaymentMethods extends AbstractHelper
\Magento\Framework\App\RequestInterface $request, \Magento\Framework\App\RequestInterface $request,
\Magento\Framework\View\Asset\Source $assetSource, \Magento\Framework\View\Asset\Source $assetSource,
\Magento\Framework\View\DesignInterface $design, \Magento\Framework\View\DesignInterface $design,
\Magento\Framework\View\Design\Theme\ThemeProviderInterface $themeProvider \Magento\Framework\View\Design\Theme\ThemeProviderInterface $themeProvider,
\Magento\Checkout\Model\PaymentDetailsFactory $paymentDetailsFactory
) { ) {
$this->quoteRepository = $quoteRepository; $this->quoteRepository = $quoteRepository;
$this->config = $config; $this->config = $config;
...@@ -129,6 +136,7 @@ class PaymentMethods extends AbstractHelper ...@@ -129,6 +136,7 @@ class PaymentMethods extends AbstractHelper
$this->assetSource = $assetSource; $this->assetSource = $assetSource;
$this->design = $design; $this->design = $design;
$this->themeProvider = $themeProvider; $this->themeProvider = $themeProvider;
$this->paymentDetailsFactory = $paymentDetailsFactory;
} }
/** /**
...@@ -146,7 +154,7 @@ class PaymentMethods extends AbstractHelper ...@@ -146,7 +154,7 @@ class PaymentMethods extends AbstractHelper
$this->setQuote($quote); $this->setQuote($quote);
$paymentMethods = $this->fetchAlternativeMethods($country); $paymentMethods = $this->fetchPaymentMethods($country);
return $paymentMethods; return $paymentMethods;
} }
...@@ -154,7 +162,7 @@ class PaymentMethods extends AbstractHelper ...@@ -154,7 +162,7 @@ class PaymentMethods extends AbstractHelper
* @param $country * @param $country
* @return array * @return array
*/ */
protected function fetchAlternativeMethods($country) protected function fetchPaymentMethods($country)
{ {
$quote = $this->getQuote(); $quote = $this->getQuote();
$store = $quote->getStore(); $store = $quote->getStore();
...@@ -192,19 +200,17 @@ class PaymentMethods extends AbstractHelper ...@@ -192,19 +200,17 @@ class PaymentMethods extends AbstractHelper
$responseData = $this->getPaymentMethodsResponse($adyFields, $store); $responseData = $this->getPaymentMethodsResponse($adyFields, $store);
$paymentMethods = []; if (empty($responseData['paymentMethods'])) {
if (isset($responseData['paymentMethods'])) { return [];
foreach ($responseData['paymentMethods'] as $paymentMethod) { }
$paymentMethodCode = $paymentMethod['type'];
$paymentMethod = $this->fieldMapPaymentMethod($paymentMethod);
// check if payment method is an openinvoice method $paymentMethods = $responseData['paymentMethods'];
$paymentMethod['isPaymentMethodOpenInvoiceMethod'] = $response['paymentMethodsResponse'] = $responseData;
$this->adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethodCode);
// Add extra details per payment mmethod
$paymentMethodsExtraDetails = [];
// add icon location in result
if ($this->adyenHelper->showLogos()) { if ($this->adyenHelper->showLogos()) {
// Fix for MAGETWO-70402 https://github.com/magento/magento2/pull/7686
// Explicitly setting theme // Explicitly setting theme
$themeCode = "Magento/blank"; $themeCode = "Magento/blank";
...@@ -226,6 +232,10 @@ class PaymentMethods extends AbstractHelper ...@@ -226,6 +232,10 @@ class PaymentMethods extends AbstractHelper
$params $params
); );
foreach ($paymentMethods as $paymentMethod) {
$paymentMethodCode = $paymentMethod['type'];
$asset = $this->assetRepo->createAsset( $asset = $this->assetRepo->createAsset(
'Adyen_Payment::images/logos/' . 'Adyen_Payment::images/logos/' .
$paymentMethodCode . '.png', $paymentMethodCode . '.png',
...@@ -234,7 +244,7 @@ class PaymentMethods extends AbstractHelper ...@@ -234,7 +244,7 @@ class PaymentMethods extends AbstractHelper
$placeholder = $this->assetSource->findSource($asset); $placeholder = $this->assetSource->findSource($asset);
$icon = null; $icon = [];
if ($placeholder) { if ($placeholder) {
list($width, $height) = getimagesize($asset->getSourceFile()); list($width, $height) = getimagesize($asset->getSourceFile());
$icon = [ $icon = [
...@@ -242,14 +252,26 @@ class PaymentMethods extends AbstractHelper ...@@ -242,14 +252,26 @@ class PaymentMethods extends AbstractHelper
'width' => $width, 'width' => $width,
'height' => $height 'height' => $height
]; ];
} else {
$icon = [
'url' => 'https://checkoutshopper-live.adyen.com/checkoutshopper/images/logos/medium/' .$paymentMethodCode . '.png',
'width' => 77,
'height' => 50
];
} }
$paymentMethod['icon'] = $icon;
} $paymentMethodsExtraDetails[$paymentMethodCode]['icon'] = $icon;
$paymentMethods[$paymentMethodCode] = $paymentMethod;
// check if payment method is an openinvoice method
$paymentMethodsExtraDetails[$paymentMethodCode]['isOpenInvoice'] =
$this->adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethodCode);
} }
} }
return $paymentMethods; $response['paymentMethodsExtraDetails'] = $paymentMethodsExtraDetails;
//TODO this should be the implemented with an interface
return json_encode($response);
} }
/** /**
...@@ -306,28 +328,6 @@ class PaymentMethods extends AbstractHelper ...@@ -306,28 +328,6 @@ class PaymentMethods extends AbstractHelper
return ""; return "";
} }
/**
* @var array
*/
protected $fieldMapPaymentMethod = [
'name' => 'title'
];
/**
* @param $paymentMethod
* @return mixed
*/
protected function fieldMapPaymentMethod($paymentMethod)
{
foreach ($this->fieldMapPaymentMethod as $field => $newField) {
if (isset($paymentMethod[$field])) {
$paymentMethod[$newField] = $paymentMethod[$field];
unset($paymentMethod[$field]);
}
}
return $paymentMethod;
}
/** /**
* @param $requestParams * @param $requestParams
* @param $store * @param $store
......
...@@ -315,17 +315,6 @@ class Requests extends AbstractHelper ...@@ -315,17 +315,6 @@ class Requests extends AbstractHelper
$request['additionalData']['allow3DS2'] = true; $request['additionalData']['allow3DS2'] = true;
$request['origin'] = $this->adyenHelper->getOrigin(); $request['origin'] = $this->adyenHelper->getOrigin();
$request['channel'] = 'web'; $request['channel'] = 'web';
$request['browserInfo']['screenWidth'] = $additionalData[AdyenCcDataAssignObserver::SCREEN_WIDTH];
$request['browserInfo']['screenHeight'] = $additionalData[AdyenCcDataAssignObserver::SCREEN_HEIGHT];
$request['browserInfo']['colorDepth'] = $additionalData[AdyenCcDataAssignObserver::SCREEN_COLOR_DEPTH];
$request['browserInfo']['timeZoneOffset'] = $additionalData[AdyenCcDataAssignObserver::TIMEZONE_OFFSET];
$request['browserInfo']['language'] = $additionalData[AdyenCcDataAssignObserver::LANGUAGE];
if ($javaEnabled = $additionalData[AdyenCcDataAssignObserver::JAVA_ENABLED]) {
$request['browserInfo']['javaEnabled'] = $javaEnabled;
} else {
$request['browserInfo']['javaEnabled'] = false;
}
} else { } else {
$request['additionalData']['allow3DS2'] = false; $request['additionalData']['allow3DS2'] = false;
$request['origin'] = $this->adyenHelper->getOrigin(); $request['origin'] = $this->adyenHelper->getOrigin();
...@@ -341,7 +330,7 @@ class Requests extends AbstractHelper ...@@ -341,7 +330,7 @@ class Requests extends AbstractHelper
* @param $storeId * @param $storeId
* @param $payment * @param $payment
*/ */
public function buildRecurringData($areaCode, int $storeId, $additionalData, $request = []) public function buildRecurringData($areaCode, int $storeId, $request = [])
{ {
// If the vault feature is on this logic is handled in the VaultDataBuilder // If the vault feature is on this logic is handled in the VaultDataBuilder
if (!$this->adyenHelper->isCreditCardVaultEnabled()) { if (!$this->adyenHelper->isCreditCardVaultEnabled()) {
...@@ -363,11 +352,6 @@ class Requests extends AbstractHelper ...@@ -363,11 +352,6 @@ class Requests extends AbstractHelper
} else { } else {
$request['enableRecurring'] = false; $request['enableRecurring'] = false;
} }
// value can be 0,1 or true
if (!empty($additionalData[AdyenCcDataAssignObserver::STORE_CC])) {
$request['paymentMethod']['storeDetails'] = true;
}
} }
return $request; return $request;
......
...@@ -75,18 +75,11 @@ class AdyenOrderPaymentStatus implements \Adyen\Payment\Api\AdyenOrderPaymentSta ...@@ -75,18 +75,11 @@ class AdyenOrderPaymentStatus implements \Adyen\Payment\Api\AdyenOrderPaymentSta
) { ) {
$additionalInformation = $payment->getAdditionalInformation(); $additionalInformation = $payment->getAdditionalInformation();
$type = null; if (!empty($additionalInformation['action'])) {
if (!empty($additionalInformation['threeDSType'])) { return json_encode($additionalInformation['action']);
$type = $additionalInformation['threeDSType'];
} }
$token = null;
if (!empty($additionalInformation['threeDS2Token'])) {
$token = $additionalInformation['threeDS2Token'];
} }
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($type, $token);
}
return true; return true;
} }
} }
...@@ -75,6 +75,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface ...@@ -75,6 +75,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
public function initiate($payload) public function initiate($payload)
{ {
// Decode payload from frontend // Decode payload from frontend
// TODO implement interface to handle the request the correct way
$payload = json_decode($payload, true); $payload = json_decode($payload, true);
// Validate JSON that has just been parsed if it was in a valid format // Validate JSON that has just been parsed if it was in a valid format
...@@ -84,6 +85,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface ...@@ -84,6 +85,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
); );
} }
// Validate if order id is present
if (empty($payload['orderId'])) { if (empty($payload['orderId'])) {
$order = $this->getOrder(); $order = $this->getOrder();
// In the next major release remove support for retrieving order from session and throw exception instead // In the next major release remove support for retrieving order from session and throw exception instead
...@@ -96,30 +98,16 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface ...@@ -96,30 +98,16 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
$payment = $order->getPayment(); $payment = $order->getPayment();
// Init payments/details request
$result = [];
if ($paymentData = $payment->getAdditionalInformation("threeDS2PaymentData")) {
// Add payment data into the request object
$request = [
"paymentData" => $payment->getAdditionalInformation("threeDS2PaymentData")
];
// unset payment data from additional information // Unset action from additional info since it is not needed anymore
$payment->unsAdditionalInformation("threeDS2PaymentData"); $payment->unsAdditionalInformation("action");
} else {
$this->adyenLogger->error("3D secure 2.0 failed, payment data not found");
throw new \Magento\Framework\Exception\LocalizedException(
__('3D secure 2.0 failed, payment data not found')
);
}
// Depends on the component's response we send a fingerprint or the challenge result // TODO validate and format the request root level keys
if (!empty($payload['details']['threeds2.fingerprint'])) { $request = $payload;
$request['details']['threeds2.fingerprint'] = $payload['details']['threeds2.fingerprint'];
} elseif (!empty($payload['details']['threeds2.challengeResult'])) { // Init payments/details request
$request['details']['threeds2.challengeResult'] = $payload['details']['threeds2.challengeResult']; $result = [];
}
// Send the request // Send the request
try { try {
...@@ -135,12 +123,9 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface ...@@ -135,12 +123,9 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
// Check if result is challenge shopper, if yes return the token // Check if result is challenge shopper, if yes return the token
if (!empty($result['resultCode']) && if (!empty($result['resultCode']) &&
$result['resultCode'] === 'ChallengeShopper' && $result['resultCode'] === 'ChallengeShopper' &&
!empty($result['authentication']['threeds2.challengeToken']) !empty($result['action'])
) { ) {
return $this->adyenHelper->buildThreeDS2ProcessResponseJson( return json_encode($result['action']);
$result['resultCode'],
$result['authentication']['threeds2.challengeToken']
);
} }
// Save the payments response because we are going to need it during the place order flow // Save the payments response because we are going to need it during the place order flow
......
...@@ -59,6 +59,8 @@ class GuestAdyenPaymentMethodManagement implements \Adyen\Payment\Api\GuestAdyen ...@@ -59,6 +59,8 @@ class GuestAdyenPaymentMethodManagement implements \Adyen\Payment\Api\GuestAdyen
// if shippingAddress is provided use this country // if shippingAddress is provided use this country
$country = null; $country = null;
// TODO check why the frontend doesn't have the shipping address
// or get it from the cart
if ($shippingAddress) { if ($shippingAddress) {
$country = $shippingAddress->getCountryId(); $country = $shippingAddress->getCountryId();
} }
......
...@@ -67,11 +67,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -67,11 +67,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
*/ */
private $storeManager; private $storeManager;
/**
* @var \Magento\Framework\Serialize\SerializerInterface
*/
private $serializer;
/** /**
* AdyenCcConfigProvider constructor. * AdyenCcConfigProvider constructor.
* *
...@@ -82,7 +77,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -82,7 +77,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
* @param \Magento\Framework\View\Asset\Source $assetSource * @param \Magento\Framework\View\Asset\Source $assetSource
* @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Payment\Model\CcConfig $ccConfig * @param \Magento\Payment\Model\CcConfig $ccConfig
* @param \Magento\Framework\Serialize\SerializerInterface $serializer
*/ */
public function __construct( public function __construct(
\Magento\Payment\Helper\Data $paymentHelper, \Magento\Payment\Helper\Data $paymentHelper,
...@@ -91,8 +85,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -91,8 +85,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
\Magento\Framework\UrlInterface $urlBuilder, \Magento\Framework\UrlInterface $urlBuilder,
\Magento\Framework\View\Asset\Source $assetSource, \Magento\Framework\View\Asset\Source $assetSource,
\Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Payment\Model\CcConfig $ccConfig, \Magento\Payment\Model\CcConfig $ccConfig
\Magento\Framework\Serialize\SerializerInterface $serializer
) { ) {
$this->_paymentHelper = $paymentHelper; $this->_paymentHelper = $paymentHelper;
$this->_adyenHelper = $adyenHelper; $this->_adyenHelper = $adyenHelper;
...@@ -101,7 +94,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -101,7 +94,6 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
$this->_assetSource = $assetSource; $this->_assetSource = $assetSource;
$this->ccConfig = $ccConfig; $this->ccConfig = $ccConfig;
$this->storeManager = $storeManager; $this->storeManager = $storeManager;
$this->serializer = $serializer;
} }
/** /**
...@@ -170,7 +162,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface ...@@ -170,7 +162,7 @@ class AdyenCcConfigProvider implements ConfigProviderInterface
$installments = $this->_adyenHelper->getAdyenCcConfigData('installments'); $installments = $this->_adyenHelper->getAdyenCcConfigData('installments');
if ($installmentsEnabled && $installments) { if ($installmentsEnabled && $installments) {
$config['payment']['adyenCc']['installments'] = $this->serializer->unserialize($installments); $config['payment']['adyenCc']['installments'] = $installments;
$config['payment']['adyenCc']['hasInstallments'] = true; $config['payment']['adyenCc']['hasInstallments'] = true;
} else { } else {
$config['payment']['adyenCc']['installments'] = []; $config['payment']['adyenCc']['installments'] = [];
......
...@@ -69,10 +69,6 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface ...@@ -69,10 +69,6 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
$config['payment']['adyen']['showLogo'] = false; $config['payment']['adyen']['showLogo'] = false;
} }
$config['payment']['checkoutCardComponentSource'] = $this->_adyenHelper->getCheckoutCardComponentJs(
$this->storeManager->getStore()->getId()
);
return $config; return $config;
} }
......
<?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,50 +24,31 @@ ...@@ -24,50 +24,31 @@
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 AdyenCcDataAssignObserver extends AbstractDataAssignObserver class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
{ {
const CC_TYPE = 'cc_type'; /**
const NUMBER_OF_INSTALLMENTS = 'number_of_installments'; * Approved root level keys from additional data array
const STORE_CC = 'store_cc'; *
const ENCRYPTED_CREDIT_CARD_NUMBER = 'number'; * @var array
const ENCRYPTED_SECURITY_CODE = 'cvc'; */
const ENCRYPTED_EXPIRY_MONTH = 'expiryMonth'; protected $approvedAdditionalDataKeys = [
const ENCRYPTED_EXPIRY_YEAR = 'expiryYear'; self::STATE_DATA,
const HOLDER_NAME = 'holderName'; self::COMBO_CARD_TYPE,
const VARIANT = 'variant'; self::NUMBER_OF_INSTALLMENTS
const JAVA_ENABLED = 'java_enabled'; ];
const SCREEN_COLOR_DEPTH = 'screen_color_depth';
const SCREEN_WIDTH = 'screen_width';
const SCREEN_HEIGHT = 'screen_height';
const TIMEZONE_OFFSET = 'timezone_offset';
const LANGUAGE = 'language';
const GUEST_EMAIL = 'guestEmail';
const COMBO_CARD_TYPE = 'combo_card_type';
/** /**
* Approved root level keys from the checkout component's state data object
*
* @var array * @var array
*/ */
protected $additionalInformationList = [ protected $approvedStateDataKeys = [
self::CC_TYPE, self::BROWSER_INFO,
self::NUMBER_OF_INSTALLMENTS, self::PAYMENT_METHOD,
self::STORE_CC, self::RISK_DATA,
self::ENCRYPTED_CREDIT_CARD_NUMBER, self::STORE_PAYMENT_METHOD
self::ENCRYPTED_SECURITY_CODE,
self::ENCRYPTED_EXPIRY_MONTH,
self::ENCRYPTED_EXPIRY_YEAR,
self::HOLDER_NAME,
self::VARIANT,
self::JAVA_ENABLED,
self::SCREEN_COLOR_DEPTH,
self::SCREEN_WIDTH,
self::SCREEN_HEIGHT,
self::TIMEZONE_OFFSET,
self::LANGUAGE,
self::GUEST_EMAIL,
self::COMBO_CARD_TYPE
]; ];
/** /**
...@@ -76,27 +57,20 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver ...@@ -76,27 +57,20 @@ class AdyenCcDataAssignObserver 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) {
// set ccType $paymentInfo->setAdditionalInformation($key, $data);
if (!empty($additionalData['cc_type'])) {
$paymentInfo->setCcType($additionalData['cc_type']);
} }
foreach ($this->additionalInformationList as $additionalInformationKey) { // set ccType
if (isset($additionalData[$additionalInformationKey])) { if (!empty($additionalData[self::CC_TYPE])) {
$paymentInfo->setAdditionalInformation( $paymentInfo->setCcType($additionalData[self::CC_TYPE]);
$additionalInformationKey,
$additionalData[$additionalInformationKey]
);
}
} }
} }
} }
...@@ -24,40 +24,29 @@ ...@@ -24,40 +24,29 @@
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 AdyenHppDataAssignObserver extends AbstractDataAssignObserver class AdyenHppDataAssignObserver extends AbstractDataAssignObserver
{ {
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
]; ];
/** /**
...@@ -66,26 +55,20 @@ class AdyenHppDataAssignObserver extends AbstractDataAssignObserver ...@@ -66,26 +55,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) {
$paymentInfo->setAdditionalInformation($key, $data);
}
// Set BrandCode into CCType
if (isset($additionalData[self::BRAND_CODE])) { if (isset($additionalData[self::BRAND_CODE])) {
$paymentInfo->setCcType($additionalData[self::BRAND_CODE]); $paymentInfo->setCcType($additionalData[self::BRAND_CODE]);
} }
foreach ($this->additionalInformationList as $additionalInformationKey) {
if (isset($additionalData[$additionalInformationKey])) {
$paymentInfo->setAdditionalInformation(
$additionalInformationKey,
$additionalData[$additionalInformationKey]
);
}
}
} }
} }
...@@ -77,20 +77,17 @@ ...@@ -77,20 +77,17 @@
<tooltip>Enable installments for each credit card type.</tooltip> <tooltip>Enable installments for each credit card type.</tooltip>
<config_path>payment/adyen_cc/enable_installments</config_path> <config_path>payment/adyen_cc/enable_installments</config_path>
</field> </field>
<field id="installments" translate="label" sortOrder="220" showInDefault="1" showInWebsite="1" <field id="installments" type="textarea" translate="label" sortOrder="220" showInDefault="1"
showInStore="1"> showInWebsite="1" showInStore="1">
<label>Installments</label> <label>Installments</label>
<depends> <depends>
<field id="enable_installments">1</field> <field id="enable_installments">1</field>
</depends> </depends>
<tooltip>Configure your installment for each credit card type: Insert the minimum amount required to <validate>required-entry</validate>
make the configured installment available in the amount range column. <comment><![CDATA[
Example: if the amount range is configured to 100 and the number of installments to 4x, the shopper Generate the desired installments configuration <a href="">here</a> and paste it on this field.
will see the 4x option only if the payment total is higher or equal than 100. ]]></comment>
</tooltip> <config_path>payment/adyen_cc/installments_code</config_path>
<frontend_model>Adyen\Payment\Block\Adminhtml\System\Config\Field\Installments</frontend_model>
<backend_model>Adyen\Payment\Model\Config\Backend\Installments</backend_model>
<config_path>payment/adyen_cc/installments</config_path>
</field> </field>
</group> </group>
......
...@@ -557,7 +557,7 @@ ...@@ -557,7 +557,7 @@
<item name="payment" xsi:type="string">Adyen\Payment\Gateway\Request\PaymentDataBuilder</item> <item name="payment" xsi:type="string">Adyen\Payment\Gateway\Request\PaymentDataBuilder</item>
<item name="browserinfo" xsi:type="string">Adyen\Payment\Gateway\Request\BrowserInfoDataBuilder</item> <item name="browserinfo" xsi:type="string">Adyen\Payment\Gateway\Request\BrowserInfoDataBuilder</item>
<item name="recurring" xsi:type="string">Adyen\Payment\Gateway\Request\RecurringDataBuilder</item> <item name="recurring" xsi:type="string">Adyen\Payment\Gateway\Request\RecurringDataBuilder</item>
<item name="transaction" xsi:type="string">Adyen\Payment\Gateway\Request\CcAuthorizationDataBuilder</item> <item name="transaction" xsi:type="string">Adyen\Payment\Gateway\Request\CheckoutDataBuilder</item>
<item name="vault" xsi:type="string">Adyen\Payment\Gateway\Request\VaultDataBuilder</item> <item name="vault" xsi:type="string">Adyen\Payment\Gateway\Request\VaultDataBuilder</item>
<item name="threeds2" xsi:type="string">Adyen\Payment\Gateway\Request\ThreeDS2DataBuilder</item> <item name="threeds2" xsi:type="string">Adyen\Payment\Gateway\Request\ThreeDS2DataBuilder</item>
</argument> </argument>
...@@ -990,11 +990,6 @@ ...@@ -990,11 +990,6 @@
<argument name="serializer" xsi:type="object">Magento\Framework\Serialize\Serializer\Serialize</argument> <argument name="serializer" xsi:type="object">Magento\Framework\Serialize\Serializer\Serialize</argument>
</arguments> </arguments>
</type> </type>
<type name="Adyen\Payment\Gateway\Validator\InstallmentValidator">
<arguments>
<argument name="serializer" xsi:type="object">Magento\Framework\Serialize\Serializer\Serialize</argument>
</arguments>
</type>
<type name="Adyen\Payment\Model\Ui\AdyenPosCloudConfigProvider"> <type name="Adyen\Payment\Model\Ui\AdyenPosCloudConfigProvider">
<arguments> <arguments>
<argument name="serializer" xsi:type="object">Magento\Framework\Serialize\Serializer\Serialize</argument> <argument name="serializer" xsi:type="object">Magento\Framework\Serialize\Serializer\Serialize</argument>
......
This diff is collapsed.
This diff is collapsed.
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* 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>
*/
define(
[
],
function () {
'use strict';
return {
getOriginKey: function () {
return window.checkoutConfig.payment.adyenCc.originKey;
},
showLogo: function () {
return window.checkoutConfig.payment.adyen.showLogo;
},
getLocale: function () {
return window.checkoutConfig.payment.adyenCc.locale;
},
getCheckoutEnvironment: function () {
return window.checkoutConfig.payment.adyenCc.checkoutEnvironment;
},
};
}
);
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
define(
[
'ko'
],
function (ko) {
'use strict';
return ko.observableArray([]);
}
);
...@@ -4,37 +4,23 @@ ...@@ -4,37 +4,23 @@
*/ */
define( define(
[ [
'ko',
'underscore', 'underscore',
'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/quote',
'Adyen_Payment/js/model/adyen-method-list',
'Magento_Customer/js/model/customer', 'Magento_Customer/js/model/customer',
'Magento_Checkout/js/model/url-builder', 'Magento_Checkout/js/model/url-builder',
'mage/storage' 'mage/storage',
'Adyen_Payment/js/bundle',
], ],
function (_, quote, methodList, customer, urlBuilder, storage) { function (ko, _, quote, customer, urlBuilder, storage, adyenComponent) {
'use strict'; 'use strict';
var checkoutComponent = {};
var paymentMethods = ko.observable({})
return { return {
/**
* Populate the list of payment methods
* @param {Array} methods
*/
setPaymentMethods: function (methods) {
methodList(methods);
},
/**
* Get the list of available payment methods.
* @returns {Array}
*/
getAvailablePaymentMethods: function () {
return methodList();
},
/** /**
* Retrieve the list of available payment methods from the server * Retrieve the list of available payment methods from the server
*/ */
retrieveAvailablePaymentMethods: function (callback) { retrieveAvailablePaymentMethods: function () {
var self = this;
// retrieve payment methods // retrieve payment methods
var serviceUrl, var serviceUrl,
payload; payload;
...@@ -51,28 +37,60 @@ define( ...@@ -51,28 +37,60 @@ define(
shippingAddress: quote.shippingAddress() shippingAddress: quote.shippingAddress()
}; };
storage.post( return storage.post(
serviceUrl, serviceUrl,
JSON.stringify(payload) JSON.stringify(payload),
).done( true
function (response) {
self.setPaymentMethods(response);
if (callback) {
callback();
}
}
).fail(
function () {
self.setPaymentMethods([]);
}
) )
}, },
/**
* The results that the 3DS2 components returns in the onComplete callback needs to be sent to the
* backend to the /adyen/threeDS2Process endpoint and based on the response render a new threeDS2
* component or place the order (validateThreeDS2OrPlaceOrder)
* @param response
*/
processThreeDS2: function (data) {
var payload = {
"payload": JSON.stringify(data)
};
var serviceUrl = urlBuilder.createUrl('/adyen/threeDS2Process', {});
return storage.post(
serviceUrl,
JSON.stringify(payload),
true
);
},
getOrderPaymentStatus: function (orderId) { getOrderPaymentStatus: function (orderId) {
var serviceUrl = urlBuilder.createUrl('/adyen/orders/:orderId/payment-status', { var serviceUrl = urlBuilder.createUrl('/adyen/orders/:orderId/payment-status', {
orderId: orderId orderId: orderId
}); });
return storage.get(serviceUrl); return storage.get(serviceUrl);
},
initCheckoutComponent: function(paymentMethodsResponse, originKey, locale, environment, ) {
checkoutComponent = new AdyenCheckout({
locale: locale,
originKey: originKey,
environment: environment,
paymentMethodsResponse: paymentMethodsResponse,
consentCheckbox: false,
visibility: {
personalDetails: 'editable',
billingAddress: 'editable',
separateDeliveryAddress: 'hidden',
deliveryAddress: 'hidden'
}
});
paymentMethods(paymentMethodsResponse.paymentMethods);
},
getCheckoutComponent: function() {
return checkoutComponent;
},
getPaymentMethodsObservable: function() {
return paymentMethods;
} }
}; };
} }
......
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
define(
[
'ko',
'jquery',
],
function (ko, $) {
'use strict';
return {
/**
*
* @param installments
* @param grandTotal
* @param precision
* @param currencyCode
* @returns {Array}
*/
getInstallmentsWithPrices: function (installments, grandTotal, precision, currencyCode) {
let numberOfInstallments = [];
let dividedAmount = 0;
let dividedString = "";
$.each(installments, function (amount, installment) {
if (grandTotal >= amount) {
dividedAmount = (grandTotal / installment).toFixed(precision);
dividedString = installment + " x " + dividedAmount + " " + currencyCode;
numberOfInstallments.push({
key: [dividedString],
value: installment
});
}
});
return numberOfInstallments;
}
};
}
);
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
define(
[
'Magento_Checkout/js/model/url-builder',
'mage/storage'
],
function (urlBuilder, storage) {
'use strict';
return {
/**
* The results that the 3DS2 components returns in the onComplete callback needs to be sent to the
* backend to the /adyen/threeDS2Process endpoint and based on the response render a new threeDS2
* component or place the order (validateThreeDS2OrPlaceOrder)
* @param response
*/
processThreeDS2: function (data) {
var payload = {
"payload": JSON.stringify(data)
};
var serviceUrl = urlBuilder.createUrl('/adyen/threeDS2Process', {});
return storage.post(
serviceUrl,
JSON.stringify(payload),
true
);
}
};
}
);
...@@ -24,11 +24,19 @@ ...@@ -24,11 +24,19 @@
define( 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-configuration',
'Magento_Checkout/js/model/quote',
'Magento_Customer/js/model/customer'
], ],
function ( function (
Component, Component,
rendererList rendererList,
adyenPaymentService,
adyenConfiguration,
quote,
customer
) { ) {
'use strict'; 'use strict';
rendererList.push( rendererList.push(
...@@ -63,16 +71,13 @@ define( ...@@ -63,16 +71,13 @@ 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; var self = this;
this._super();
// include checkout card component javascript this._super();
var checkoutCardComponentScriptTag = document.createElement('script');
checkoutCardComponentScriptTag.id = "AdyenCheckoutCardComponentScript";
checkoutCardComponentScriptTag.src = self.getCheckoutCardComponentSource();
checkoutCardComponentScriptTag.type = "text/javascript";
document.head.appendChild(checkoutCardComponentScriptTag);
if (this.isGooglePayEnabled()) { if (this.isGooglePayEnabled()) {
var googlepayscript = document.createElement('script'); var googlepayscript = document.createElement('script');
...@@ -80,12 +85,58 @@ define( ...@@ -80,12 +85,58 @@ define(
googlepayscript.type = "text/javascript"; googlepayscript.type = "text/javascript";
document.head.appendChild(googlepayscript); 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();
}
})
}, },
getCheckoutCardComponentSource: function () { setAdyenPaymentMethods: function() {
return window.checkoutConfig.payment.checkoutCardComponentSource; adyenPaymentService.retrieveAvailablePaymentMethods().done(function (response) {
var responseJson = JSON.parse(response);
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
/*if (!!window.checkoutConfig.payment.adyenHpp) {
if (JSON.stringify(paymentMethods).indexOf("ratepay") > -1) {
var ratePayId = window.checkoutConfig.payment.adyenHpp.ratePayId;
var dfValueRatePay = self.getRatePayDeviceIdentToken();
window.di = {
t: dfValueRatePay.replace(':', ''),
v: ratePayId,
l: 'Checkout'
};
// Load Ratepay script
var ratepayScriptTag = document.createElement('script');
ratepayScriptTag.src = "//d.ratepay.com/" + ratePayId + "/di.js";
ratepayScriptTag.type = "text/javascript";
document.body.appendChild(ratepayScriptTag);
}
}*/
// Initialises adyen checkout main component with default configuration
adyenPaymentService.initCheckoutComponent(
paymentMethodsResponse,
adyenConfiguration.getOriginKey(),
adyenConfiguration.getLocale(),
adyenConfiguration.getCheckoutEnvironment()
);
})
}, },
isGooglePayEnabled: function () { isGooglePayEnabled: function () {
return window.checkoutConfig.payment.adyenGooglePay.active; return window.checkoutConfig.payment.adyenGooglePay.active;
},
getRatePayDeviceIdentToken: function () {
return window.checkoutConfig.payment.adyenHpp.deviceIdentToken;
} }
}); });
} }
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
<!-- /ko --> <!-- /ko -->
<div class="field number cardContainerField"> <div class="field number cardContainerField">
<div class="checkout-component-dock" afterRender="renderSecureFields()" data-bind="attr: { id: 'cardContainer'}"></div> <div class="checkout-component-dock" afterRender="renderCardComponent()" data-bind="attr: { id: 'cardContainer'}"></div>
</div> </div>
<div id="threeDS2Wrapper"> <div id="threeDS2Wrapper">
...@@ -101,34 +101,6 @@ ...@@ -101,34 +101,6 @@
</div> </div>
</div> </div>
<!-- ko if: (hasInstallments())-->
<div class="field required"
data-bind="attr: {id: getCode() + '_installments_div'}, visible: installments().length > 0">
<label data-bind="attr: {for: getCode() + '_installments'}" class="label">
<span><!-- ko text: $t('Installments')--><!-- /ko --></span>
</label>
<div class="control">
<select class="select"
name="payment[number_of_installments]"
data-bind="attr: {id: getCode() + '_installments', 'data-container': getCode() + '-installments', 'data-validate': JSON.stringify({required:false})},
enable: isActive($parents),
options: installments,
optionsValue: 'value',
optionsText: 'key',
optionsCaption: $t('Do not use Installments'),
value: installment"
data-validate="{required:true}">
</select>
</div>
</div>
<!-- /ko -->
<!-- ko if: (isVaultEnabled())--> <!-- ko if: (isVaultEnabled())-->
<div class="field choice"> <div class="field choice">
<input type="checkbox" <input type="checkbox"
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* Author: Adyen <magento@adyen.com> * Author: Adyen <magento@adyen.com>
*/ */
--> -->
<!-- ko foreach: getAdyenBillingAgreements() --> <!-- ko foreach: getAdyenStoredPayments() -->
<div class="payment-method" data-bind="css: {'_active': (value == $parent.isBillingAgreementChecked())}"> <div class="payment-method" data-bind="css: {'_active': (value == $parent.isBillingAgreementChecked())}">
<div class="payment-method-title field choice"> <div class="payment-method-title field choice">
<input type="radio" <input type="radio"
...@@ -46,7 +46,8 @@ ...@@ -46,7 +46,8 @@
<div class="payment-method-content"> <div class="payment-method-content">
<!-- ko ifnot: (getOriginKey()) --> <!-- ko ifnot: (getOriginKey()) -->
<span class="message message-error error"><!-- ko text: $t('Please configure an API Key and a live endpoint prefix(if in Production Mode) in your Adyen Required Settings')--><!-- /ko --></span> <span class="message message-error error"><!-- ko text: $t('Please configure an API Key and a live endpoint prefix(if in Production Mode) in your Adyen Required Settings')-->
<!-- /ko --></span>
<!--/ko--> <!--/ko-->
<!-- ko foreach: $parent.getRegion(getMessageName()) --> <!-- ko foreach: $parent.getRegion(getMessageName()) -->
...@@ -71,70 +72,10 @@ ...@@ -71,70 +72,10 @@
<fieldset <fieldset
data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + $parent.getCode() + '_' + value}"> data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + $parent.getCode() + '_' + value}">
<!-- ko if: agreement_data.card --> <div class="checkout-component-dock" afterRender="renderStoredPaymentComponent()"
<div class="field number"> data-bind="attr: { id: 'storedPaymentContainer-' + value}"></div>
<label class="label">
<span><!-- ko text: $t('Credit Card Number')--><!-- /ko --></span>
</label>
<div class="control">
<span data-bind="text: '**** **** **** ' + agreement_data.card.number"></span>
</div>
</div>
<div class="checkout-component-dock" afterRender="renderSecureCVC()" data-bind="attr: { id: 'cvcContainer-' + value}"></div>
<!--/ko--> <!--/ko-->
<!-- ko if: agreement_data.bank -->
<div class="field number">
<label class="label">
<span><!-- ko text: $t('Bank account holder name')--><!-- /ko --></span>
</label>
<div class="control">
<span data-bind="text: agreement_data.bank.ownerName"></span>
</div>
</div>
<div class="field number">
<label class="label">
<span><!-- ko text: $t('Iban')--><!-- /ko --></span>
</label>
<div class="control">
<span data-bind="text: agreement_data.bank.iban"></span>
</div>
</div>
<div class="field number">
<label class="label">
<span><!-- ko text: $t('Country')--><!-- /ko --></span>
</label>
<div class="control">
<span data-bind="text: agreement_data.bank.countryCode"></span>
</div>
</div>
<!--/ko-->
<!-- ko if: number_of_installments.length > 0 -->
<div class="field required"
data-bind="attr: {id: getCode() + '_installments_div'}, visible: getInstallments().length > 0">
<label data-bind="attr: {for: getCode() + '_installments'}" class="label">
<span><!-- ko text: $t('Installments')--><!-- /ko --></span>
</label>
<div class="control">
<select class="select"
name="payment[number_of_installments]"
data-bind="attr: {id: getCode() + '_installments', 'data-container': getCode() + '-installments', 'data-validate': JSON.stringify({required:false})},
enable: $parent.isActive($parents),
options: getInstallments,
optionsValue: 'value',
optionsText: 'key',
optionsCaption: $t('Do not use Installments'),
value: installment"
data-validate="{required:true}">
</select>
</div>
</div>
<!-- /ko -->
<div id="threeDS2ModalOneClick"> <div id="threeDS2ModalOneClick">
<div id="threeDS2ContainerOneClick"></div> <div id="threeDS2ContainerOneClick"></div>
</div> </div>
......
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