Skip to content

Commit

Permalink
Merge branch 'main' into ECP-9177
Browse files Browse the repository at this point in the history
  • Loading branch information
candemiralp authored Dec 27, 2024
2 parents 1e81dcf + 3ab803c commit aa0d6ea
Show file tree
Hide file tree
Showing 17 changed files with 207 additions and 44 deletions.
2 changes: 1 addition & 1 deletion Gateway/Http/Client/TransactionCancel.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ 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, '/cancels');
$request['applicationInfo'] = $this->adyenHelper->buildApplicationInfo($client);
$paymentCancelRequest = new PaymentCancelRequest($request);
Expand Down
6 changes: 4 additions & 2 deletions Gateway/Http/Client/TransactionCapture.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ public function placeRequest(TransferInterface $transferObject): array
{
$request = $transferObject->getBody();
$headers = $transferObject->getHeaders();
$idempotencyKeyExtraData = $headers['idempotencyExtraData'];
unset($headers['idempotencyExtraData']);
$clientConfig = $transferObject->getClientConfig();

$client = $this->adyenHelper->initializeAdyenClientWithClientConfig($clientConfig);
$service = $this->adyenHelper->initializeModificationsApi($client);

$requestOptions['headers'] = $this->adyenHelper->buildRequestHeaders();
$requestOptions['headers'] = $headers;
$request['applicationInfo'] = $this->adyenHelper->buildApplicationInfo($client);

if (array_key_exists(self::MULTIPLE_AUTHORIZATIONS, $request)) {
Expand All @@ -86,7 +88,7 @@ public function placeRequest(TransferInterface $transferObject): array

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

Expand Down
8 changes: 5 additions & 3 deletions Gateway/Http/Client/TransactionPaymentLinks.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ public function placeRequest(TransferInterface $transferObject): array
{
$request = $transferObject->getBody();
$headers = $transferObject->getHeaders();
$idempotencyKeyExtraData = $headers['idempotencyExtraData'] ?? null;
unset($headers['idempotencyExtraData']);
$clientConfig = $transferObject->getClientConfig();

$client = $this->adyenHelper->initializeAdyenClientWithClientConfig($clientConfig);
$service = new PaymentLinksApi($client);
$service = $this->adyenHelper->initializePaymentLinksApi($client);

// If the payment links call is already done return the request
if (!empty($request['resultCode'])) {
Expand All @@ -68,11 +70,11 @@ public function placeRequest(TransferInterface $transferObject): array

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

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

$this->adyenHelper->logRequest($request, Client::API_CHECKOUT_VERSION, '/paymentLinks');
Expand Down
7 changes: 5 additions & 2 deletions Gateway/Http/Client/TransactionRefund.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public function placeRequest(TransferInterface $transferObject): array
{
$requests = $transferObject->getBody();
$headers = $transferObject->getHeaders();
$idempotencyKeyExtraData = $headers['idempotencyExtraData'];
unset($headers['idempotencyExtraData']);
$clientConfig = $transferObject->getClientConfig();

$client = $this->adyenHelper->initializeAdyenClientWithClientConfig($clientConfig);
Expand All @@ -66,10 +68,11 @@ public function placeRequest(TransferInterface $transferObject): array
$responseData = [];
$idempotencyKey = $this->idempotencyHelper->generateIdempotencyKey(
$request,
$headers['idempotencyExtraData'] ?? null
$idempotencyKeyExtraData ?? null
);
$requestOptions['idempotencyKey'] = $idempotencyKey;
$requestOptions['headers'] = $this->adyenHelper->buildRequestHeaders();
$requestOptions['headers'] = $headers;

$this->adyenHelper->logRequest($request, Client::API_CHECKOUT_VERSION, '/refunds');
$request['applicationInfo'] = $this->adyenHelper->buildApplicationInfo($client);
$paymentRefundRequest = new PaymentRefundRequest($request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@
* Author: Adyen <magento@adyen.com>
*/

namespace Adyen\Payment\Gateway\Request;
namespace Adyen\Payment\Gateway\Request\Header;

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
class HeaderDataBuilder implements BuilderInterface, HeaderDataBuilderInterface
{
const FRONTENDTYPE = 'external-platform-frontendtype';
const FRONTENDTYPE_HEADLESS = 'headless';

/**
* @var Data
*/
Expand Down
15 changes: 15 additions & 0 deletions Gateway/Request/Header/HeaderDataBuilderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Adyen\Payment\Gateway\Request\Header;

interface HeaderDataBuilderInterface
{
const EXTERNAL_PLATFORM_NAME = 'external-platform-name';
const EXTERNAL_PLATFORM_VERSION = 'external-platform-version';
const EXTERNAL_PLATFORM_EDITION = 'external-platform-edition';
const EXTERNAL_PLATFORM_FRONTEND_TYPE = 'external-platform-frontendtype';
const MERCHANT_APPLICATION_NAME = 'merchant-application-name';
const MERCHANT_APPLICATION_VERSION = 'merchant-application-version';

const ADDITIONAL_DATA_FRONTEND_TYPE_KEY = 'frontendType';
}
24 changes: 15 additions & 9 deletions Helper/Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
use Adyen\Model\Checkout\ApplicationInfo;
use Adyen\Model\Checkout\CommonField;
use Adyen\Model\Checkout\UtilityRequest;
use Adyen\Payment\Gateway\Request\Header\HeaderDataBuilderInterface;
use Adyen\Payment\Helper\Config as ConfigHelper;
use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Service\Checkout;
use Adyen\Payment\Logger\AdyenLogger;
use Adyen\Payment\Model\Config\Source\RenderMode;
Expand All @@ -27,6 +27,7 @@
use Adyen\Payment\Observer\AdyenPaymentMethodDataAssignObserver;
use Adyen\Service\Checkout\ModificationsApi;
use Adyen\Service\Checkout\OrdersApi;
use Adyen\Service\Checkout\PaymentLinksApi;
use Adyen\Service\Checkout\PaymentsApi;
use Adyen\Service\Checkout\UtilityApi;
use Adyen\Service\PosPayment;
Expand Down Expand Up @@ -1173,16 +1174,16 @@ public function buildRequestHeaders($payment = null)
{
$magentoDetails = $this->getMagentoDetails();
$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()
HeaderDataBuilderInterface::EXTERNAL_PLATFORM_NAME => $magentoDetails['name'],
HeaderDataBuilderInterface::EXTERNAL_PLATFORM_VERSION => $magentoDetails['version'],
HeaderDataBuilderInterface::EXTERNAL_PLATFORM_EDITION => $magentoDetails['edition'],
HeaderDataBuilderInterface::MERCHANT_APPLICATION_NAME => $this->getModuleName(),
HeaderDataBuilderInterface::MERCHANT_APPLICATION_VERSION => $this->getModuleVersion()
];

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

return $headers;
Expand Down Expand Up @@ -1248,6 +1249,11 @@ public function initializeOrdersApi(Client $client): OrdersApi
return new OrdersApi($client);
}

public function initializePaymentLinksApi(Client $client):PaymentLinksApi
{
return new PaymentLinksApi($client);
}

/**
* @param Client $client
* @return PosPayment
Expand Down
4 changes: 2 additions & 2 deletions Observer/AdyenCcDataAssignObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use Magento\Framework\Event\Observer;
use Magento\Payment\Observer\AbstractDataAssignObserver;
use Magento\Quote\Api\Data\PaymentInterface;
use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Payment\Gateway\Request\Header\HeaderDataBuilderInterface;

class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
{
Expand All @@ -46,7 +46,7 @@ class AdyenCcDataAssignObserver extends AbstractDataAssignObserver
self::CC_TYPE,
self::RETURN_URL,
self::RECURRING_PROCESSING_MODEL,
HeaderDataBuilder::FRONTENDTYPE
HeaderDataBuilderInterface::ADDITIONAL_DATA_FRONTEND_TYPE_KEY
];

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

namespace Adyen\Payment\Observer;

use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Payment\Gateway\Request\Header\HeaderDataBuilderInterface;
use Adyen\Payment\Helper\StateData;
use Adyen\Payment\Helper\Util\CheckoutStateDataValidator;
use Adyen\Payment\Helper\Util\DataArrayValidator;
Expand Down Expand Up @@ -39,7 +39,7 @@ class AdyenPaymentMethodDataAssignObserver extends AbstractDataAssignObserver
self::RETURN_URL,
self::RECURRING_PROCESSING_MODEL,
self::CC_NUMBER,
HeaderDataBuilder::FRONTENDTYPE
HeaderDataBuilderInterface::ADDITIONAL_DATA_FRONTEND_TYPE_KEY
];

protected CheckoutStateDataValidator $checkoutStateDataValidator;
Expand Down
120 changes: 120 additions & 0 deletions Test/Unit/Gateway/Http/Client/TransactionPaymentLinksTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace Adyen\Payment\Test\Unit\Gateway\Http\Client;

use Adyen\AdyenException;
use Adyen\Model\Checkout\ApplicationInfo;
use Adyen\Model\Checkout\PaymentLinkRequest;
use Adyen\Model\Checkout\PaymentLinkResponse;
use Adyen\Payment\Gateway\Http\Client\TransactionPaymentLinks;
use Adyen\Payment\Helper\Data;
use Adyen\Payment\Helper\Idempotency;
use Adyen\Payment\Test\Unit\AbstractAdyenTestCase;
use Adyen\Client;
use Adyen\Service\Checkout\PaymentLinksApi;
use Magento\Payment\Gateway\Http\TransferInterface;

class TransactionPaymentLinksTest extends AbstractAdyenTestCase
{
private $clientMock;
private $adyenHelperMock;
private $idempotencyHelperMock;
private $transferObjectMock;
private $transactionPaymentLinks;
private $paymentLinksApiMock;

protected function setUp(): void
{
$this->adyenHelperMock = $this->createMock(Data::class);
$this->idempotencyHelperMock = $this->createMock(Idempotency::class);
$this->transferObjectMock = $this->createMock(TransferInterface::class);
$this->applicationInfoMock = $this->createMock(ApplicationInfo::class);
$this->adyenHelperMock->method('buildApplicationInfo')->willReturn($this->applicationInfoMock);
$this->transferObjectMock->method('getClientConfig')->willReturn([]);
$this->clientMock = $this->createMock(Client::class);
$this->adyenHelperMock->method('initializeAdyenClientWithClientConfig')->willReturn($this->clientMock);
$this->paymentLinksApiMock = $this->createMock(PaymentLinksApi::class);
$this->adyenHelperMock
->method('initializePaymentLinksApi')
->with($this->clientMock)
->willReturn($this->paymentLinksApiMock);

$this->transactionPaymentLinks = new TransactionPaymentLinks(
$this->adyenHelperMock,
$this->idempotencyHelperMock
);
}

public function testSuccessfulPlaceRequest()
{
$requestBody = [
'allowedPaymentMethods' => ['ideal','giropay'],
'amount' => ['value' => 1000, 'currency' => 'EUR'],
'applicationInfo' => $this->applicationInfoMock
];

$headers = [ 'idempotencyExtraData' => [], 'header' => 'some-data'];
$idempotencyKey = 'generated_idempotency_key';

$this->transferObjectMock->method('getBody')->willReturn($requestBody);
$this->transferObjectMock->method('getHeaders')->willReturn($headers);

$this->idempotencyHelperMock->expects($this->once())
->method('generateIdempotencyKey')
->with($requestBody, $headers['idempotencyExtraData'])
->willReturn('generated_idempotency_key');

$this->paymentLinksApiMock->expects($this->once())
->method('paymentLinks')
->with(
$this->callback(function (PaymentLinkRequest $paymentLinkRequest) use ($requestBody) {
$amount = $paymentLinkRequest->getAmount();
$this->assertEquals($amount, ['value' => 1000, 'currency' => 'EUR']);
$allowedPaymentMethods = $paymentLinkRequest->getAllowedPaymentMethods();
$this->assertEquals($allowedPaymentMethods, ['ideal', 'giropay']);
return true;
}),
$this->callback(function ($requestOptions) use ($idempotencyKey, $headers) {
$this->assertArrayHasKey('idempotencyKey', $requestOptions);
$this->assertArrayHasKey('headers', $requestOptions);
$this->assertEquals($idempotencyKey, $requestOptions['idempotencyKey']);
$this->assertEquals(['header' => 'some-data'], $requestOptions['headers']);
return true;
})
)->willReturn(new PaymentLinkResponse(['url' => 'https://paymentlink.com']));

$response = $this->transactionPaymentLinks->placeRequest($this->transferObjectMock);
$this->assertIsArray($response);
$this->assertArrayHasKey('url', $response);
}

public function testRequestWithAdyenException()
{
$requestBody = [
'amount' => ['currency' => 'EUR', 'value' => 1000],
'merchantAccount' => 'TestMerchant',
'reference' => 'TestReference',
];
$this->transferObjectMock->method('getBody')->willReturn($requestBody);
$this->transferObjectMock->method('getHeaders')->willReturn([]);
$this->transferObjectMock->method('getClientConfig')->willReturn([]);

$this->paymentLinksApiMock
->method('paymentLinks')
->willThrowException(new AdyenException());

$response = $this->transactionPaymentLinks->placeRequest($this->transferObjectMock);

$this->assertArrayHasKey('error', $response);
}

public function testRequestWithResultCodePresent()
{
$requestBody = ['resultCode' => 'Authorised'];
$this->transferObjectMock->method('getBody')->willReturn($requestBody);

$response = $this->transactionPaymentLinks->placeRequest($this->transferObjectMock);
$this->assertEquals($requestBody, $response);
}

}
2 changes: 0 additions & 2 deletions Test/Unit/Gateway/Http/Client/TransactionRefundTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ public function testPlaceRequestIncludesHeadersInRequest()

$this->adyenHelperMock->method('initializeAdyenClientWithClientConfig')->willReturn($adyenClientMock);
$this->adyenHelperMock->method('initializeModificationsApi')->willReturn($serviceMock);
$this->adyenHelperMock->method('buildRequestHeaders')->willReturn(['custom-header' => 'value']);

$this->idempotencyHelperMock->expects($this->once())
->method('generateIdempotencyKey')
Expand All @@ -91,7 +90,6 @@ public function testPlaceRequestIncludesHeadersInRequest()
$this->assertArrayHasKey('idempotencyKey', $requestOptions);
$this->assertArrayHasKey('headers', $requestOptions);
$this->assertEquals('generated_idempotency_key', $requestOptions['idempotencyKey']);
$this->assertArrayHasKey('custom-header', $requestOptions['headers']);
return true;
})
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

use Adyen\Payment\Gateway\Request\HeaderDataBuilder;
use Adyen\Payment\Gateway\Request\Header\HeaderDataBuilder;
use Adyen\Payment\Test\Unit\AbstractAdyenTestCase;
use Adyen\Payment\Helper\Data;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
Expand Down
Loading

0 comments on commit aa0d6ea

Please sign in to comment.