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, ' ')); } }