You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 00:02:04