Laravel与Vue.js集成Amazon支付:CheckoutSession完成报错求助
解决Amazon Pay
completeCheckoutSession 422状态错误 错误原因
这个InvalidCheckoutSessionStatus错误的核心是:你要执行的「完成结账会话」操作,不符合当前结账会话的状态规则。Amazon Pay的结账会话有严格的状态流转逻辑,比如会话可能已完成、取消、过期,或者还没走到允许调用completeCheckoutSession的阶段(比如用户未完成支付授权)。
排查与修复步骤
1. 先确认会话当前状态
在调用completeCheckoutSession之前,先调用Amazon Pay的getCheckoutSession接口获取会话状态,只有状态为Open且用户已完成授权时,才能执行完成操作。
给代码增加状态检查:
// 调用complete前先获取会话详情 $sessionResult = $client->getCheckoutSession($checkoutSessionId); if ($sessionResult['status'] === 200) { $sessionData = json_decode($sessionResult['response'], true); // 仅当会话状态为Open时继续执行 if ($sessionData['status'] !== 'Open') { return response()->json([ 'error' => '当前会话状态不允许完成操作,状态:'.$sessionData['status'] ], 422); } } else { return response()->json(['error' => '获取会话信息失败'], $sessionResult['status']); }
2. 检查流程是否符合Amazon Pay规范
Amazon Pay的标准流程是:
- 创建结账会话(
createCheckoutSession) - 用户跳转至Amazon Pay页面完成身份验证与授权
- 后端收到Amazon的回调通知,确认会话状态更新为
Open - 调用
completeCheckoutSession完成支付
如果跳过用户授权步骤,或者还没收到会话状态更新的回调就直接调用complete,必然触发这个错误。请确认前端是否引导用户完成了Amazon的授权跳转,后端是否正确处理了回调。
3. 修正配置与参数不匹配问题
你的区域配置为UK,但货币代码用的是USD,这会导致会话状态异常。UK区域对应的货币应为GBP,修改payload中的货币代码:
$payload = array( "chargeAmount" => array( "amount" => "100", "currencyCode"=> "GBP" // 修正为UK区域对应货币 ), );
同时确认checkoutSessionId是有效、未过期的会话ID,避免使用已失效的ID调用接口。
4. 排查沙箱会话过期问题
沙箱环境的结账会话有过期时间,若创建会话后长时间未操作,会话会自动过期。确保你使用的是近期创建、且用户已完成授权的会话ID。
代码优化示例
将直接echo的错误处理改为Laravel标准的JSON响应,方便前端接收处理:
public function completeCheckout(Request $request){ $amazonpay_config = array( 'public_key_id' => config('amazonkey.public_key_id'), 'private_key' => config('amazonkey.private_key'), 'region' => 'UK', 'sandbox' => true ); $payload = array( "chargeAmount" => array( "amount" => "100", "currencyCode"=> "GBP" ), ); $payload = json_encode($payload); try { $checkoutSessionId = $request->checkoutSessionId; $client = new ApayAPI($amazonpay_config); // 检查会话状态 $sessionResult = $client->getCheckoutSession($checkoutSessionId); if ($sessionResult['status'] !== 200) { return response()->json(['error' => '获取会话信息失败'], $sessionResult['status']); } $sessionData = json_decode($sessionResult['response'], true); if ($sessionData['status'] !== 'Open') { return response()->json([ 'error' => '无法完成结账,会话当前状态:'.$sessionData['status'] ], 422); } // 执行完成操作 $result = $client->completeCheckoutSession($checkoutSessionId, $payload); if ($result['status'] === 200) { $response = json_decode($result['response'], true); return response()->json($response); } else { $errorData = json_decode($result['response'], true); return response()->json($errorData, $result['status']); } } catch (\Exception $e) { return response()->json(['error' => $e->getMessage()], 500); } }
内容的提问来源于stack exchange,提问作者Sufyan
相关产品推荐
相关产品推荐

