Commit 11633b90 authored by cyattilakiss's avatar cyattilakiss Committed by GitHub

Merge pull request #698 from Adyen/attila/PW-2212

Card payments finalised
parents c3dae75f 8cfb5272
......@@ -67,14 +67,6 @@ class Cc extends \Magento\Payment\Block\Form\Cc
$this->checkoutSession = $checkoutSession;
}
/**
* @return string
*/
public function getCheckoutCardComponentJs()
{
return $this->adyenHelper->getCheckoutCardComponentJs($this->checkoutSession->getQuote()->getStore()->getId());
}
/**
* @return string
* @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;
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -64,8 +64,7 @@ class RecurringDataBuilder implements BuilderInterface
$payment = $paymentDataObject->getPayment();
$storeId = $payment->getOrder()->getStoreId();
$areaCode = $this->appState->getAreaCode();
$additionalInformation = $payment->getAdditionalInformation();
$request['body'] = $this->adyenRequestsHelper->buildRecurringData([], $areaCode, $storeId, $additionalInformation);
$request['body'] = $this->adyenRequestsHelper->buildRecurringData([], $areaCode, $storeId);
return $request;
}
}
......@@ -69,15 +69,9 @@ class CheckoutResponseValidator extends AbstractValidator
// validate result
if (!empty($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":
$payment->setAdditionalInformation('threeDSType', $response['resultCode']);
$payment->setAdditionalInformation('threeDS2Token', $response['authentication']['threeds2.challengeToken']);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
case "IdentifyShopper":
$payment->setAdditionalInformation('action', $response['action']);
break;
case "Authorised":
case "Received":
......
......@@ -34,8 +34,6 @@ class Data extends AbstractHelper
const MODULE_NAME = 'adyen-magento2';
const TEST = 'test';
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
......@@ -1603,19 +1601,6 @@ 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;
}
/**
* @param $order
* @param $additionalData
......@@ -1807,27 +1792,6 @@ class Data extends AbstractHelper
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
* @return mixed|string
......
......@@ -50,10 +50,10 @@ class PaymentMethods extends AbstractHelper
*/
protected $session;
/**
* @var \Magento\Framework\Locale\ResolverInterface
*/
protected $localeResolver;
/**
* @var \Magento\Framework\Locale\ResolverInterface
*/
protected $localeResolver;
/**
* @var \Adyen\Payment\Logger\AdyenLogger
......@@ -116,7 +116,7 @@ class PaymentMethods extends AbstractHelper
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Checkout\Model\Session $session,
\Magento\Framework\Locale\ResolverInterface $localeResolver,
\Magento\Framework\Locale\ResolverInterface $localeResolver,
\Adyen\Payment\Logger\AdyenLogger $adyenLogger,
\Magento\Framework\View\Asset\Repository $assetRepo,
\Magento\Framework\App\RequestInterface $request,
......@@ -129,7 +129,7 @@ class PaymentMethods extends AbstractHelper
$this->config = $config;
$this->adyenHelper = $adyenHelper;
$this->session = $session;
$this->localeResolver = $localeResolver;
$this->localeResolver = $localeResolver;
$this->adyenLogger = $adyenLogger;
$this->assetRepo = $assetRepo;
$this->request = $request;
......@@ -154,7 +154,7 @@ class PaymentMethods extends AbstractHelper
$this->setQuote($quote);
$paymentMethods = $this->fetchAlternativeMethods($country);
$paymentMethods = $this->fetchPaymentMethods($country);
return $paymentMethods;
}
......@@ -162,7 +162,7 @@ class PaymentMethods extends AbstractHelper
* @param $country
* @return array
*/
protected function fetchAlternativeMethods($country)
protected function fetchPaymentMethods($country)
{
$quote = $this->getQuote();
$store = $quote->getStore();
......@@ -200,70 +200,78 @@ class PaymentMethods extends AbstractHelper
$responseData = $this->getPaymentMethodsResponse($adyFields, $store);
// TODO this should be the implemented with the PaymentDetailsInterface but for now we json encode it and
// on the fronend we decode it so we can move forward
// /** @var \Magento\Checkout\Api\Data\PaymentDetailsInterface $paymentDetails */
// $paymentDetails = $this->paymentDetailsFactory->create();
// $paymentDetails->setPaymentMethods($responseData);
//$paymentDetails->setTotals($this->cartTotalsRepository->get($cartId));
//return $paymentDetails;
return json_encode($responseData);
if (empty($responseData['paymentMethods'])) {
return [];
}
$paymentMethods = $responseData['paymentMethods'];
$response['paymentMethodsResponse'] = $responseData;
// Add extra details per payment mmethod
$paymentMethodsExtraDetails = [];
if ($this->adyenHelper->showLogos()) {
// Explicitly setting theme
$themeCode = "Magento/blank";
$themeId = $this->design->getConfigurationDesignTheme(\Magento\Framework\App\Area::AREA_FRONTEND);
if (!empty($themeId)) {
$theme = $this->themeProvider->getThemeById($themeId);
if ($theme && !empty($theme->getCode())) {
$themeCode = $theme->getCode();
}
}
$params = [];
$params = array_merge(
[
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'_secure' => $this->request->isSecure(),
'theme' => $themeCode
],
$params
);
$paymentMethods = [];
if (isset($responseData['paymentMethods'])) {
foreach ($responseData['paymentMethods'] as $paymentMethod) {
foreach ($paymentMethods as $paymentMethod) {
$paymentMethodCode = $paymentMethod['type'];
$paymentMethod = $this->fieldMapPaymentMethod($paymentMethod);
// check if payment method is an openinvoice method
//$paymentMethod['isPaymentMethodOpenInvoiceMethod'] =
//$this->adyenHelper->isPaymentMethodOpenInvoiceMethod($paymentMethodCode);
//TODO create the icons on the frontend or in a separate function but not here!
// add icon location in result
if ($this->adyenHelper->showLogos()) {
// Fix for MAGETWO-70402 https://github.com/magento/magento2/pull/7686
// Explicitly setting theme
$themeCode = "Magento/blank";
$themeId = $this->design->getConfigurationDesignTheme(\Magento\Framework\App\Area::AREA_FRONTEND);
if (!empty($themeId)) {
$theme = $this->themeProvider->getThemeById($themeId);
if ($theme && !empty($theme->getCode())) {
$themeCode = $theme->getCode();
}
}
$params = [];
$params = array_merge([
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'_secure' => $this->request->isSecure(),
'theme' => $themeCode
], $params);
$asset = $this->assetRepo->createAsset('Adyen_Payment::images/logos/' .
$paymentMethodCode . '.png', $params);
$placeholder = $this->assetSource->findSource($asset);
$icon = null;
if ($placeholder) {
list($width, $height) = getimagesize($asset->getSourceFile());
$icon = [
'url' => $asset->getUrl(),
'width' => $width,
'height' => $height
];
}
$paymentMethod['icon'] = $icon;
$asset = $this->assetRepo->createAsset(
'Adyen_Payment::images/logos/' .
$paymentMethodCode . '.png',
$params
);
$placeholder = $this->assetSource->findSource($asset);
$icon = [];
if ($placeholder) {
list($width, $height) = getimagesize($asset->getSourceFile());
$icon = [
'url' => $asset->getUrl(),
'width' => $width,
'height' => $height
];
} else {
$icon = [
'url' => 'https://checkoutshopper-live.adyen.com/checkoutshopper/images/logos/medium/' .$paymentMethodCode . '.png',
'width' => 77,
'height' => 50
];
}
$paymentMethods[$paymentMethodCode] = $paymentMethod;
$paymentMethodsExtraDetails[$paymentMethodCode]['icon'] = $icon;
// 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);
}
/**
......@@ -321,28 +329,6 @@ class PaymentMethods extends AbstractHelper
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 $store
......@@ -351,7 +337,6 @@ class PaymentMethods extends AbstractHelper
*/
protected function getPaymentMethodsResponse($requestParams, $store)
{
// initialize the adyen client
$client = $this->adyenHelper->initializeAdyenClient($store->getId());
......@@ -401,7 +386,6 @@ class PaymentMethods extends AbstractHelper
*/
public function getConnectedTerminals()
{
$storeId = $this->getQuote()->getStoreId();
// initialize the adyen client
......
......@@ -311,17 +311,6 @@ class Requests extends AbstractHelper
$request['additionalData']['allow3DS2'] = true;
$request['origin'] = $this->adyenHelper->getOrigin();
$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 {
$request['additionalData']['allow3DS2'] = false;
$request['origin'] = $this->adyenHelper->getOrigin();
......@@ -337,7 +326,7 @@ class Requests extends AbstractHelper
* @param $storeId
* @param $payment
*/
public function buildRecurringData($request = [], $areaCode, int $storeId, $additionalData)
public function buildRecurringData($request = [], $areaCode, int $storeId)
{
// If the vault feature is on this logic is handled in the VaultDataBuilder
if (!$this->adyenHelper->isCreditCardVaultEnabled()) {
......@@ -360,11 +349,6 @@ class Requests extends AbstractHelper
} else {
$request['enableRecurring'] = false;
}
// value can be 0,1 or true
if (!empty($additionalData[AdyenCcDataAssignObserver::STORE_CC])) {
$request['paymentMethod']['storeDetails'] = true;
}
}
return $request;
......
......@@ -75,18 +75,11 @@ class AdyenOrderPaymentStatus implements \Adyen\Payment\Api\AdyenOrderPaymentSta
) {
$additionalInformation = $payment->getAdditionalInformation();
$type = null;
if (!empty($additionalInformation['threeDSType'])) {
$type = $additionalInformation['threeDSType'];
if (!empty($additionalInformation['action'])) {
return json_encode($additionalInformation['action']);
}
$token = null;
if (!empty($additionalInformation['threeDS2Token'])) {
$token = $additionalInformation['threeDS2Token'];
}
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($type, $token);
}
return true;
}
}
......@@ -76,6 +76,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
public function initiate($payload)
{
// Decode payload from frontend
// TODO implement interface to handle the request the correct way
$payload = json_decode($payload, true);
// Validate JSON that has just been parsed if it was in a valid format
......@@ -83,6 +84,7 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed because the request was not a valid JSON'));
}
// Validate if order id is present
if (empty($payload['orderId'])) {
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed because of a missing order id'));
}
......@@ -91,28 +93,16 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
$order = $this->orderFactory->create()->load($payload['orderId']);
$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
$payment->unsAdditionalInformation("threeDS2PaymentData");
} 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
if (!empty($payload['details']['threeds2.fingerprint'])) {
$request['details']['threeds2.fingerprint'] = $payload['details']['threeds2.fingerprint'];
} elseif (!empty($payload['details']['threeds2.challengeResult'])) {
$request['details']['threeds2.challengeResult'] = $payload['details']['threeds2.challengeResult'];
}
// Unset action from additional info since it is not needed anymore
$payment->unsAdditionalInformation("action");
// TODO validate and format the request root level keys
$request = $payload;
// Init payments/details request
$result = [];
// Send the request
try {
......@@ -128,9 +118,9 @@ class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
// Check if result is challenge shopper, if yes return the token
if (!empty($result['resultCode']) &&
$result['resultCode'] === 'ChallengeShopper' &&
!empty($result['authentication']['threeds2.challengeToken'])
!empty($result['action'])
) {
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($result['resultCode'], $result['authentication']['threeds2.challengeToken']);
return json_encode($result['action']);
}
// Save the payments response because we are going to need it during the place order flow
......
......@@ -69,8 +69,6 @@ class AdyenGenericConfigProvider implements ConfigProviderInterface
$config['payment']['adyen']['showLogo'] = false;
}
$config['payment']['checkoutCardComponentSource'] = $this->_adyenHelper->getCheckoutCardComponentJs($this->storeManager->getStore()->getId());
return $config;
}
......
......@@ -20,6 +20,7 @@
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Observer;
use Magento\Framework\Event\Observer;
......@@ -31,45 +32,39 @@ use Magento\Quote\Api\Data\PaymentInterface;
*/
class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
{
//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 STORE_CC = 'store_cc';
const ENCRYPTED_CREDIT_CARD_NUMBER = 'number';
const ENCRYPTED_SECURITY_CODE = 'cvc';
const ENCRYPTED_EXPIRY_MONTH = 'expiryMonth';
const ENCRYPTED_EXPIRY_YEAR = 'expiryYear';
const HOLDER_NAME = 'holderName';
const VARIANT = 'variant';
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';
const BROWSER_INFO = 'browserInfo';
const PAYMENT_METHOD = 'paymentMethod';
const RISK_DATA = 'riskData';
/**
* Approved root level keys from additional data array
*
* @var array
*/
protected $additionalInformationList = [
self::CC_TYPE,
self::NUMBER_OF_INSTALLMENTS,
self::STORE_CC,
self::ENCRYPTED_CREDIT_CARD_NUMBER,
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
private static $approvedAdditionalDataKeys = [
self::STATE_DATA,
self::COMBO_CARD_TYPE,
self::NUMBER_OF_INSTALLMENTS
];
/**
* Approved root level keys from the checkout component's state data object
*
* @var array
*/
private static $approvedStateDataKeys = [
self::BROWSER_INFO,
self::PAYMENT_METHOD,
self::RISK_DATA,
self::STORE_PAYMENT_METHOD
];
/**
......@@ -78,27 +73,61 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
*/
public function execute(Observer $observer)
{
// Get request fields
$data = $this->readDataArgument($observer);
// 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, 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
$paymentInfo = $this->readPaymentModelArgument($observer);
foreach ($additionalData as $key => $data) {
$paymentInfo->setAdditionalInformation($key, $data);
}
// set ccType
if (!empty($additionalData['cc_type'])) {
$paymentInfo->setCcType($additionalData['cc_type']);
if (!empty($additionalData[self::CC_TYPE])) {
$paymentInfo->setCcType($additionalData[self::CC_TYPE]);
}
}
foreach ($this->additionalInformationList as $additionalInformationKey) {
if (isset($additionalData[$additionalInformationKey])) {
$paymentInfo->setAdditionalInformation(
$additionalInformationKey,
$additionalData[$additionalInformationKey]
);
/**
* 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;
}
}
......@@ -557,7 +557,7 @@
<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="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="threeds2" xsi:type="string">Adyen\Payment\Gateway\Request\ThreeDS2DataBuilder</item>
</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([]);
}
);
......@@ -6,35 +6,19 @@ define(
[
'underscore',
'Magento_Checkout/js/model/quote',
'Adyen_Payment/js/model/adyen-method-list',
'Magento_Customer/js/model/customer',
'Magento_Checkout/js/model/url-builder',
'mage/storage'
'mage/storage',
'Adyen_Payment/js/bundle',
],
function (_, quote, methodList, customer, urlBuilder, storage) {
function (_, quote, customer, urlBuilder, storage, adyenComponent) {
'use strict';
var checkoutComponent = {};
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
*/
retrieveAvailablePaymentMethods: function (callback) {
var self = this;
retrieveAvailablePaymentMethods: function () {
// retrieve payment methods
var serviceUrl,
payload;
......@@ -51,30 +35,48 @@ define(
shippingAddress: quote.shippingAddress()
};
storage.post(
serviceUrl, JSON.stringify(payload)
).done(
function (response) {
var jsonResponse = JSON.parse(response);
console.log(jsonResponse);
self.setPaymentMethods(jsonResponse);
if (callback) {
callback();
}
}
).fail(
function () {
self.setPaymentMethods([]);
}
return storage.post(
serviceUrl,
JSON.stringify(payload),
true
)
},
/**
* 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) {
var serviceUrl = urlBuilder.createUrl('/adyen/orders/:orderId/payment-status', {
orderId: orderId
});
return storage.get(serviceUrl);
},
initCheckoutComponent: function(paymentMethodsResponse, originKey, locale, environment, ) {
checkoutComponent = new AdyenCheckout({
locale: locale,
originKey: originKey,
environment: environment,
paymentMethodsResponse: paymentMethodsResponse,
});
},
getCheckoutComponent: function() {
return checkoutComponent;
}
};
}
......
/**
* 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
);
}
};
}
);
......@@ -25,12 +25,14 @@ define(
[
'uiComponent',
'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'
],
function (
Component,
rendererList,
adyenPaymentService
adyenPaymentService,
adyenConfiguration
) {
'use strict';
rendererList.push(
......@@ -66,41 +68,42 @@ define(
/** Add view logic here if needed */
return Component.extend({
initialize: function () {
var self = this;
this._super();
// reset variable:
adyenPaymentService.setPaymentMethods();
adyenPaymentService.retrieveAvailablePaymentMethods().done(function (response) {
adyenPaymentService.retrieveAvailablePaymentMethods(function () {
var paymentMethods = adyenPaymentService.getAvailablePaymentMethods();
console.log(paymentMethods);
if (!!window.checkoutConfig.payment.adyenHpp) {
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'
};
var ratePayId = window.checkoutConfig.payment.adyenHpp.ratePayId;
var dfValueRatePay = self.getRatePayDeviceIdentToken();
// Load Ratepay script
var ratepayScriptTag = document.createElement('script');
ratepayScriptTag.src = "//d.ratepay.com/" + ratePayId + "/di.js";
ratepayScriptTag.type = "text/javascript";
document.body.appendChild(ratepayScriptTag);
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);
}
}
});
}*/
// include checkout card component javascript
var checkoutCardComponentScriptTag = document.createElement('script');
checkoutCardComponentScriptTag.id = "AdyenCheckoutCardComponentScript";
checkoutCardComponentScriptTag.src = self.getCheckoutCardComponentSource();
checkoutCardComponentScriptTag.type = "text/javascript";
document.head.appendChild(checkoutCardComponentScriptTag);
// Initialises adyen checkout main component with default configuration
adyenPaymentService.initCheckoutComponent(
paymentMethodsResponse,
adyenConfiguration.getOriginKey(),
adyenConfiguration.getLocale(),
adyenConfiguration.getCheckoutEnvironment()
);
})
if (this.isGooglePayEnabled()) {
var googlepayscript = document.createElement('script');
......@@ -109,15 +112,12 @@ define(
document.head.appendChild(googlepayscript);
}
},
getCheckoutCardComponentSource: function() {
return window.checkoutConfig.payment.checkoutCardComponentSource;
},
isGooglePayEnabled: function() {
return window.checkoutConfig.payment.adyenGooglePay.active;
},
getRatePayDeviceIdentToken: function () {
return window.checkoutConfig.payment.adyenHpp.deviceIdentToken;
},
}
});
}
);
......@@ -92,7 +92,7 @@
<!-- /ko -->
<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 id="threeDS2Wrapper">
......@@ -101,34 +101,6 @@
</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())-->
<div class="field choice">
<input type="checkbox"
......
......@@ -21,7 +21,7 @@
* 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-title field choice">
<input type="radio"
......@@ -46,7 +46,8 @@
<div class="payment-method-content">
<!-- 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 foreach: $parent.getRegion(getMessageName()) -->
......@@ -69,72 +70,12 @@
}, 'validation':[]}">
<fieldset
data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + $parent.getCode() + '_' + value}">
<!-- ko if: agreement_data.card -->
<div class="field number">
<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 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>
data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + $parent.getCode() + '_' + value}">
<div class="checkout-component-dock" afterRender="renderStoredPaymentComponent()"
data-bind="attr: { id: 'storedPaymentContainer-' + value}"></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="threeDS2ContainerOneClick"></div>
</div>
......@@ -161,4 +102,4 @@
</div>
</div>
</div>
<!--/ko-->
\ No newline at end of file
<!--/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