PayPal REST API创建订单:Bash正常PHP报403 Forbidden
PayPal REST API创建订单PHP脚本返回403 Forbidden的原因
现象说明
Bash脚本调用PayPal REST API可正常完成认证并创建订单,但相同逻辑的PHP脚本在创建订单环节返回403 Forbidden错误。
问题核心原因
对比两段代码的请求头,关键差异在于创建订单接口的Content-Type设置错误:
- Bash脚本中创建订单的请求头为
Content-Type: application/json,符合PayPal v2/checkout/orders接口的要求(该接口仅接收JSON格式的请求体) - PHP脚本中错误将创建订单的
Content-Type设置为application/x-www-form-urlencoded,导致PayPal服务器无法正确解析请求体,进而返回403权限拒绝错误。
另外,PHP认证接口使用的URL是api.sandbox.paypal.com,而Bash用的是api-m.sandbox.paypal.com,不过该差异不影响认证(两个域名均支持OAuth2 token接口),建议统一使用api-m.sandbox.paypal.com保持一致性。
修正方案
修改PHP脚本create_order函数的请求头,将Content-Type改为application/json:
$http_header = array ( "Content-Type: application/json", // 修正此处 "Authorization: Bearer $access_token", "PayPal-Request-Id: 7b92603e-77ed-4896-8e78-5dea2050476a" );
附:原代码及执行结果对比
正常运行的Bash脚本及执行结果
$ cat paypal.sh # https://developer.paypal.com/api/rest/authentication/ # https://developer.paypal.com/dashboard/applications/sandbox CLIENT_ID="aaa" CLIENT_SECRET="aaa" # authenticate RESULT=$( \ curl \ -s \ -X POST "https://api-m.sandbox.paypal.com/v1/oauth2/token" \ -u "${CLIENT_ID}:${CLIENT_SECRET}" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials") ACCESS_TOKEN=$(echo ${RESULT} | sed 's/.*"access_token":"\([-_a-zA-Z0-9]*\)".*/\1/') echo "ACCESS_TOKEN=${ACCESS_TOKEN}" # create order RESULT=$( \ curl \ -s \ -X POST "https://api-m.sandbox.paypal.com/v2/checkout/orders" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "PayPal-Request-Id: 7b92603e-77ed-4896-8e78-5dea2050476a" \ -d '{ "intent": "CAPTURE", "purchase_units": [ { "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b", "amount": { "currency_code": "EUR", "value": "10.00" } } ], "payment_source": { "paypal": { "experience_context": { "payment_method_preference": "IMMEDIATE_PAYMENT_REQUIRED", "payment_method_selected": "PAYPAL", "brand_name": "EXAMPLE INC", "locale": "en-US", "landing_page": "LOGIN", "shipping_preference": "SET_PROVIDED_ADDRESS", "user_action": "PAY_NOW", "return_url": "https://example.com/returnUrl", "cancel_url": "https://example.com/cancelUrl" } } } }') ORDER_ID=$(echo ${RESULT} | sed 's/.*"id":"\([-a-zA-Z0-9_]*\)".*/\1/') ORDER_STATUS=$(echo ${RESULT} | sed 's/.*"status":"\([A-Z_]*\)".*/\1/') ORDER_HREF=$(echo ${RESULT} | sed 's/.*"href":"\([-a-zA-Z0-9_:/.?=]*\)".*/\1/') echo "ORDER_ID=${ORDER_ID}" echo "ORDER_STATUS=${ORDER_STATUS}" echo "ORDER_HREF=${ORDER_HREF}"
执行结果:
$ ./paypal.sh ACCESS_TOKEN=aaa ORDER_ID=aaa ORDER_STATUS=PAYER_ACTION_REQUIRED ORDER_HREF=https://www.sandbox.paypal.com/checkoutnow?token=aaa
返回403的PHP脚本及执行结果
$ cat paypal.php <?php function authenticate() { $ch = false; $client_id = "aaa"; $client_secret = "aaa"; $http_header = array("Content-Type: application/x-www-form-urlencoded"); $post_fields = 'grant_type=client_credentials'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api.sandbox.paypal.com/v1/oauth2/token"); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERPWD, $client_id.":".$client_secret); curl_setopt($ch, CURLOPT_HTTPHEADER, $http_header); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); $result = curl_exec($ch); $json = json_decode($result); $access_token = $json->access_token; curl_close($ch); return $access_token; } function create_order($access_token) { $ch = false; $http_header = array ( "Content-Type: application/x-www-form-urlencoded", "Authorization: Bearer $access_token", "PayPal-Request-Id: 7b92603e-77ed-4896-8e78-5dea2050476a" ); $post_fields = '{ "intent": "CAPTURE", "purchase_units": [ { "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b", "amount": { "currency_code": "EUR", "value": "10.00" } } ], "payment_source": { "paypal": { "experience_context": { "payment_method_preference": "IMMEDIATE_PAYMENT_REQUIRED", "payment_method_selected": "PAYPAL", "brand_name": "EXAMPLE INC", "locale": "en-US", "landing_page": "LOGIN", "shipping_preference": "SET_PROVIDED_ADDRESS", "user_action": "PAY_NOW", "return_url": "https://example.com/returnUrl", "cancel_url": "https://example.com/cancelUrl" } } } }'; echo "create_order: access_token: $access_token "; echo "create_order: http_header: "; print_r($http_header); echo "create_order: post_fields: $post_fields "; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api-m.sandbox.paypal.com/v2/checkout/orders"); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $http_header); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); $result = curl_exec($ch); echo "create_order: result: "; print_r($result); echo " "; curl_close($ch); } $access_token = authenticate(); echo "access_token: ".$access_token." "; create_order($access_token); ?>
执行结果:
$ php -f paypal.php access_token: aaa create_order: access_token: aaa create_order: http_header: Array ( [0] => Content-Type: application/x-www-form-urlencoded [1] => Authorization: Bearer aaa [2] => PayPal-Request-Id: 7b92603e-77ed-4896-8e78-5dea2050476a ) create_order: post_fields: { "intent": "CAPTURE", "purchase_units": [ { "reference_id": "d9f80740-38f0-11e8-b467-0ed5f89f718b", "amount": { "currency_code": "EUR", "value": "10.00" } } ], "payment_source": { "paypal": { "experience_context": { "payment_method_preference": "IMMEDIATE_PAYMENT_REQUIRED", "payment_method_selected": "PAYPAL", "brand_name": "EXAMPLE INC", "locale": "en-US", "landing_page": "LOGIN", "shipping_preference": "SET_PROVIDED_ADDRESS", "user_action": "PAY_NOW", "return_url": "https://example.com/returnUrl", "cancel_url": "https://example.com/cancelUrl" } } } } create_order: result: 403 Forbidden
内容的提问来源于stack exchange,提问作者YuGiOhJCJ
相关产品推荐
相关产品推荐

