PayPal支付完成返回本地环境时出现UNPROCESSABLE_ENTITY错误
PayPal支付返回UNPROCESSABLE_ENTITY错误排查
错误场景与详情
在本地开发环境完成PayPal支付后返回系统时,触发UNPROCESSABLE_ENTITY错误,错误输出如下:
array:1 [▼ // app/Http/Controllers/ParentPaypalController.php:101 "error" => array:5 [▼ "name" => "UNPROCESSABLE_ENTITY" "details" => array:1 [▶] "message" => "The requested action could not be performed, semantically incorrect, or failed business validation." "debug_id" => "f287683883b27" "links" => array:1 [▼ 0 => array:3 [▶] ] ] ]
支付请求生成代码
Laravel控制器中生成PayPal支付订单的代码:
$provider = new PayPalClient; $provider->setApiCredentials(config('paypal')); $provider->getAccessToken(); $response = $provider->createOrder([ "intent" => "CAPTURE", "application_context" => [ "return_url" => route('paypal.thank_you', $parentInvoice->id), "cancel_url" => route('paypal.cancel', $parentInvoice->id), ], "purchase_units" => [ 0 => [ "reference_id" => $parentInvoice->id, "amount" => [ "currency_code" => "EUR", "value" => $membership->amount ] ] ] ]); if (isset($response['id']) & $response['id'] != null) { foreach ($response['links'] as $links) { if ($links['rel'] == 'approve') { return redirect()->away($links['href']); } } return redirect() ->route('paypal.cancel') ->with('error', 'Something went wrong.'); } else { return redirect() ->route('paypal.cancel') ->with('error', $response['message'] ?? 'Something went wrong.'); }
请求体与跳转前响应
请求体
[ "intent" => "CAPTURE", "application_context" => [ "return_url" => "http://paypal_demo.test/paypal_pay_card/thank_you/9cb73566-b2e3-499b-adf2-fa3382987033", "cancel_url" => "http://paypal_demo.test/paypal_pay_card/cancel/9cb73566-b2e3-499b-adf2-fa3382987033" ], "purchase_units" => [ 0 => [ "reference_id" => "9cb73566-b2e3-499b-adf2-fa3382987033", "amount" => [ "currency_code" => "EUR", "value" => "20.00" ] ] ] ]
跳转至PayPal前的响应
"id" => "45R71510DA8720826", "status" => "CREATED", "links" => array:4 [▼ 0 => array:3 [▼ "href" => "https://api.sandbox.paypal.com/v2/checkout/orders/45R71510DA8720826", "rel" => "self", "method" => "GET" ], 1 => array:3 [▼ "href" => "https://www.sandbox.paypal.com/checkoutnow?token=45R71510DA8720826", "rel" => "approve", "method" => "GET" ], 2 => array:3 [▼ "href" => "https://api.sandbox.paypal.com/v2/checkout/orders/45R71510DA8720826", "rel" => "update", "method" => "PATCH" ], 3 => array:3 [▼ "href" => "https://api.sandbox.paypal.com/v2/checkout/orders/45R71510DA8720826/capture", "rel" => "capture", "method" => "POST" ] ]
排查原因及解决方案
本地域名无法被PayPal访问
PayPal沙盒环境要求return_url和cancel_url必须是公网可访问的地址,本地自定义域名(如paypal_demo.test)无法被PayPal服务器回调,触发验证失败。
解决:用ngrok将本地服务映射为公网HTTPS地址,替换路由生成的URL为公网地址。缺少订单捕获逻辑
当前代码仅完成订单创建和授权跳转,但用户支付完成返回后,未调用PayPal的订单捕获API,导致订单状态未完成,触发业务验证错误。
解决:在paypal.thank_you对应的控制器方法中添加捕获逻辑:
$provider = new PayPalClient; $provider->setApiCredentials(config('paypal')); $provider->getAccessToken(); $orderToken = request()->get('token'); $captureResponse = $provider->captureOrder($orderToken); if ($captureResponse['status'] === 'COMPLETED') { // 执行支付成功后的逻辑,如更新订单状态、通知用户等 } else { // 处理支付失败情况,跳转至错误页面 return redirect()->route('paypal.cancel')->with('error', 'Payment capture failed.'); }
金额或货币格式问题
若商家沙盒账户不支持EUR货币,或金额格式不符合PayPal要求(如未保留两位小数),会触发业务验证错误。
解决:确保沙盒商家账户启用EUR货币;格式化金额为两位小数,示例:number_format($membership->amount, 2)。订单重复处理或过期
同一订单ID被多次捕获,或订单创建后超过3小时有效期,会触发错误。
解决:在数据库中记录PayPal订单ID和状态,避免重复处理;引导用户在订单创建后及时完成支付。
内容的提问来源于stack exchange,提问作者mrakodol
相关产品推荐
相关产品推荐

