refactor: create AxeptaConfig class with tests

This commit is contained in:
Jeremy Munsch 2026-06-23 16:27:23 +02:00
parent 260ab791d8
commit 34237b9910
No known key found for this signature in database
GPG key ID: 7A502D8B9839C78C
3 changed files with 173 additions and 39 deletions

View file

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace App\Lib\Axepta;
final readonly class AxeptaConfig
{
public function __construct(
#[\SensitiveParameter]
public string $endpoint,
#[\SensitiveParameter]
public string $merchantId,
#[\SensitiveParameter]
public string $apiKey,
#[\SensitiveParameter]
public string $hmac,
/** @param array<string,mixed> $axeptaConfig */
#[\SensitiveParameter]
public array $checkoutConfig = []
) {
if (empty(trim($endpoint))) {
throw new \DomainException('Endpoint cannot be empty');
}
if (empty(trim($merchantId))) {
throw new \DomainException('Merchant ID cannot be empty');
}
if (empty(trim($apiKey))) {
throw new \DomainException('API Key cannot be empty');
}
if (empty(trim($hmac))) {
throw new \DomainException('HMAC cannot be empty');
}
}
}

View file

@ -21,15 +21,13 @@ class AxeptaPayment
/**
* Guzzle Client instance
*
* @var GuzzleHttp\Client
*/
private \GuzzleHttp\Client $client;
/**
* Additionnal or Update Axepta configuration
*
* @var array
* @var array<string,mixed>
*/
private array $axeptaCheckoutConfig;
@ -40,35 +38,12 @@ class AxeptaPayment
*/
private string $cacheKey = "AxeptaBearerToken";
/**
* Construct method
*
* @param string $endpoint Axepta Endpoint
* @param string $merchantId Axepta Merchant ID
* @param string $apiKey Axepta Secret API Key
* @param string $hmac Axepta HMAC
* @param array $axeptaConfig Additionnal or Update Axepta configuration
* @return void
*/
public function __construct(
private readonly LoggerInterface $logger,
#[\SensitiveParameter]
private string $endpoint,
#[\SensitiveParameter]
private string $merchantId,
#[\SensitiveParameter]
private string $apiKey,
#[\SensitiveParameter]
private string $hmac,
#[\SensitiveParameter]
private array $axeptaConfig = []
private readonly AxeptaConfig $axeptaConfig
) {
$this->endpoint = $endpoint;
$this->merchantId = $merchantId;
$this->apiKey = $apiKey;
$this->hmac = $hmac;
$this->client = new Client([
'base_uri' => $this->endpoint,
$this->client = new Client([
'base_uri' => $this->axeptaConfig->endpoint,
'timeout' => 5.0,
]);
$this->axeptaCheckoutConfig = [
@ -89,7 +64,7 @@ class AxeptaPayment
],
]
],
...$axeptaConfig
...$axeptaConfig->checkoutConfig
];
}
@ -110,8 +85,8 @@ class AxeptaPayment
$response = $this->client->post('/authorization/oauth/token', [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => $this->merchantId,
'client_secret' => $this->apiKey
'client_id' => $this->axeptaConfig->merchantId,
'client_secret' => $this->axeptaConfig->apiKey
]
]);
@ -145,8 +120,12 @@ class AxeptaPayment
* @return string
* @throws \RuntimeException
*/
public function getCheckoutUrl(AxeptaOrder $order, string $returnUrl, string $cancelUrl, string $webhookUrl): string
{
public function getCheckoutUrl(
#[\SensitiveParameter] AxeptaOrder $order,
#[\SensitiveParameter] string $returnUrl,
#[\SensitiveParameter] $cancelUrl,
#[\SensitiveParameter] string $webhookUrl
): string {
$payload = [
"transId" => $this->generateTransId(),
"urls" => [
@ -268,7 +247,8 @@ class AxeptaPayment
$rawPayload = $request->getContent(false);
$this->logger->debug(
'Received an IPN call', [
'Received an IPN call',
[
'request_signature_version' => $signatureVersion,
'request_signature' => $signature,
'request_timestamp' => $timestamp,
@ -347,8 +327,11 @@ class AxeptaPayment
* @param string $rawPayload
* @return boolean
*/
private function isValidSignature(string $signature, CarbonInterface $timestamp, string $rawPayload): bool
{
private function isValidSignature(
#[\SensitiveParameter] string $signature,
CarbonInterface $timestamp,
#[\SensitiveParameter] string $rawPayload
): bool {
$providedSignature = $this->extractSignatureFromCurrentVersion($signature);
if (!$providedSignature) {
@ -360,7 +343,7 @@ class AxeptaPayment
}
$signedPayload = "{$timestamp}.{$rawPayload}";
$expectedSignature = hash_hmac('sha256', $signedPayload, $this->hmac);
$expectedSignature = hash_hmac('sha256', $signedPayload, $this->axeptaConfig->hmac);
$signatureIsValid = hash_equals($expectedSignature, $providedSignature);
if (!$signatureIsValid) {
@ -386,7 +369,7 @@ class AxeptaPayment
* @param string $signature
* @return string|null
*/
private function extractSignatureFromCurrentVersion(string $signature): ?string
private function extractSignatureFromCurrentVersion(#[\SensitiveParameter] string $signature): ?string
{
$signatures = explode(',', $signature);
$filteredSignatures = array_filter($signatures, function (string $key) {

View file

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace Tests\Unit\Lib\Axepta;
use App\Lib\Axepta\AxeptaConfig;
use DomainException;
use Tests\TestCase;
class AxeptaConfigTest extends TestCase
{
public function testCanInstanciateAnAxeptaConfig(): void
{
// GIVEN
$endpoint = 'https://api.axepta.com';
$merchantId = 'M_123456';
$apiKey = 'secret_key_123';
$hmac = 'hmac_value_456';
// WHEN
$config = new AxeptaConfig(
$endpoint,
$merchantId,
$apiKey,
$hmac
);
// THEN
$this->assertInstanceOf(AxeptaConfig::class, $config);
}
public function testCannotInstanciateWithEmptyEndpoint(): void
{
$this->assertThrows(function () {
// GIVEN
$endpoint = '';
$merchantId = 'M_123';
$apiKey = 'key';
$hmac = 'hmac';
// WHEN
new AxeptaConfig(
$endpoint,
$merchantId,
$apiKey,
$hmac
);
// THEN
}, DomainException::class);
}
public function testCannotInstanciateWithEmptyMerchantId(): void
{
$this->assertThrows(function () {
// GIVEN
$endpoint = 'https://api.axepta.com';
$merchantId = '';
$apiKey = 'key';
$hmac = 'hmac';
// WHEN
new AxeptaConfig(
$endpoint,
$merchantId,
$apiKey,
$hmac
);
// THEN
}, DomainException::class);
}
public function testCannotInstanciateWithEmptyApiKey(): void
{
$this->assertThrows(function () {
// GIVEN
$endpoint = 'https://api.axepta.com';
$merchantId = 'M_123';
$apiKey = '';
$hmac = 'hmac';
// WHEN
new AxeptaConfig(
$endpoint,
$merchantId,
$apiKey,
$hmac
);
// THEN
}, DomainException::class);
}
public function testCannotInstanciateWithEmptyHmac(): void
{
$this->assertThrows(function () {
// GIVEN
$endpoint = 'https://api.axepta.com';
$merchantId = 'M_123';
$apiKey = 'key';
$hmac = '';
// WHEN
new AxeptaConfig(
$endpoint,
$merchantId,
$apiKey,
$hmac
);
// THEN
}, DomainException::class);
}
}