|
|
@@ -26,6 +26,7 @@ class Klarna extends Payment
|
|
|
protected $currentInput;
|
|
|
protected $createSessionUlr = 'https://api-na.playground.klarna.com/payments/v1/sessions';
|
|
|
protected $createOrderUlr = 'https://api-na.playground.klarna.com/payments/v1/authorizations/{authorizationToken}/order';
|
|
|
+ protected $getOrderUlr = 'https://api-na.playground.klarna.com/ordermanagement/v1/orders/{order_id}';
|
|
|
|
|
|
public function __construct(
|
|
|
protected InvoiceRepository $invoiceRepository,
|
|
|
@@ -35,6 +36,7 @@ class Klarna extends Payment
|
|
|
if ($this->getConfigData('mode') == 'live') {
|
|
|
$this->createSessionUlr = 'https://api.klarna.com/payments/v1/sessions';
|
|
|
$this->createOrderUlr = 'https://api.klarna.com/payments/v1/authorizations/{authorizationToken}/order';
|
|
|
+ $this->getOrderUlr = 'https://api.klarna.com/ordermanagement/v1/orders/{order_id}';
|
|
|
}
|
|
|
$this->clientId = $this->getConfigData('client_id');
|
|
|
$this->apikey = $this->getConfigData('secret_id');
|
|
|
@@ -134,7 +136,16 @@ class Klarna extends Payment
|
|
|
if (empty($resultObject->client_token)) {
|
|
|
throw new \Exception('klarna api is error');
|
|
|
}
|
|
|
- return $resultObject->client_token;
|
|
|
+ // 生成 verify_token 并存入 order payment additional
|
|
|
+ $verifyToken = bin2hex(random_bytes(32));
|
|
|
+ if ($order->payment) {
|
|
|
+ $additional = $order->payment->additional ?? [];
|
|
|
+ $additional['klarna_verify_token'] = $verifyToken;
|
|
|
+ $additional['klarna_session_id'] = $resultObject->session_id ?? null;
|
|
|
+ $order->payment->additional = $additional;
|
|
|
+ $order->payment->save();
|
|
|
+ }
|
|
|
+ return $resultObject->client_token . '|' . $verifyToken;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -164,6 +175,12 @@ class Klarna extends Payment
|
|
|
if ($order->status != Order::STATUS_PENDING) {
|
|
|
return new \Exception('order status is error');
|
|
|
}
|
|
|
+ $input = $this->getInput();
|
|
|
+ $verifyToken = $input->verifyToken ?? null;
|
|
|
+ $storedToken = $order->payment->additional['klarna_verify_token'] ?? null;
|
|
|
+ if (!$verifyToken || !$storedToken || !hash_equals($storedToken, $verifyToken)) {
|
|
|
+ throw new \Exception('klarna verify token is invalid');
|
|
|
+ }
|
|
|
return $this->createOrder($order, $authorizationToken);
|
|
|
}
|
|
|
|
|
|
@@ -222,6 +239,42 @@ class Klarna extends Payment
|
|
|
throw new \Exception('klarna Create an order is error');
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public function fetchOrderStatus($gatewayOrderId = null)
|
|
|
+ {
|
|
|
+ $order = $this->getOrder();
|
|
|
+ if ($order) {
|
|
|
+ $gatewayOrderId = $order->payment->additional['transaction_id'];
|
|
|
+ }
|
|
|
+ if (empty($gatewayOrderId)) {
|
|
|
+ return new \Exception('OrderId is empty');
|
|
|
+ }
|
|
|
+ $client = new Client();
|
|
|
+ $response = $client->request('GET', str_replace('{order_id}', $gatewayOrderId, $this->getOrderUlr), [
|
|
|
+ 'headers' => [
|
|
|
+ 'Accept' => 'application/json',
|
|
|
+ 'Content-Type' => 'application/json',
|
|
|
+ 'Authorization' => 'Basic ' . base64_encode("{$this->clientId}:{$this->apikey}")
|
|
|
+ ],
|
|
|
+ 'timeout' => 30,
|
|
|
+ 'verify' => false,
|
|
|
+ ]);
|
|
|
+ $responseBody = $response->getBody()->getContents();
|
|
|
+ Log::channel('payment')->info("klarna fetchOrderStatus response", [
|
|
|
+ 'gatewayOrderId' => $gatewayOrderId,
|
|
|
+ 'status' => $response->getStatusCode(),
|
|
|
+ 'body' => $responseBody
|
|
|
+ ]);
|
|
|
+ $resultObject = json_decode($responseBody);
|
|
|
+ $paymentStatus = [];
|
|
|
+ $paymentStatus['captures'] = null;
|
|
|
+ $paymentStatus['status'] = null;
|
|
|
+ if ($resultObject->fraud_status == 'ACCEPTED' && $resultObject->status == 'AUTHORIZED') {
|
|
|
+ $paymentStatus['captures'] = true;
|
|
|
+ $paymentStatus['status'] = 'COMPLETED';
|
|
|
+ }
|
|
|
+ return $paymentStatus;
|
|
|
+ }
|
|
|
/**
|
|
|
* Get payment method image.
|
|
|
*
|