PHP Amazon Pay V2 SDK调用CompleteCheckoutSession报错解决方案
错误核心原因
你遇到的InvalidCheckoutSessionStatus错误是调用completeCheckoutSession的时机不符合Checkout Session的状态流转要求:只有用户在Amazon支付侧完成授权操作、Checkout Session状态变为Approved后,才允许调用该方法。你当前在updateCheckoutSession执行完成后直接调用completeCheckoutSession,跳过了用户跳转授权的步骤,因此触发状态错误。
代码存在的具体问题
- 没有处理
updateCheckoutSession的返回结果,没有跳转至Amazon支付页让用户完成授权 - 未校验Checkout Session状态就直接调用
completeCheckoutSession - 没有在指定的
checkoutResultReturnUrl回调逻辑中处理后续流程
正确实现步骤
1. 修改updateCheckoutSession后的逻辑
执行完更新会话操作后,提取返回结果中的Amazon支付跳转链接,引导用户完成授权:
$payload = array( 'webCheckoutDetails' => array( "checkoutResultReturnUrl" => HTTPS_SERVER . "index.php?route=payment/amazon/returnURL" ), 'paymentDetails' => array( 'paymentIntent' => 'Authorize', 'canHandlePendingAuthorization' => false, 'chargeAmount' => array( 'amount' => (int)$total_amount, 'currencyCode' => 'JPY' ), ), 'merchantMetadata' => array( 'merchantReferenceId' => $order_id, 'merchantStoreName' => 'MWYW Online Store', 'noteToBuyer' => 'Thank you for your order!' ) ); try { $client = new Amazon\Pay\API\Client($amazonpay_config); $result = $client->updateCheckoutSession($checkoutSessionId, $payload); $response = json_decode($result['response'], true); // 状态正常则跳转至Amazon支付页 if ($result['status'] === 200 && isset($response['webCheckoutDetails']['amazonPayRedirectUrl'])) { header('Location: ' . $response['webCheckoutDetails']['amazonPayRedirectUrl']); exit; } } catch (\Exception $e) { // 异常处理逻辑 }
2. 在returnURL回调逻辑中获取chargeID
在你配置的payment/amazon/returnURL路由对应的处理方法中,先校验Checkout Session状态,再调用completeCheckoutSession获取chargeID:
// 回调页逻辑 $checkoutSessionId = $_GET['checkoutSessionId']; $total_amount = ''; // 从你的订单系统中读取对应金额 $amazonpay_config = []; // 加载你的Amazon Pay配置 try { $client = new Amazon\Pay\API\Client($amazonpay_config); // 先获取会话状态 $getResult = $client->getCheckoutSession($checkoutSessionId); $getResponse = json_decode($getResult['response'], true); if ($getResult['status'] === 200 && $getResponse['statusDetails']['state'] === 'Approved') { // 状态符合要求,调用complete方法 $completePayload = [ 'chargeAmount' => [ 'amount' => (int)$total_amount, 'currencyCode' => 'JPY' ] ]; $completeResult = $client->completeCheckoutSession($checkoutSessionId, $completePayload); $completeResponse = json_decode($completeResult['response'], true); if ($completeResult['status'] === 200) { // 成功获取chargeID $chargeId = $completeResponse['chargeId']; // 后续处理你的订单状态更新、发货逻辑 } } else { // 处理用户取消支付、授权失败的逻辑 } } catch (\Exception $e) { // 异常处理逻辑 }
注意事项
- 调用
completeCheckoutSession前必须先校验会话状态为Approved,否则始终会触发状态错误 - 金额数值需要符合对应币种的精度要求,日元不需要小数位,你当前用int类型传值符合要求
- 如果paymentIntent设置为
AuthorizeWithCapture,调用complete方法后会自动执行扣款,不需要额外调用Capture接口
内容的提问来源于stack exchange,提问作者Chhorn Soro
相关产品推荐
相关产品推荐

