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 6f6a2efe authored by cyattilakiss's avatar cyattilakiss Committed by GitHub

Merge pull request #452 from Adyen/develop

Release 4.2.0
parents 5b8e6426 296f8de9
......@@ -15,32 +15,20 @@
*
* Adyen Payment Module
*
* Copyright (c) 2018 Adyen B.V.
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Model;
namespace Adyen\Payment\Api;
class AdyenPaymentInformationManagement extends \Magento\Checkout\Model\PaymentInformationManagement
interface AdyenPaymentProcessInterface
{
/**
* {@inheritDoc}
* @param string $payload
* @return string
*/
public function savePaymentInformationAndPlaceOrder(
$cartId,
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
) {
$this->savePaymentInformation($cartId, $paymentMethod, $billingAddress);
try {
$orderId = $this->cartManagement->placeOrder($cartId);
} catch (\Exception $e) {
throw $e;
}
return $orderId;
}
public function initiate($payload);
}
<?php
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Payment Module
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
* Author: Adyen <magento@adyen.com>
*/
namespace Adyen\Payment\Api;
interface AdyenThreeDS2ProcessInterface
{
/**
* @param string $payload
* @return string
*/
public function initiate($payload);
}
......@@ -112,29 +112,6 @@ class Redirect extends \Magento\Payment\Block\Form
$this->_request = $context->getRequest();
}
/**
* Returns if the payment should follow the old HPP or the new Checkout flow
* - hpp will submit a form with all the additional information that the API requests\
* - checkout will redirect to a url without form submission
*
* @return bool
* @throws \Exception
*/
public function isCheckoutAPM() {
try {
if ($paymentObject = $this->_order->getPayment()) {
if ($paymentObject->getAdditionalInformation('CheckoutAPM')) {
return true;
}
}
} catch (Exception $e) {
// do nothing for now
throw($e);
}
return false;
}
/**
* @return mixed|string[]
* @throws AdyenException
......
......@@ -87,7 +87,7 @@ class Result extends \Magento\Framework\App\Action\Action
$this->_orderHistoryFactory = $orderHistoryFactory;
$this->_session = $session;
$this->_adyenLogger = $adyenLogger;
$this->storeManager = $storeManager;
$this->storeManager = $storeManager;
parent::__construct($context);
}
......@@ -306,10 +306,10 @@ class Result extends \Magento\Framework\App\Action\Action
$merchantSigNotification = $response['merchantSig'];
// do it like this because $_GET is converting dot to underscore
$queryString = $_SERVER['QUERY_STRING'];
$result = [];
$pairs = explode("&", $queryString);
// do it like this because $_GET is converting dot to underscore
$queryString = $_SERVER['QUERY_STRING'];
$result = [];
$pairs = explode("&", $queryString);
foreach ($pairs as $pair) {
$nv = explode("=", $pair);
......@@ -318,12 +318,12 @@ class Result extends \Magento\Framework\App\Action\Action
$result[$name] = $value;
}
// do not include the merchantSig in the merchantSig calculation
unset($result['merchantSig']);
// do not include the merchantSig in the merchantSig calculation
unset($result['merchantSig']);
// Sign request using secret key
$hmacKey = $this->_adyenHelper->getHmac();
$merchantSig = \Adyen\Util\Util::calculateSha256Signature($hmacKey, $result);
// Sign request using secret key
$hmacKey = $this->_adyenHelper->getHmac();
$merchantSig = \Adyen\Util\Util::calculateSha256Signature($hmacKey, $result);
if (strcmp($merchantSig, $merchantSigNotification) === 0) {
return true;
......
......@@ -55,6 +55,13 @@ class TransactionPayment implements ClientInterface
public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject)
{
$request = $transferObject->getBody();
// If the payments call is already done return the request
if (!empty($request['resultCode'])) {
//Initiate has already a response
return $request;
}
$client = $this->adyenHelper->initializeAdyenClient();
$service = new \Adyen\Service\Checkout($client);
......
......@@ -31,22 +31,22 @@ use Magento\Payment\Gateway\Request\BuilderInterface;
class AddressDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenHelper;
private $adyenRequestsHelper;
/**
* AddressDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper
\Adyen\Payment\Helper\Requests $adyenRequestsHelper
)
{
$this->adyenHelper = $adyenHelper;
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
/**
* Add delivery\billing details into request
*
......@@ -59,76 +59,8 @@ class AddressDataBuilder implements BuilderInterface
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$order = $paymentDataObject->getOrder();
$billingAddress = $order->getBillingAddress();
$result = [];
if ($billingAddress) {
$requestBilling = [
"street" => "N/A",
"postalCode" => '',
"city" => "N/A",
"houseNumberOrName" => '',
"stateOrProvince" => '',
"country" => "ZZ"
];
$address = $this->adyenHelper->getStreetFromString($billingAddress->getStreetLine1());
if ($address) {
$requestBilling["street"] = $address["name"];
$requestBilling["houseNumberOrName"] = $address["house_number"];
}
if ($billingAddress->getPostcode()) {
$requestBilling["postalCode"] = $billingAddress->getPostcode();
}
if ($billingAddress->getCity()) {
$requestBilling["city"] = $billingAddress->getCity();
}
if ($billingAddress->getRegionCode()) {
$requestBilling["stateOrProvince"] = $billingAddress->getRegionCode();
}
if ($billingAddress->getCountryId()) {
$requestBilling["country"] = $billingAddress->getCountryId();
}
$result['billingAddress'] = $requestBilling;
}
$shippingAddress = $order->getShippingAddress();
if ($shippingAddress) {
$address = $this->adyenHelper->getStreetFromString($shippingAddress->getStreetLine1());
if ($address) {
$requestDelivery["street"] = $address["name"];
$requestDelivery["houseNumberOrName"] = $address["house_number"];
}
if ($shippingAddress->getPostcode()) {
$requestDelivery["postalCode"] = $shippingAddress->getPostcode();
}
if ($shippingAddress->getCity()) {
$requestDelivery["city"] = $shippingAddress->getCity();
}
if ($shippingAddress->getRegionCode()) {
$requestDelivery["stateOrProvince"] = $shippingAddress->getRegionCode();
}
if ($shippingAddress->getCountryId()) {
$requestDelivery["country"] = $shippingAddress->getCountryId();
}
$result['deliveryAddress'] = $requestDelivery;
}
return $result;
return $this->adyenRequestsHelper->buildAddressData([], $billingAddress, $shippingAddress);
}
}
......@@ -29,18 +29,29 @@ use Magento\Payment\Gateway\Request\BuilderInterface;
*/
class BrowserInfoDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenRequestsHelper;
/**
* BrowserInfoDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
public function __construct(
\Adyen\Payment\Helper\Requests $adyenRequestsHelper
)
{
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
/**
* @param array $buildSubject
* @return array
*/
public function build(array $buildSubject)
{
return [
'browserInfo' =>
[
'userAgent' => $_SERVER['HTTP_USER_AGENT'],
'acceptHeader' => $_SERVER['HTTP_ACCEPT']
]
];
return $this->adyenRequestsHelper->buildBrowserData();
}
}
......@@ -102,7 +102,7 @@ class CaptureDataBuilder implements BuilderInterface
// The latest invoice will contain only the selected items(and quantities) for the (partial) capture
$latestInvoice = $invoices->getLastItem();
foreach ($latestInvoice->getItemsCollection() as $invoiceItem) {
foreach ($latestInvoice->getItems() as $invoiceItem) {
++$count;
$numberOfItems = (int)$invoiceItem->getQty();
$formFields = $this->adyenHelper->createOpenInvoiceLineItem(
......@@ -113,7 +113,7 @@ class CaptureDataBuilder implements BuilderInterface
$currency,
$invoiceItem->getTaxAmount(),
$invoiceItem->getPriceInclTax(),
$invoiceItem->getTaxPercent(),
$invoiceItem->getOrderItem()->getTaxPercent(),
$numberOfItems,
$payment,
$invoiceItem->getId()
......
......@@ -24,91 +24,30 @@
namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface;
use Adyen\Payment\Observer\AdyenCcDataAssignObserver;
class CcAuthorizationDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* @var \Magento\Framework\App\State
*/
private $appState;
/**
* CcAuthorizationDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\Model\Context $context
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context
) {
$this->adyenHelper = $adyenHelper;
$this->appState = $context->getAppState();
}
/**
* @param array $buildSubject
* @return mixed
* @return array|mixed
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function build(array $buildSubject)
{
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$order = $paymentDataObject->getOrder();
$storeId = $order->getStoreId();
$request = [];
// If ccType is set use this. For bcmc you need bcmc otherwise it will fail
$request['paymentMethod']['type'] = "scheme";
if ($cardNumber = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER)) {
$request['paymentMethod']['encryptedCardNumber'] = $cardNumber;
}
if ($expiryMonth = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH)) {
$request['paymentMethod']['encryptedExpiryMonth'] = $expiryMonth;
}
if ($expiryYear = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR)) {
$request['paymentMethod']['encryptedExpiryYear'] = $expiryYear;
}
if ($holderName = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::HOLDER_NAME)) {
$request['paymentMethod']['holderName'] = $holderName;
}
if ($securityCode = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE)) {
$request['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 MOTO for backend is enabled use MOTO as shopper interaction type
*/
$enableMoto = $this->adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $storeId);
if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE &&
$enableMoto
) {
$request['shopperInteraction'] = "Moto";
}
// if installments is set add it into the request
if ($payment->getAdditionalInformation(AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS) &&
$payment->getAdditionalInformation(AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS) > 0
) {
$request['installments']['value'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS);
// retrieve payments response which we already got and saved in the payment controller
if ($response = $payment->getAdditionalInformation("paymentsResponse")) {
// the payments response needs to be passed to the next process because after this point we don't have
// access to the payment object therefore to the additionalInformation array
$request = $response;
// Remove from additional data
$payment->unsAdditionalInformation("paymentsResponse");
} else {
$errorMsg = __('Error with payment method please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
return $request;
......
<?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 CcBackendAuthorizationDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* @var \Magento\Framework\App\State
*/
private $appState;
/**
* CcAuthorizationDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\Model\Context $context
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context
) {
$this->adyenHelper = $adyenHelper;
$this->appState = $context->getAppState();
}
/**
* @param array $buildSubject
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function build(array $buildSubject)
{
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$order = $paymentDataObject->getOrder();
$storeId = $order->getStoreId();
$request = [];
// If ccType is set use this. For bcmc you need bcmc otherwise it will fail
$request['paymentMethod']['type'] = 'scheme';
if ($cardNumber = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_CREDIT_CARD_NUMBER)) {
$request['paymentMethod']['encryptedCardNumber'] = $cardNumber;
}
if ($expiryMonth = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_MONTH)) {
$request['paymentMethod']['encryptedExpiryMonth'] = $expiryMonth;
}
if ($expiryYear = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_EXPIRY_YEAR)) {
$request['paymentMethod']['encryptedExpiryYear'] = $expiryYear;
}
if ($holderName = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::HOLDER_NAME)) {
$request['paymentMethod']['holderName'] = $holderName;
}
if ($securityCode = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::ENCRYPTED_SECURITY_CODE)) {
$request['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 MOTO for backend is enabled use MOTO as shopper interaction type
*/
$enableMoto = $this->adyenHelper->getAdyenCcConfigDataFlag('enable_moto', $storeId);
if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE &&
$enableMoto
) {
$request['shopperInteraction'] = "Moto";
}
// if installments is set add it into the request
if ($payment->getAdditionalInformation(AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS) &&
$payment->getAdditionalInformation(AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS) > 0
) {
$request['installments']['value'] = $payment->getAdditionalInformation(AdyenCcDataAssignObserver::NUMBER_OF_INSTALLMENTS);
}
return $request;
}
}
......@@ -148,8 +148,8 @@ class CheckoutDataBuilder implements BuilderInterface
if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
) || $this->adyenHelper->isPaymentMethodAfterpayTouchMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
) || $this->adyenHelper->isPaymentMethodOneyMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
) || $this->adyenHelper->isPaymentMethodOneyMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
)
) {
......@@ -219,15 +219,15 @@ class CheckoutDataBuilder implements BuilderInterface
foreach ($this->quote->getAllVisibleItems() as $item) {
$numberOfItems = (int)$item->getQtyOrdered();
$numberOfItems = (int)$item->getQty();
// Summarize the discount amount item by item
$discountAmount += $item->getDiscountAmount();
$priceExcludingTax = $item->getPriceInclTax() - $item->getTaxAmount();
$formattedPriceExcludingTax = $this->adyenHelper->formatAmount($priceExcludingTax, $currency);
$formattedPriceExcludingTax = $this->adyenHelper->formatAmount($item->getPrice(), $currency);
$formattedTaxAmount = $this->adyenHelper->formatAmount($item->getTaxAmount(), $currency);
$taxAmount = $item->getPrice() * ($item->getTaxPercent() / 100);
$formattedTaxAmount = $this->adyenHelper->formatAmount($taxAmount, $currency);
$formattedTaxPercentage = $item->getTaxPercent() * 100;
$formFields['lineItems'][] = [
......@@ -236,7 +236,7 @@ class CheckoutDataBuilder implements BuilderInterface
'amountExcludingTax' => $formattedPriceExcludingTax,
'taxAmount' => $formattedTaxAmount,
'description' => $item->getName(),
'quantity' => $item->getQty(),
'quantity' => $numberOfItems,
'taxCategory' => $item->getProduct()->getAttributeText('tax_class_id'),
'taxPercentage' => $formattedTaxPercentage
];
......
......@@ -23,28 +23,27 @@
namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface;
use Adyen\Payment\Observer\AdyenHppDataAssignObserver;
/**
* Class CustomerDataBuilder
*/
class CustomerDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenRequestsHelper;
/**
* CustomerDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
/**
* CustomerDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper
\Adyen\Payment\Helper\Requests $adyenRequestsHelper
)
{
$this->adyenHelper = $adyenHelper;
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
/**
......@@ -55,69 +54,14 @@ class CustomerDataBuilder implements BuilderInterface
*/
public function build(array $buildSubject)
{
$result = [];
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$order = $paymentDataObject->getOrder();
$payment = $paymentDataObject->getPayment();
$payment = $paymentDataObject->getPayment();
$customerId = $order->getCustomerId();
$billingAddress = $order->getBillingAddress();
$storeId = $order->getStoreId();
if ($customerId > 0) {
$result['shopperReference'] = $customerId;
}
$billingAddress = $order->getBillingAddress();
if (!empty($billingAddress)) {
if ($this->adyenHelper->isPaymentMethodOpenInvoiceMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
) && !$this->adyenHelper->isPaymentMethodAfterpayTouchMethod(
$payment->getAdditionalInformation(AdyenHppDataAssignObserver::BRAND_CODE)
)) {
if ($customerEmail = $billingAddress->getEmail()) {
$result['paymentMethod']['personalDetails']['shopperEmail'] = $customerEmail;
}
if ($customerTelephone = trim($billingAddress->getTelephone())) {
$result['paymentMethod']['personalDetails']['telephoneNumber'] = $customerTelephone;
}
if ($firstName = $billingAddress->getFirstname()) {
$result['paymentMethod']['personalDetails']['firstName'] = $firstName;
}
if ($lastName = $billingAddress->getLastname()) {
$result['paymentMethod']['personalDetails']['lastName'] = $lastName;
}
} else {
if ($customerEmail = $billingAddress->getEmail()) {
$result['shopperEmail'] = $customerEmail;
}
if ($customerTelephone = trim($billingAddress->getTelephone())) {
$result['telephoneNumber'] = $customerTelephone;
}
if ($firstName = $billingAddress->getFirstname()) {
$result['shopperName']['firstName'] = $firstName;
}
if ($lastName = $billingAddress->getLastname()) {
$result['shopperName']['lastName'] = $lastName;
}
}
if ($countryId = $billingAddress->getCountryId()) {
$result['countryCode'] = $countryId;
}
if ($shopperLocale = $this->adyenHelper->getCurrentLocaleCode($order->getStoreId())) {
$result['shopperLocale'] = $shopperLocale;
}
}
return $result;
return $this->adyenRequestsHelper->buildCustomerData([], $customerId, $billingAddress, $storeId, $payment);
}
}
......@@ -29,6 +29,21 @@ use Magento\Payment\Gateway\Request\BuilderInterface;
*/
class CustomerIpDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenRequestsHelper;
/**
* CustomerIpDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
public function __construct(\Adyen\Payment\Helper\Requests $adyenRequestsHelper)
{
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
/**
* @param array $buildSubject
* @return array
......@@ -38,6 +53,7 @@ class CustomerIpDataBuilder implements BuilderInterface
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$order = $paymentDataObject->getOrder();
return ['shopperIP' => $order->getRemoteIp()];
return $this->adyenRequestsHelper->buildCustomerIpData([], $order->getRemoteIp());
}
}
......@@ -28,19 +28,19 @@ use Magento\Payment\Gateway\Request\BuilderInterface;
class MerchantAccountDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenHelper;
private $adyenRequestsHelper;
/**
* RecurringDataBuilder constructor.
* MerchantAccountDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper
\Adyen\Payment\Helper\Requests $adyenRequestsHelper
) {
$this->adyenHelper = $adyenHelper;
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
/**
......@@ -52,12 +52,10 @@ class MerchantAccountDataBuilder implements BuilderInterface
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$order = $paymentDataObject->getOrder();
$storeId = $order->getStoreId();
$payment = $paymentDataObject->getPayment();
$storeId = $order->getStoreId();
$method = $payment->getMethod();
$merchantAccount = $this->adyenHelper->getAdyenMerchantAccount($method, $storeId);
return ["merchantAccount" => $merchantAccount];
return $this->adyenRequestsHelper->buildMerchantAccountData([], $method, $storeId);
}
}
......@@ -29,20 +29,19 @@ use Magento\Payment\Gateway\Request\BuilderInterface;
*/
class PaymentDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenHelper;
private $adyenRequestsHelper;
/**
* PaymentDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
public function __construct(\Adyen\Payment\Helper\Data $adyenHelper)
public function __construct(\Adyen\Payment\Helper\Requests $adyenRequestsHelper)
{
$this->adyenHelper = $adyenHelper;
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
/**
......@@ -60,14 +59,8 @@ class PaymentDataBuilder implements BuilderInterface
$currencyCode = $fullOrder->getOrderCurrencyCode();
$amount = $fullOrder->getGrandTotal();
$reference = $order->getOrderIncrementId();
$amount = ['currency' => $currencyCode,
'value' => $this->adyenHelper->formatAmount($amount, $currencyCode)];
return [
"amount" => $amount,
"reference" => $order->getOrderIncrementId(),
"fraudOffset" => "0"
];
return $this->adyenRequestsHelper->buildPaymentData([], $amount, $currencyCode, $reference);
}
}
......@@ -28,27 +28,27 @@ use Magento\Payment\Gateway\Request\BuilderInterface;
class RecurringDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Data
* @var \Magento\Framework\App\State
*/
private $adyenHelper;
private $appState;
/**
* @var \Magento\Framework\App\State
* @var \Adyen\Payment\Helper\Requests
*/
private $appState;
private $adyenRequestsHelper;
/**
* RecurringDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Magento\Framework\Model\Context $context
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper,
\Magento\Framework\Model\Context $context
\Magento\Framework\Model\Context $context,
\Adyen\Payment\Helper\Requests $adyenRequestsHelper
) {
$this->adyenHelper = $adyenHelper;
$this->appState = $context->getAppState();
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
......@@ -59,39 +59,12 @@ class RecurringDataBuilder implements BuilderInterface
*/
public function build(array $buildSubject)
{
$result = [];
// If the vault feature is on this logic is handled in the VaultDataBuilder
if (!$this->adyenHelper->isCreditCardVaultEnabled()) {
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$storeId = null;
if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE) {
$storeId = $payment->getOrder()->getStoreId();
}
$enableOneclick = $this->adyenHelper->getAdyenAbstractConfigData('enable_oneclick', $storeId);
$enableRecurring = $this->adyenHelper->getAdyenAbstractConfigData('enable_recurring', $storeId);
if ($enableOneclick) {
$result['enableOneClick'] = true;
} else {
$result['enableOneClick'] = false;
}
if ($enableRecurring) {
$result['enableRecurring'] = true;
} else {
$result['enableRecurring'] = false;
}
if ($payment->getAdditionalInformation('store_cc') === '1') {
$result['paymentMethod']['storeDetails'] = true;
}
}
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$storeId = $payment->getOrder()->getStoreId();
$areaCode = $this->appState->getAreaCode();
return $result;
return $this->adyenRequestsHelper->buildRecurringData([], $areaCode, $storeId, $payment);
}
}
......@@ -46,4 +46,4 @@ class RecurringVaultDataBuilder implements BuilderInterface
$result['shopperInteraction'] = 'ContAuth';
return $result;
}
}
\ No newline at end of file
}
......@@ -177,7 +177,10 @@ class RefundDataBuilder implements BuilderInterface
return $result;
}
/**
* @param \Magento\Payment\Model\InfoInterface $payment
* @return array|mixed
*/
protected function getOpenInvoiceData($payment)
{
$formFields = [];
......@@ -185,11 +188,11 @@ class RefundDataBuilder implements BuilderInterface
$currency = $payment->getOrder()->getOrderCurrencyCode();
/**
* Magento\Sales\Model\Order\Creditmemo
* @var \Magento\Sales\Model\Order\Creditmemo $creditMemo
*/
$creditMemo = $payment->getCreditMemo();
foreach ($creditMemo->getAllItems() as $refundItem) {
foreach ($creditMemo->getItems() as $refundItem) {
++$count;
$numberOfItems = (int)$refundItem->getQty();
......@@ -201,7 +204,7 @@ class RefundDataBuilder implements BuilderInterface
$currency,
$refundItem->getTaxAmount(),
$refundItem->getPriceInclTax(),
$refundItem->getTaxPercent(),
$refundItem->getOrderItem()->getTaxPercent(),
$numberOfItems,
$payment,
$refundItem->getId()
......
......@@ -24,17 +24,23 @@
namespace Adyen\Payment\Gateway\Request;
use Magento\Payment\Gateway\Request\BuilderInterface;
use Magento\Vault\Model\Ui\VaultConfigProvider;
use \Magento\Payment\Gateway\Helper\SubjectReader;
class VaultDataBuilder implements BuilderInterface
{
/**
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenRequestsHelper;
/**
* Recurring variable
* @var string
* VaultDataBuilder constructor.
*
* @param \Adyen\Payment\Helper\Requests $adyenRequestsHelper
*/
private static $enableRecurring = 'enableRecurring';
public function __construct(\Adyen\Payment\Helper\Requests $adyenRequestsHelper)
{
$this->adyenRequestsHelper = $adyenRequestsHelper;
}
/**
* @param array $buildSubject
......@@ -43,21 +49,11 @@ class VaultDataBuilder implements BuilderInterface
public function build(array $buildSubject)
{
// vault is enabled and shopper provided consent to store card this logic is triggered
$request = [];
$paymentDO = SubjectReader::readPayment($buildSubject);
$payment = $paymentDO->getPayment();
$data = $payment->getAdditionalInformation();
/** @var \Magento\Payment\Gateway\Data\PaymentDataObject $paymentDataObject */
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$additionalInformation = $payment->getAdditionalInformation();
if (!empty($data[VaultConfigProvider::IS_ACTIVE_CODE]) &&
$data[VaultConfigProvider::IS_ACTIVE_CODE] === true
) {
// store it only as oneclick otherwise we store oneclick tokens (maestro+bcmc) that will fail
$request[self::$enableRecurring] = true;
} else {
// explicity turn this off as merchants have recurring on by default
$request[self::$enableRecurring] = false;
}
return $request;
return $this->adyenRequestsHelper->buildVaultData([], $additionalInformation);
}
}
\ No newline at end of file
}
......@@ -48,10 +48,9 @@ class CheckoutPaymentsDetailsHandler implements HandlerInterface
*/
public function handle(array $handlingSubject, array $response)
{
$payment = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($handlingSubject);
$paymentDataObject = \Magento\Payment\Gateway\Helper\SubjectReader::readPayment($handlingSubject);
/** @var OrderPaymentInterface $payment */
$payment = $payment->getPayment();
$payment = $paymentDataObject->getPayment();
// set transaction not to processing by default wait for notification
$payment->setIsTransactionPending(true);
......@@ -69,7 +68,8 @@ class CheckoutPaymentsDetailsHandler implements HandlerInterface
}
if (!empty($response['additionalData']['recurring.recurringDetailReference']) &&
!$this->adyenHelper->isCreditCardVaultEnabled()
!$this->adyenHelper->isCreditCardVaultEnabled() &&
$payment->getMethodInstance()->getCode() !== \Adyen\Payment\Model\Ui\AdyenOneclickConfigProvider::CODE
) {
$order = $payment->getOrder();
$this->adyenHelper->createAdyenBillingAgreement($order, $response['additionalData']);
......
......@@ -80,6 +80,9 @@ class CheckoutResponseValidator extends AbstractValidator
}
}
$payment->setAdditionalInformation('pspReference', $response['pspReference']);
break;
case "Received":
$payment->setAdditionalInformation('pspReference', $response['pspReference']);
break;
case "PresentToShopper":
......
<?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\Validator;
use Magento\Payment\Gateway\Validator\AbstractValidator;
class ThreeDS2ResponseValidator extends AbstractValidator
{
/**
* GeneralResponseValidator constructor.
*
* @param \Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
*/
public function __construct(
\Magento\Payment\Gateway\Validator\ResultInterfaceFactory $resultFactory
) {
parent::__construct($resultFactory);
}
/**
* @param array $validationSubject
* @return \Magento\Payment\Gateway\Validator\ResultInterface
*/
public function validate(array $validationSubject)
{
$response = \Magento\Payment\Gateway\Helper\SubjectReader::readResponse($validationSubject);
if (!empty($validationSubject['payment'])) {
$payment = $validationSubject['payment'];
} else {
$errorMsg = __('Error with payment method during validation please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
$isValid = true;
$errorMessages = [];
// validate result
if (!empty($response['resultCode'])) {
// 3DS2.0 should have IdentifyShopper or ChallengeShopper as a resultCode
if ($response['resultCode'] == "IdentifyShopper" &&
!empty($response['authentication']['threeds2.fingerprintToken'])
) {
$payment->setAdditionalInformation('threeDS2Type', $response['resultCode']);
$payment->setAdditionalInformation('threeDS2Token', $response['authentication']['threeds2.fingerprintToken']);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
} elseif ($response['resultCode'] == "ChallengeShopper" &&
!empty($response['authentication']['threeds2.challengeToken'])
) {
$payment->setAdditionalInformation('threeDS2Type', $response['resultCode']);
$payment->setAdditionalInformation('threeDS2Token', $response['authentication']['threeds2.challengeToken']);
$payment->setAdditionalInformation('threeDS2PaymentData', $response['paymentData']);
} else {
$errorMsg = __('Error with payment method please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
} else {
$errorMsg = __('Error with payment method please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
return $this->createResult($isValid, $errorMessages);
}
}
......@@ -35,8 +35,8 @@ class Data extends AbstractHelper
const LIVE = 'live';
const CHECKOUT_CONTEXT_URL_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/';
const CHECKOUT_CONTEXT_URL_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/';
const CHECKOUT_COMPONENT_JS_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/2.1.0/adyen.js';
const CHECKOUT_COMPONENT_JS_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/2.1.0/adyen.js';
const CHECKOUT_COMPONENT_JS_LIVE = 'https://checkoutshopper-live.adyen.com/checkoutshopper/sdk/2.5.0/adyen.js';
const CHECKOUT_COMPONENT_JS_TEST = 'https://checkoutshopper-test.adyen.com/checkoutshopper/sdk/2.5.0/adyen.js';
/**
* @var \Magento\Framework\Encryption\EncryptorInterface
......@@ -371,7 +371,7 @@ class Data extends AbstractHelper
*/
public function getStreetFromString($streetLine)
{
$street = self::formatStreet(array($streetLine));
$street = self::formatStreet([$streetLine]);
$streetName = $street['0'];
unset($street['0']);
$streetNr = implode(' ', $street);
......@@ -449,10 +449,10 @@ class Data extends AbstractHelper
}
/**
* Gives back adyen_cc configuration values as flag
* Gives back adyen_cc_vault configuration values as flag
*
* @param $field
* @param null $storeId
* @param int|null $storeId
* @return mixed
*/
public function getAdyenCcVaultConfigDataFlag($field, $storeId = null)
......@@ -460,6 +460,18 @@ class Data extends AbstractHelper
return $this->getConfigData($field, 'adyen_cc_vault', $storeId, true);
}
/**
* Gives back adyen_cc_threeds2 configuration values as flag
*
* @param $field
* @param null $storeId
* @return mixed
*/
public function getAdyenCcThreeDS2ConfigDataFlag($field, $storeId = null)
{
return $this->getConfigData($field, 'adyen_cc_threeds2', $storeId, true);
}
/**
* Gives back adyen_hpp configuration values
*
......@@ -1110,6 +1122,15 @@ class Data extends AbstractHelper
return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
}
/**
* Format Magento locale codes with undersocre to ISO locale codes with dash
* @param $localeCode
*/
public function formatLocaleCode($localeCode)
{
return str_replace("_", "-", $localeCode);
}
public function getApplePayShippingTypes()
{
return [
......@@ -1348,11 +1369,15 @@ class Data extends AbstractHelper
* return the merchant account name defined in required settings.
*
* @param $paymentMethod
* @param int $storeId
* @param int|null $storeId
* @return string
*/
public function getAdyenMerchantAccount($paymentMethod, $storeId)
public function getAdyenMerchantAccount($paymentMethod, $storeId = null)
{
if (!$storeId) {
$storeId = $this->storeManager->getStore()->getId();
}
$merchantAccount = $this->getAdyenAbstractConfigData("merchant_account", $storeId);
$merchantAccountPos = $this->getAdyenPosCloudConfigData('pos_merchant_account', $storeId);
......@@ -1452,6 +1477,16 @@ class Data extends AbstractHelper
return new \Adyen\Client();
}
/**
* @return string
*/
public function getOrigin() {
$baseUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB);
$parsed = parse_url($baseUrl);
$origin = $parsed['scheme'] . "://" . $parsed['host'];
return $origin;
}
/**
* Retrieve origin keys for platform's base url
*
......@@ -1460,15 +1495,13 @@ class Data extends AbstractHelper
*/
public function getOriginKeyForBaseUrl()
{
$baseUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB);
$parsed = parse_url($baseUrl);
$domain = $parsed['scheme'] . "://" . $parsed['host'];
$origin = $this->getOrigin();
$storeId = $this->storeManager->getStore()->getId();
$cacheKey = 'Adyen_origin_key_for_' . $domain . '_' . $storeId;
$cacheKey = 'Adyen_origin_key_for_' . $origin . '_' . $storeId;
if (!$originKey = $this->cache->load($cacheKey)) {
if ($originKey = $this->getOriginKeyForUrl($domain, $storeId)) {
$this->cache->save($originKey, $cacheKey, array(), 60 * 60 * 24);
if ($originKey = $this->getOriginKeyForOrigin($origin, $storeId)) {
$this->cache->save($originKey, $cacheKey, [], 60 * 60 * 24);
}
}
......@@ -1476,20 +1509,20 @@ class Data extends AbstractHelper
}
/**
* Get origin key for a specific url using the adyen api library client
* Get origin key for a specific origin using the adyen api library client
*
* @param $url
* @param $origin
* @param int|null $storeId
* @return string
* @throws \Adyen\AdyenException
*/
private function getOriginKeyForUrl($url, $storeId = null)
private function getOriginKeyForOrigin($origin, $storeId = null)
{
$params = array(
"originDomains" => array(
$url
)
);
$params = [
"originDomains" => [
$origin
]
];
$client = $this->initializeAdyenClient($storeId);
......@@ -1502,8 +1535,8 @@ class Data extends AbstractHelper
$originKey = "";
if (!empty($response['originKeys'][$url])) {
$originKey = $response['originKeys'][$url];
if (!empty($response['originKeys'][$origin])) {
$originKey = $response['originKeys'][$origin];
}
return $originKey;
......@@ -1580,7 +1613,8 @@ class Data extends AbstractHelper
// Populate billing agreement data
$storeOneClick = $order->getPayment()->getAdditionalInformation('store_cc');
$billingAgreement->setCcBillingAgreement($additionalData, $storeOneClick);
$billingAgreement->setCcBillingAgreement($additionalData, $storeOneClick, $order->getStoreId());
if ($billingAgreement->isValid()) {
if (!$this->agreementResourceModel->getOrderRelation($billingAgreement->getAgreementId(),
......@@ -1658,7 +1692,6 @@ class Data extends AbstractHelper
return $icon;
}
/**
* Check if CreditCard vault is enabled
*
......@@ -1682,6 +1715,16 @@ class Data extends AbstractHelper
return in_array(strtolower($country), $countryList);
}
/**
* Check if 3DS2.0 is enabled for credit cards
*
* @param int|null $storeId
* @return mixed
*/
public function isCreditCardThreeDS2Enabled($storeId = null)
{
return $this->getAdyenCcThreeDS2ConfigDataFlag('active', $storeId);
}
/**
* @param $client
......@@ -1716,6 +1759,26 @@ 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 ($type && $token) {
$response = [
"threeDS2" => true,
"type" => $type,
"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
......@@ -92,7 +92,7 @@ class PaymentMethods extends AbstractHelper
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param Data $adyenHelper
* @param \Magento\Checkout\Model\Session $session
* @param \Magento\Framework\Locale\ResolverInterface $localeResolver
* @param \Magento\Framework\Locale\ResolverInterface $localeResolver
* @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger
* @param \Magento\Framework\View\Asset\Repository $assetRepo
* @param \Magento\Framework\App\RequestInterface $request
......@@ -105,7 +105,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,
......@@ -117,7 +117,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;
......
This diff is collapsed.
<?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\Model;
use \Adyen\Payment\Api\AdyenPaymentProcessInterface;
class AdyenPaymentProcess implements AdyenPaymentProcessInterface
{
/**
* @var \Magento\Checkout\Model\Session
*/
private $checkoutSession;
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* @var \Adyen\Payment\Helper\Requests
*/
private $adyenRequestHelper;
/**
* @var \Magento\Framework\Model\Context
*/
private $context;
/**
* @var \Adyen\Payment\Gateway\Http\TransferFactory
*/
private $transferFactory;
/**
* @var \Adyen\Payment\Gateway\Http\Client\TransactionPayment
*/
private $transactionPayment;
/**
* @var \Adyen\Payment\Gateway\Validator\CheckoutResponseValidator
*/
private $checkoutResponseValidator;
/**
* @var \Adyen\Payment\Gateway\Validator\ThreeDS2ResponseValidator
*/
private $threeDS2ResponseValidator;
/**
* AdyenPaymentProcess constructor.
*
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Checkout\Model\Session $checkoutSession
* @param \Adyen\Payment\Helper\Data $adyenHelper
* @param \Adyen\Payment\Helper\Requests $adyenRequestHelper
* @param \Adyen\Payment\Gateway\Http\TransferFactory $transferFactory
* @param \Adyen\Payment\Gateway\Http\Client\TransactionPayment $transactionPayment
* @param \Adyen\Payment\Gateway\Validator\CheckoutResponseValidator $checkoutResponseValidator
* @param \Adyen\Payment\Gateway\Validator\ThreeDS2ResponseValidator $threeDS2ResponseValidator
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Checkout\Model\Session $checkoutSession,
\Adyen\Payment\Helper\Data $adyenHelper,
\Adyen\Payment\Helper\Requests $adyenRequestHelper,
\Adyen\Payment\Gateway\Http\TransferFactory $transferFactory,
\Adyen\Payment\Gateway\Http\Client\TransactionPayment $transactionPayment,
\Adyen\Payment\Gateway\Validator\CheckoutResponseValidator $checkoutResponseValidator,
\Adyen\Payment\Gateway\Validator\ThreeDS2ResponseValidator $threeDS2ResponseValidator
)
{
$this->context = $context;
$this->checkoutSession = $checkoutSession;
$this->adyenHelper = $adyenHelper;
$this->adyenRequestHelper = $adyenRequestHelper;
$this->transferFactory = $transferFactory;
$this->transactionPayment = $transactionPayment;
$this->checkoutResponseValidator = $checkoutResponseValidator;
$this->threeDS2ResponseValidator = $threeDS2ResponseValidator;
}
/**
* @api
* @param string $payload
* @return string
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function initiate($payload)
{
// Decode payload from frontend
$payload = json_decode($payload, true);
// Validate JSON that has just been parsed if it was in a valid format
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Magento\Framework\Exception\LocalizedException(__('Error with payment method please select different payment method.'));
}
// Get payment and cart information from session
$quote = $this->checkoutSession->getQuote();
$payment = $quote->getPayment();
// Init request array
$request = [];
// Merchant account data builder
$paymentMethod = $payment->getMethod();
$storeId = $quote->getStoreId();
$request = $this->adyenRequestHelper->buildMerchantAccountData($request, $paymentMethod, $storeId);
// Customer data builder
$customerId = $quote->getCustomerId();
$billingAddress = $quote->getBillingAddress();
$request = $this->adyenRequestHelper->buildCustomerData($request, $customerId, $billingAddress, $storeId);
// Customer Ip data builder
$shopperIp = $quote->getRemoteIp();
$request = $this->adyenRequestHelper->buildCustomerIpData($request, $shopperIp);
// AddressDataBuilder
$shippingAddress = $quote->getShippingAddress();
$request = $this->adyenRequestHelper->buildAddressData($request, $billingAddress, $shippingAddress);
// PaymentDataBuilder
$currencyCode = $quote->getQuoteCurrencyCode();
$amount = $quote->getGrandTotal();
// Setting the orderid to null, so that we generate a new one for each /payments call
$quote->setReservedOrderId(null);
$reference = $quote->reserveOrderId()->getReservedOrderId();
$request = $this->adyenRequestHelper->buildPaymentData($request, $amount, $currencyCode, $reference);
// Browser data builder
$request = $this->adyenRequestHelper->buildBrowserData($request);
// 3DS2.0 data builder
$isThreeDS2Enabled = $this->adyenHelper->isCreditCardThreeDS2Enabled($storeId);
if ($isThreeDS2Enabled) {
$request = $this->adyenRequestHelper->buildThreeDS2Data($request, $payload, $quote->getStore());
}
// RecurringDataBuilder
$areaCode = $this->context->getAppState()->getAreaCode();
$request = $this->adyenRequestHelper->buildRecurringData($request, $areaCode, $storeId, $payload);
// CcAuthorizationDataBuilder
$request = $this->adyenRequestHelper->buildCCData($request, $payload, $storeId, $areaCode);
// Vault data builder
$request = $this->adyenRequestHelper->buildVaultData($request, $payload);
// Create and send request
$transferObject = $this->transferFactory->create($request);
$paymentsResponse = $this->transactionPayment->placeRequest($transferObject);
// Check if 3DS2.0 validation is needed or not
// In case 3DS2.0 validation is necessary send the type and token back to the frontend
if (!empty($paymentsResponse['resultCode'])) {
if ($paymentsResponse['resultCode'] == 'IdentifyShopper' ||
$paymentsResponse['resultCode'] == 'ChallengeShopper') {
if ($this->threeDS2ResponseValidator->validate(array(
"response" => $paymentsResponse,
"payment" => $payment
))->isValid()) {
$quote->save();
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($payment->getAdditionalInformation('threeDS2Type'),
$payment->getAdditionalInformation('threeDS2Token'));
}
}
} else {
$errorMsg = __('Error with payment method please select different payment method.');
throw new \Magento\Framework\Exception\LocalizedException(__($errorMsg));
}
// Save the payments response because we are going to need it during the place order flow
$payment->setAdditionalInformation("paymentsResponse", $paymentsResponse);
// To actually save the additional info changes into the quote
$quote->save();
// Original flow can continue, return to frontend and place the order
return $this->adyenHelper->buildThreeDS2ProcessResponseJson();
}
}
<?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\Model;
use \Adyen\Payment\Api\AdyenThreeDS2ProcessInterface;
class AdyenThreeDS2Process implements AdyenThreeDS2ProcessInterface
{
/**
* @var \Magento\Checkout\Model\Session
*/
private $checkoutSession;
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* AdyenThreeDS2Process constructor.
*
* @param \Magento\Checkout\Model\Session $checkoutSession
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
\Magento\Checkout\Model\Session $checkoutSession,
\Adyen\Payment\Helper\Data $adyenHelper
)
{
$this->checkoutSession = $checkoutSession;
$this->adyenHelper = $adyenHelper;
}
/**
* @api
* @param string $payload
* @return string
*/
public function initiate($payload)
{
// Decode payload from frontend
$payload = json_decode($payload, true);
// Validate JSON that has just been parsed if it was in a valid format
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed because the request was not a valid JSON'));
}
// Get payment and cart information from session
$quote = $this->checkoutSession->getQuote();
$payment = $quote->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 {
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'];
}
// Send the request
try {
$client = $this->adyenHelper->initializeAdyenClient($quote->getStoreId());
$service = $this->adyenHelper->createAdyenCheckoutService($client);
$result = $service->paymentsDetails($request);
} catch (\Adyen\AdyenException $e) {
throw new \Magento\Framework\Exception\LocalizedException(__('3D secure 2.0 failed'));
}
// Check if result is challenge shopper, if yes return the token
if (!empty($result['resultCode']) &&
$result['resultCode'] === 'ChallengeShopper' &&
!empty($result['authentication']['threeds2.challengeToken'])
) {
return $this->adyenHelper->buildThreeDS2ProcessResponseJson($result['resultCode'], $result['authentication']['threeds2.challengeToken']);
}
// Payment can get back to the original flow
// Save the payments response because we are going to need it during the place order flow
$payment->setAdditionalInformation("paymentsResponse", $result);
// Setting the placeOrder to true enables the process to skip the payments call because the paymentsResponse
// is already in place - only set placeOrder to true when you have the paymentsResponse
$payment->setAdditionalInformation('placeOrder', true);
// To actually save the additional info changes into the quote
$quote->save();
// 3DS2 flow is done, original place order flow can continue from frontend
return $this->adyenHelper->buildThreeDS2ProcessResponseJson();
}
}
......@@ -173,7 +173,7 @@ class Agreement extends \Magento\Paypal\Model\Billing\Agreement
* @param $contractDetail
* @return $this
*/
public function setCcBillingAgreement($contractDetail, $storeOneClick)
public function setCcBillingAgreement($contractDetail, $storeOneClick, $storeId)
{
$this
->setMethodCode('adyen_oneclick')
......@@ -212,9 +212,9 @@ class Agreement extends \Magento\Paypal\Model\Billing\Agreement
$expiryDate = explode('/', $contractDetail['expiryDate']);
if (!empty($contractDetail['pos_payment'])) {
$recurringType = $this->adyenHelper->getAdyenPosCloudConfigData('recurring_type');
$recurringType = $this->adyenHelper->getAdyenPosCloudConfigData('recurring_type', $storeId);
} else {
$recurringType = $this->adyenHelper->getRecurringTypeFromOneclickRecurringSetting();
$recurringType = $this->adyenHelper->getRecurringTypeFromOneclickRecurringSetting($storeId);
// for bcmc and maestro recurring is not allowed so don't set this
if ($recurringType === \Adyen\Payment\Model\RecurringType::ONECLICK_RECURRING &&
......
......@@ -907,6 +907,41 @@ class Cron
}
break;
case Notification::OFFER_CLOSED:
$previousSuccess = $this->_order->getData('adyen_notification_event_code_success');
// Order is already Authorised
if (!empty($previousSuccess)) {
$this->_adyenLogger->addAdyenNotificationCronjob("Order is already authorised, skipping OFFER_CLOSED");
break;
}
/*
* For cards, it can be 'visa', 'maestro',...
* For alternatives, it can be 'ideal', 'directEbanking',...
*/
$notificationPaymentMethod = $this->_paymentMethod;
/*
* For cards, it can be 'VI', 'MI',...
* For alternatives, it can be 'ideal', 'directEbanking',...
*/
$orderPaymentMethod = $this->_order->getPayment()->getCcType();
$isOrderCc = strcmp($this->_paymentMethodCode(),
'adyen_cc') == 0 || strcmp($this->_paymentMethodCode(), 'adyen_oneclick') == 0;
/*
* If the order was made with an Alternative payment method,
* continue with the cancellation only if the payment method of
* the notification matches the payment method of the order.
*/
if (!$isOrderCc && strcmp($notificationPaymentMethod, $orderPaymentMethod) !== 0) {
$this->_adyenLogger->addAdyenNotificationCronjob("Order is not a credit card,
or the payment method in the notification does not match the payment method of the order,
skipping OFFER_CLOSED");
break;
}
if (!$this->_order->canCancel()) {
// Move the order from PAYMENT_REVIEW to NEW, so that can be cancelled
$this->_order->setState(\Magento\Sales\Model\Order::STATE_NEW);
......@@ -1148,9 +1183,14 @@ class Cron
protected function _authorizePayment()
{
$this->_adyenLogger->addAdyenNotificationCronjob('Authorisation of the order');
// Set adyen_notification_event_code_success to true so that we ignore a possible OFFER_CLOSED
if (strcmp($this->_success, 'true') == 0) {
$this->_order->setData('adyen_notification_event_code_success', 1);
}
$fraudManualReviewStatus = $this->_getFraudManualReviewStatus();
// If manual review is active and a seperate status is used then ignore the pre authorized status
// If manual review is active and a separate status is used then ignore the pre authorized status
if ($this->_fraudManualReview != true || $fraudManualReviewStatus == "") {
$this->_setPrePaymentAuthorized();
} else {
......
......@@ -134,7 +134,7 @@ class AdyenHppConfigProvider implements ConfigProviderInterface
}
}
$config['payment']['adyenHpp']['locale'] = $this->adyenHelper->getStoreLocale($this->storeManager->getStore()->getId());
$config['payment']['adyenHpp']['locale'] = $this->adyenHelper->getCurrentLocaleCode($this->storeManager->getStore()->getId());
// add to config
$config['payment'] ['adyenHpp']['gender'] = $gender;
......
......@@ -46,6 +46,21 @@ class AdyenBoletoDataAssignObserver extends AbstractDataAssignObserver
self::LASTNAME
];
/**
* @var \Adyen\Payment\Helper\Data
*/
private $adyenHelper;
/**
* AdyenBoletoDataAssignObserver constructor.
*
* @param \Adyen\Payment\Helper\Data $adyenHelper
*/
public function __construct(
\Adyen\Payment\Helper\Data $adyenHelper
) {
$this->adyenHelper = $adyenHelper;
}
/**
* @param Observer $observer
* @return void
......@@ -60,8 +75,11 @@ class AdyenBoletoDataAssignObserver extends AbstractDataAssignObserver
}
$paymentInfo = $this->readPaymentModelArgument($observer);
$paymentInfo->setCcType('boleto');
if (!empty($additionalData[self::BOLETO_TYPE])) {
$paymentInfo->setCcType($additionalData[self::BOLETO_TYPE]);
} else {
$paymentInfo->setCcType($this->adyenHelper->getAdyenBoletoConfigData('boletotypes'));
}
foreach ($this->additionalInformationList as $additionalInformationKey) {
if (isset($additionalData[$additionalInformationKey])) {
......
......@@ -40,6 +40,12 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
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';
/**
* @var array
......@@ -53,7 +59,13 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
self::ENCRYPTED_EXPIRY_MONTH,
self::ENCRYPTED_EXPIRY_YEAR,
self::HOLDER_NAME,
self::VARIANT
self::VARIANT,
self::JAVA_ENABLED,
self::SCREEN_COLOR_DEPTH,
self::SCREEN_WIDTH,
self::SCREEN_HEIGHT,
self::TIMEZONE_OFFSET,
self::LANGUAGE
];
/**
......
......@@ -35,6 +35,12 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
const ENCRYPTED_SECURITY_CODE = 'cvc';
const NUMBER_OF_INSTALLMENTS = 'number_of_installments';
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';
/**
* @var array
......@@ -43,7 +49,13 @@ class AdyenOneclickDataAssignObserver extends AbstractDataAssignObserver
self::RECURRING_DETAIL_REFERENCE,
self::ENCRYPTED_SECURITY_CODE,
self::NUMBER_OF_INSTALLMENTS,
self::VARIANT
self::VARIANT,
self::JAVA_ENABLED,
self::SCREEN_COLOR_DEPTH,
self::SCREEN_WIDTH,
self::SCREEN_HEIGHT,
self::TIMEZONE_OFFSET,
self::LANGUAGE
];
/**
......
......@@ -2,7 +2,7 @@
"name": "adyen/module-payment",
"description": "Official Magento2 Plugin to connect to Payment Service Provider Adyen.",
"type": "magento2-module",
"version": "4.1.1",
"version": "4.2.0",
"license": [
"OSL-3.0",
"AFL-3.0"
......
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!-- Authorization Request -->
<virtualType name="AdyenPaymentCcAuthorizeRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
<argument name="builders" xsi:type="array">
<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item>
<item name="customer" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerDataBuilder</item>
<item name="customerip" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerIpDataBuilder</item>
<item name="address" xsi:type="string">Adyen\Payment\Gateway\Request\AddressDataBuilder</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="recurring" xsi:type="string">Adyen\Payment\Gateway\Request\RecurringDataBuilder</item>
<item name="transaction" xsi:type="string">Adyen\Payment\Gateway\Request\CcBackendAuthorizationDataBuilder</item>
<item name="vault" xsi:type="string">Adyen\Payment\Gateway\Request\VaultDataBuilder</item>
</argument>
</arguments>
</virtualType>
<type name="Magento\Framework\Notification\MessageList">
<arguments>
<argument name="messages" xsi:type="array">
......
......@@ -59,6 +59,12 @@
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/adyen_cc_vault/active</config_path>
</field>
<field id="adyen_cc_threeds2" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1"
showInStore="1">
<label>3DS2.0 Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/adyen_cc_threeds2/active</config_path>
</field>
<group id="adyen_cc_advanced_settings" translate="label" showInDefault="1" showInWebsite="1" showInStore="1"
sortOrder="150">
......
......@@ -489,16 +489,8 @@
<virtualType name="AdyenPaymentCcAuthorizeRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
<argument name="builders" xsi:type="array">
<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item>
<item name="customer" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerDataBuilder</item>
<item name="customerip" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerIpDataBuilder</item>
<item name="address" xsi:type="string">Adyen\Payment\Gateway\Request\AddressDataBuilder</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="recurring" xsi:type="string">Adyen\Payment\Gateway\Request\RecurringDataBuilder</item>
<item name="transaction" xsi:type="string">Adyen\Payment\Gateway\Request\CcAuthorizationDataBuilder
</item>
<item name="vault" xsi:type="string">Adyen\Payment\Gateway\Request\VaultDataBuilder</item>
</argument>
</arguments>
</virtualType>
......@@ -536,15 +528,7 @@
<virtualType name="AdyenPaymentOneclickAuthorizeRequest" type="Magento\Payment\Gateway\Request\BuilderComposite">
<arguments>
<argument name="builders" xsi:type="array">
<item name="merchantaccount" xsi:type="string">Adyen\Payment\Gateway\Request\MerchantAccountDataBuilder</item>
<item name="customer" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerDataBuilder</item>
<item name="customerip" xsi:type="string">Adyen\Payment\Gateway\Request\CustomerIpDataBuilder</item>
<item name="address" xsi:type="string">Adyen\Payment\Gateway\Request\AddressDataBuilder</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="recurring" xsi:type="string">Adyen\Payment\Gateway\Request\RecurringDataBuilder</item>
<item name="transaction" xsi:type="string">Adyen\Payment\Gateway\Request\CcAuthorizationDataBuilder</item>
<item name="oneclick" xsi:type="string">Adyen\Payment\Gateway\Request\OneclickAuthorizationDataBuilder</item>
</argument>
</arguments>
</virtualType>
......@@ -644,6 +628,7 @@
<arguments>
<argument name="handlers" xsi:type="array">
<item name="payment_details" xsi:type="string">Adyen\Payment\Gateway\Response\CheckoutPaymentsDetailsHandler</item>
<item name="vault_details" xsi:type="string">Adyen\Payment\Gateway\Response\VaultDetailsHandler</item>
<item name="payment_comments" xsi:type="string">Adyen\Payment\Gateway\Response\CheckoutPaymentCommentHistoryHandler</item>
</argument>
</arguments>
......@@ -885,8 +870,10 @@
type="Adyen\Payment\Model\AdyenRequestMerchantSession"/>
<preference for="Adyen\Payment\Api\AdyenInitiateTerminalApiInterface"
type="Adyen\Payment\Model\AdyenInitiateTerminalApi"/>
<preference for="Magento\Checkout\Api\PaymentInformationManagementInterface"
type="Adyen\Payment\Model\AdyenPaymentInformationManagement"/>
<preference for="Adyen\Payment\Api\AdyenPaymentProcessInterface"
type="Adyen\Payment\Model\AdyenPaymentProcess"/>
<preference for="Adyen\Payment\Api\AdyenThreeDS2ProcessInterface"
type="Adyen\Payment\Model\AdyenThreeDS2Process"/>
<type name="Magento\Vault\Api\PaymentTokenRepositoryInterface">
<plugin name="AdyenPaymentVaultDeleteToken" type="Adyen\Payment\Plugin\PaymentVaultDeleteToken" sortOrder="10"/>
</type>
......
......@@ -24,7 +24,7 @@
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Adyen_Payment" setup_version="4.1.1">
<module name="Adyen_Payment" setup_version="4.2.0">
<sequence>
<module name="Magento_Sales"/>
<module name="Magento_Quote"/>
......
......@@ -57,4 +57,18 @@
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/adyen/payment" method="POST">
<service class="Adyen\Payment\Api\AdyenPaymentProcessInterface" method="initiate"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/adyen/threeDS2Process" method="POST">
<service class="Adyen\Payment\Api\AdyenThreeDS2ProcessInterface" method="initiate"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>
\ No newline at end of file
......@@ -104,7 +104,10 @@ echo $code; ?>" style="display:none">
var cardNode = document.getElementById("cardContainer-<?php /* @noEscape */ echo $code; ?>");
var checkout = new AdyenCheckout({
locale: "<?php echo $block->getLocale(); ?>"
locale: "<?php echo $block->getLocale(); ?>",
risk: {
enabled: false
}
});
var hideCVC = "<?php echo !$block->hasVerification(); ?>";
......
This diff is collapsed.
/**
* 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 {
/**
* Create a Payment to define if 3DS 2.0 flow needs to be activated
* @param response
*/
processPayment: function (data) {
var payload = {
"payload": JSON.stringify(data)
};
var serviceUrl = urlBuilder.createUrl('/adyen/payment', {});
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
);
}
};
}
);
!function(e,n){"object"===typeof exports&&"object"===typeof module?module.exports=n():"function"===typeof define&&define.amd?define([],n):"object"===typeof exports?exports.ThreedDS2Utils=n():e.ThreedDS2Utils=n()}(this,function(){return function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=0)}([function(e,n,t){"use strict";t.r(n);var r={container:void 0},o={"01":["250px","400px"],"02":["390px","400px"],"03":["500px","600px"],"04":["600px","400px"],"05":["100%","100%"]};function a(e){return o.hasOwnProperty(e)?e:"01"}var i={createIframe:function(e,n){var t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"0",o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"0",a=arguments.length>4?arguments[4]:void 0;if(!n||0===n.length)throw new Error("Name parameter missing for iframe");e instanceof HTMLElement?r.container=e:r.container=document.body;var i=document.createElement("iframe");i.classList.add(n+"Class"),i.width=t,i.height=o,i.name=n,i.setAttribute("frameborder","0"),i.setAttribute("border","0");var d=document.createTextNode("<p>Your browser does not support iframes.</p>");return i.appendChild(d),r.container.appendChild(i),function(e,n){e.attachEvent?e.attachEvent("onload",function(){n&&"function"===typeof n&&n(e.contentWindow)}):e.onload=function(){n&&"function"===typeof n&&n(e.contentWindow)}}(i,a),i},createForm:function(e,n,t,r,o){if(!e||!n||!t||!r||!o)throw new Error("Not all required parameters provided for form creation");if(0===e.length||0===n.length||0===t.length||0===r.length||0===o.length)throw new Error("Not all required parameters have suitable values");var a=document.createElement("form");a.style.display="none",a.name=e,a.action=n,a.method="POST",a.target=t;var i=document.createElement("input");return i.name=r,i.value=o,a.appendChild(i),a},getBrowserInfo:function(){var e=window&&window.screen?window.screen.width:"",n=window&&window.screen?window.screen.height:"",t=window&&window.screen?window.screen.colorDepth:"",r=window&&window.navigator?window.navigator.userAgent:"",o=!(!window||!window.navigator)&&navigator.javaEnabled(),a="";return window&&window.navigator&&(a=window.navigator.language?window.navigator.language:window.navigator.browserLanguage),{screenWidth:e,screenHeight:n,colorDepth:t,userAgent:r,timeZoneOffset:(new Date).getTimezoneOffset(),language:a,javaEnabled:o}},base64Url:{encode:function(e){var n=window.btoa(e).split("=")[0];return n=(n=n.replace("/+/g","-")).replace("///g","_")},decode:function(e){var n=e;switch((n=(n=n.replace("/-/g","+")).replace("/_/g","/")).length%4){case 0:break;case 2:n+="==";break;case 3:n+="=";break;default:window.console&&window.console.log&&window.console.log("### base64url::decodeBase64URL:: Illegal base64url string!")}try{return window.atob(n)}catch(e){throw new Error(e)}}},config:{challengeWindowSizes:o,validateChallengeWindowSize:a,getChallengeWindowSize:function(e){return o[a(e)]},THREEDS_METHOD_TIMEOUT:1e4,CHALLENGE_TIMEOUT:6e5}};n.default=i}]).default});
\ No newline at end of file
......@@ -81,7 +81,10 @@ define(
* @type {AdyenCheckout}
*/
self.checkoutComponent = new AdyenCheckout({
locale: self.getLocale()
locale: self.getLocale(),
risk: {
enabled: false
}
});
// reset variable:
......
......@@ -77,6 +77,9 @@
<div afterRender="renderSecureFields()" data-bind="attr: { id: 'cardContainer'}"></div>
</div>
<div id="threeDS2Modal">
<div id="threeDS2Container"></div>
</div>
<!-- ko if: (hasInstallments())-->
......@@ -117,23 +120,6 @@
</div>
<!-- /ko -->
<!-- ko if: (canCreateBillingAgreement() && !isVaultEnabled())-->
<div class="field choice">
<input type="checkbox"
name="payment[store_cc]"
autocomplete="off"
class="checkbox"
data-bind="attr: {title: $t('Remember Me')}, checked: setStoreCc"
/>
<label data-bind="attr: {for: getCode() + '_remember_details'}" class="label">
<span><!-- ko text: $t('Remember these details')--><!-- /ko --></span>
</label>
</div>
<!-- /ko -->
</fieldset>
</form>
......
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