Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 9.5.2 #2612

Merged
merged 7 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions Gateway/Http/Client/TransactionCapture.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,18 @@ public function placeRequest(TransferInterface $transferObject): array
$client = $this->adyenHelper->initializeAdyenClientWithClientConfig($clientConfig);
$service = $this->adyenHelper->createAdyenCheckoutService($client);

$idempotencyKey = $this->idempotencyHelper->generateIdempotencyKey(
$request,
$headers['idempotencyExtraData'] ?? null
);

$requestOptions['idempotencyKey'] = $idempotencyKey;
$requestOptions['headers'] = $this->adyenHelper->buildRequestHeaders();

if (array_key_exists(self::MULTIPLE_AUTHORIZATIONS, $request)) {
return $this->placeMultipleCaptureRequests($service, $request, $requestOptions);
}
else {
$idempotencyKey = $this->idempotencyHelper->generateIdempotencyKey(
$request,
$headers['idempotencyExtraData'] ?? null
);
$requestOptions['idempotencyKey'] = $idempotencyKey;
}

$this->adyenHelper->logRequest($request, Client::API_CHECKOUT_VERSION, '/captures');

Expand All @@ -80,15 +81,23 @@ private function placeMultipleCaptureRequests($service, $requestContainer, $requ
{
$response = [];
foreach ($requestContainer[self::MULTIPLE_AUTHORIZATIONS] as $request) {
$idempotencyKeyExtraData = $request['idempotencyExtraData'];
unset($request['idempotencyExtraData']);
$idempotencyKey = $this->idempotencyHelper->generateIdempotencyKey(
$request,
$idempotencyKeyExtraData ?? null
);

$requestOptions['idempotencyKey'] = $idempotencyKey;
try {
// Copy merchant account from parent array to every request array
$request[Requests::MERCHANT_ACCOUNT] = $requestContainer[Requests::MERCHANT_ACCOUNT];
$singleResponse = $service->captures($request, $requestOptions);
$singleResponse[self::FORMATTED_CAPTURE_AMOUNT] = $request['amount']['currency'] . ' ' .
$this->adyenHelper->originalAmount(
$request['amount']['value'],
$request['amount']['currency']
);
$this->adyenHelper->originalAmount(
$request['amount']['value'],
$request['amount']['currency']
);
$singleResponse = $this->copyParamsToResponse($singleResponse, $request);
$response[self::MULTIPLE_AUTHORIZATIONS][] = $singleResponse;
} catch (AdyenException $e) {
Expand Down
7 changes: 4 additions & 3 deletions Gateway/Http/Client/TransactionPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Adyen\AdyenException;
use Adyen\Client;
use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Payment\Helper\Data;
use Adyen\Payment\Helper\GiftcardPayment;
use Adyen\Payment\Helper\Idempotency;
Expand Down Expand Up @@ -44,7 +45,7 @@ public function __construct(
Idempotency $idempotencyHelper,
OrdersApi $orderApiHelper,
StoreManagerInterface $storeManager,
GiftcardPayment $giftcardPaymentHelper
GiftcardPayment $giftcardPaymentHelper,
) {
$this->adyenHelper = $adyenHelper;
$this->paymentResponseFactory = $paymentResponseFactory;
Expand All @@ -53,7 +54,6 @@ public function __construct(
$this->orderApiHelper = $orderApiHelper;
$this->storeManager = $storeManager;
$this->giftcardPaymentHelper = $giftcardPaymentHelper;

$this->remainingOrderAmount = null;
}

Expand Down Expand Up @@ -84,7 +84,8 @@ public function placeRequest(TransferInterface $transferObject): array
$headers['idempotencyExtraData'] ?? null
);
$requestOptions['idempotencyKey'] = $idempotencyKey;
$requestOptions['headers'] = $this->adyenHelper->buildRequestHeaders();
$requestOptions['headers'] = $headers;


$this->adyenHelper->logRequest($request, Client::API_CHECKOUT_VERSION, '/payments');
$response = $service->payments($request, $requestOptions);
Expand Down
9 changes: 4 additions & 5 deletions Gateway/Request/CaptureDataBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ public function buildPartialOrMultipleCaptureData($payment, $currency, $adyenOrd
$openInvoiceFields = $this->openInvoiceHelper->getOpenInvoiceDataForInvoice($invoice);
$authToCapture = array_merge($authToCapture, $openInvoiceFields);
}
$authToCapture['idempotencyExtraData'] = [
'totalInvoiced' => $adyenOrderPayment[OrderPaymentInterface::TOTAL_CAPTURED] ?? 0,
'originalPspReference' => $adyenOrderPayment[OrderPaymentInterface::PSPREFRENCE]
] ;

$captureData[] = $authToCapture;
}
Expand All @@ -200,11 +204,6 @@ public function buildPartialOrMultipleCaptureData($payment, $currency, $adyenOrd

$request['body'] = $requestBody;
$request['clientConfig'] = ["storeId" => $payment->getOrder()->getStoreId()];
$request['headers'] = [
'idempotencyExtraData' => [
'totalInvoiced' => $payment->getOrder()->getTotalInvoiced() ?? 0
]
];

return $request;
}
Expand Down
53 changes: 53 additions & 0 deletions Gateway/Request/HeaderDataBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
*
* Adyen Payment module (https://www.adyen.com/)
*
* Copyright (c) 2024 Adyen MV (https://www.adyen.com/)
* See LICENSE.txt for license details.
*
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Gateway\Request;

use Adyen\Payment\Helper\Data;
use Magento\Payment\Gateway\Data\PaymentDataObject;
use Magento\Payment\Gateway\Helper\SubjectReader;
use Magento\Payment\Gateway\Request\BuilderInterface;

class HeaderDataBuilder implements BuilderInterface
{
const FRONTENDTYPE = 'frontendType';
const FRONTENDTYPE_HEADLESS = 'headless';

/**
* @var Data
*/
private Data $adyenHelper;

/**
* PaymentDataBuilder constructor.
*
* @param Data $adyenHelper
*/
public function __construct(
Data $adyenHelper
)
{
$this->adyenHelper = $adyenHelper;
}

/**
* @param array $buildSubject
* @return array
*/
public function build(array $buildSubject): array
{
/** @var PaymentDataObject $paymentDataObject */
$paymentDataObject = SubjectReader::readPayment($buildSubject);
$payment = $paymentDataObject->getPayment();
$headers = $this->adyenHelper->buildRequestHeaders($payment);
return ['headers' => $headers];
}
}
11 changes: 9 additions & 2 deletions Helper/Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Adyen\AdyenException;
use Adyen\Client;
use Adyen\Environment;
use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Service\Checkout;
use Adyen\Payment\Logger\AdyenLogger;
use Adyen\Payment\Model\Config\Source\RenderMode;
Expand Down Expand Up @@ -1167,16 +1168,22 @@ public function getMagentoDetails()
];
}

public function buildRequestHeaders()
public function buildRequestHeaders($payment = null)
{
$magentoDetails = $this->getMagentoDetails();
return [
$headers = [
'external-platform-name' => $magentoDetails['name'],
'external-platform-version' => $magentoDetails['version'],
'external-platform-edition' => $magentoDetails['edition'],
'merchant-application-name' => $this->getModuleName(),
'merchant-application-version' => $this->getModuleVersion()
];

if(isset($payment) && !is_null($payment->getAdditionalInformation(HeaderDataBuilder::FRONTENDTYPE))) {
$headers[HeaderDataBuilder::FRONTENDTYPE] = $payment->getAdditionalInformation(HeaderDataBuilder::FRONTENDTYPE);
}

return $headers;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion Observer/AdyenCcDataAssignObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Magento\Framework\Event\Observer;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface;
use Adyen\Payment\Gateway\Request\HeaderDataBuilder;

class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
{
Expand All @@ -44,7 +45,8 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
self::NUMBER_OF_INSTALLMENTS,
self::CC_TYPE,
self::RETURN_URL,
self::RECURRING_PROCESSING_MODEL
self::RECURRING_PROCESSING_MODEL,
HeaderDataBuilder::FRONTENDTYPE
];

/**
Expand Down
8 changes: 3 additions & 5 deletions Observer/AdyenPaymentMethodDataAssignObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Adyen\Payment\Observer;

use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Payment\Helper\StateData;
use Adyen\Payment\Helper\Util\CheckoutStateDataValidator;
use Adyen\Payment\Helper\Util\DataArrayValidator;
Expand All @@ -19,7 +20,6 @@
use Magento\Framework\Event\Observer;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface;
use Magento\Store\Model\StoreManagerInterface;

class AdyenPaymentMethodDataAssignObserver extends AbstractDataAssignObserver
{
Expand All @@ -38,26 +38,24 @@ class AdyenPaymentMethodDataAssignObserver extends AbstractDataAssignObserver
self::STATE_DATA,
self::RETURN_URL,
self::RECURRING_PROCESSING_MODEL,
self::CC_NUMBER
self::CC_NUMBER,
HeaderDataBuilder::FRONTENDTYPE
];

protected CheckoutStateDataValidator $checkoutStateDataValidator;
protected Collection $stateDataCollection;
private StateData $stateData;
private StoreManagerInterface $storeManager;
private Vault $vaultHelper;

public function __construct(
CheckoutStateDataValidator $checkoutStateDataValidator,
Collection $stateDataCollection,
StateData $stateData,
StoreManagerInterface $storeManager,
Vault $vaultHelper
) {
$this->checkoutStateDataValidator = $checkoutStateDataValidator;
$this->stateDataCollection = $stateDataCollection;
$this->stateData = $stateData;
$this->storeManager = $storeManager;
$this->vaultHelper = $vaultHelper;
}

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ bin/magento setup:upgrade
For more information see our [installation section](https://docs.adyen.com/developers/plugins/magento-2/set-up-the-plugin-in-magento?redirect#step1installtheplugin).

## Documentation
[Magento 2 documentation](https://docs.adyen.com/developers/plugins/magento-2)

- [Magento 2 documentation](https://docs.adyen.com/plugins/adobe-commerce)
- [V9 migration guide](https://docs.adyen.com/plugins/adobe-commerce/migrate-to-a-new-version)

## Setup Cron
Make sure that your Magento cron is running every minute. We are using a cronjob to process the notifications (our webhook service) and to update Adyen servers' IP addresses. The cronjobs will be executed every minute.
Expand Down
4 changes: 4 additions & 0 deletions Test/Unit/Gateway/Http/Client/TransactionPaymentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public function testRequestHeadersAreAddedToPaymentsCall()
->method('buildRequestHeaders')
->willReturn($expectedHeaders);

$actualHeaders = $this->adyenHelperMock->buildRequestHeaders();


$mockedPaymentResponse = [
'reference' => 'ABC12345',
'amount' => ['value' => 100],
Expand All @@ -161,5 +164,6 @@ public function testRequestHeadersAreAddedToPaymentsCall()

$this->assertArrayHasKey('resultCode', $response);
$this->assertEquals('Authorised', $response['resultCode']);
$this->assertEquals($expectedHeaders, $actualHeaders);
}
}
1 change: 0 additions & 1 deletion Test/Unit/Gateway/Request/CaptureDataBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ public function testBuildCaptureRequest($adyenOrderPayments, $fullAmountAuthoriz

$this->assertArrayHasKey('body', $request);
$this->assertArrayHasKey('clientConfig', $request);
$this->assertArrayHasKey('headers', $request);

if (count($adyenOrderPayments) > 1) {
$this->assertArrayHasKey(TransactionCapture::MULTIPLE_AUTHORIZATIONS, $request['body']);
Expand Down
67 changes: 67 additions & 0 deletions Test/Unit/Gateway/Request/HeaderDataBuilderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Adyen\Payment\Test\Unit\Gateway\Request;

use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Payment\Test\Unit\AbstractAdyenTestCase;
use Adyen\Payment\Helper\Data;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Payment\Gateway\Data\PaymentDataObject;
use Magento\Payment\Gateway\Helper\SubjectReader;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Invoice;
use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection as InvoiceCollection;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class HeaderDataBuilderTest extends AbstractAdyenTestCase
{
/**
* @var HeaderDataBuilder
*/
private $headerDataBuilder;

/**
* @var Data|MockObject
*/
private $adyenHelperMock;

protected function setUp(): void
{
$objectManager = new ObjectManager($this);

$this->adyenHelperMock = $this->getMockBuilder(Data::class)
->disableOriginalConstructor()
->getMock();

$this->headerDataBuilder = $objectManager->getObject(
HeaderDataBuilder::class,
[
'adyenHelper' => $this->adyenHelperMock
]
);
}

public function testBuild()
{
$paymentMock = $this->getMockBuilder(\Magento\Payment\Model\InfoInterface::class)
->getMock();
$paymentDataObjectMock = $this->createConfiguredMock(PaymentDataObject::class, [
'getPayment' => $paymentMock
]);

$buildSubject = ['payment' => $paymentDataObjectMock];

$headers = ['header1' => 'value1', 'header2' => 'value2'];

$this->adyenHelperMock->expects($this->once())
->method('buildRequestHeaders')
->with($paymentMock)
->willReturn($headers);

$result = $this->headerDataBuilder->build($buildSubject);

$this->assertArrayHasKey('headers', $result);
$this->assertEquals($headers, $result['headers']);
}
}
Loading
Loading