axeptaCheckoutConfig = [ ...[ 'language' => 'fr', 'amount' => ['currency' => 'EUR'], 'captureMethod' => ['type' => 'AUTOMATIC'], 'allowedPaymentMethods' => ['CARD'], 'paymentMethods' => [ 'card' => ['subType' => ['VISA', 'MASTERCARD']], ], ], ...$axeptaConfig->checkoutConfig, ]; } public function getCheckoutUrl( #[\SensitiveParameter] AxeptaOrder $order, #[\SensitiveParameter] string $returnUrl, #[\SensitiveParameter] string $cancelUrl, #[\SensitiveParameter] string $webhookUrl ): string { $payload = [ 'transId' => $this->generateTransId(), 'urls' => ['return' => $returnUrl, 'cancel' => $cancelUrl, 'webhook' => $webhookUrl], 'amount' => ['value' => $order->amount], 'order' => ['merchantReference' => $order->reference, 'creationDate' => gmdate('c')], 'customerInfo' => ['email' => $order->customerEmail], ]; try { $token = $this->tokenManager->getToken(); $response = $this->gateway->post( '/api/v2/payments/sessions', array_merge_recursive($payload, $this->axeptaCheckoutConfig), $token ); if ($response->getStatusCode() !== 202) { throw new \RuntimeException('Session creation failed'); } $responseBody = json_decode($response->getBody()->getContents()); if (! isset($responseBody->_links->redirect->href)) { throw new \RuntimeException('Missing redirect URL in response'); } return $responseBody->_links->redirect->href; } catch (RequestException $e) { throw new \RuntimeException('Payment session error: ' . $e->getMessage(), 0, $e); } } public function isValidWebhookAccess(Request $request): bool { $signatureVersion = $this->getHeaderValue($request, 'x-paygate-signature-version'); $signature = $this->getHeaderValue($request, 'x-paygate-signature'); $timestamp = $this->getHeaderValue($request, 'x-paygate-timestamp'); $rawPayload = $request->getContent(false); $this->logger->debug('Received an IPN call', [ 'request_signature_version' => $signatureVersion, 'request_signature' => $signature, 'request_timestamp' => $timestamp, 'request_payload' => base64_encode($rawPayload), ]); return $this->signatureVerifier->verify($signatureVersion, $signature, $timestamp, $rawPayload); } public function getPaymentStatusById(string $paymentId): ?string { try { $token = $this->tokenManager->getToken(); $response = $this->gateway->get(sprintf('/api/v2/payments/getByPayId/%s', $paymentId), $token); $responseBody = json_decode($response->getBody()->getContents()); return $responseBody->responseCode ?? null; } catch (RequestException $e) { if ($e->hasResponse()) { $responseBody = json_decode($e->getResponse()->getBody()->getContents()); return $responseBody->responseCode ?? null; } return null; } } private function generateTransId(): string { return Str::uuid7()->toString(); } private function getHeaderValue(Request $request, string $headerName): string { $headerValue = Arr::wrap($request->header($headerName)); $headerValue = Arr::map($headerValue, fn ($v) => is_scalar($v) ? strval($v) : ''); return Str::trim(Arr::join($headerValue, ' ')); } }