refactor: create AxeptaConfig class with tests
This commit is contained in:
parent
260ab791d8
commit
34237b9910
3 changed files with 173 additions and 39 deletions
35
app/Lib/Axepta/AxeptaConfig.php
Normal file
35
app/Lib/Axepta/AxeptaConfig.php
Normal 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
116
tests/Unit/Lib/Axepta/AxeptaConfigTest.php
Normal file
116
tests/Unit/Lib/Axepta/AxeptaConfigTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue