Paypal 结帐 - 订单捕获从服务器获得 PERMISSION-DENIED 但在 javascript 客户端中工作
Posted
技术标签:
【中文标题】Paypal 结帐 - 订单捕获从服务器获得 PERMISSION-DENIED 但在 javascript 客户端中工作【英文标题】:Paypal checkout - order capture get PERMISSION-DEINED from server but works in javascript client 【发布时间】:2021-11-22 00:04:50 【问题描述】:我正在使用 Paypal 结帐 php sdk。我从这里关注文档https://github.com/paypal/Checkout-PHP-SDK
首先我创建一个订单
$env = new SandboxEnvironment($clientId, $secretKey);
$client = new PayPalHttpClient($env);
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = buildOrder($order);
//buildOrder has this param:
/*
"application_context" => [
"return_url" => 'domain/paypal/return.php',
"cancel_url" => 'domain/paypal/cancel.php'
]
*/
//request body
$body = array (
'intent' => 'CAPTURE',
'purchase_units' =>
array (
0 =>
array (
'reference_id' => 9,
'amount' =>
array (
'value' => 125.63,
'currency_code' => 'USD',
'breakdown' =>
array (
'item_total' =>
array (
'currency_code' => 'USD',
'value' => 125.63,
),
),
),
'items' =>
array (
0 =>
array (
'name' => 'Demo 46',
'description' => NULL,
'sku' => NULL,
'unit_amount' =>
array (
'currency_code' => 'USD',
'value' => 98.0,
),
'quantity' => '1',
),
1 =>
array (
'name' => 'Demo 28',
'description' => NULL,
'sku' => NULL,
'unit_amount' =>
array (
'currency_code' => 'USD',
'value' => 12.22,
),
'quantity' => '1',
),
2 =>
array (
'name' => 'Addon 33',
'description' => NULL,
'sku' => NULL,
'unit_amount' =>
array (
'currency_code' => 'USD',
'value' => 15.41,
),
'quantity' => '1',
),
),
),
),
'application_context' =>
array (
'return_url' => 'http://domain.test/paypal/return',
'cancel_url' => 'http://domain.test/paypal/canceled',
),
)
$response = $client->execute($request);
创建订单响应:
"statusCode":201,"result":"id":"10M47599SM3059709","intent":"CAPTURE","status":"CREATED","purchase_units":["reference_id":"9","amount":"currency_code":"USD","value":"125.63","breakdown":"item_total":"currency_code":"USD","value":"125.63","payee":"email_address":"sb-kpo1v7959755@business.example.com","merchant_id":"XEH8BEAE3FXPW","items":["name":"Demo 46","unit_amount":"currency_code":"USD","value":"98.00","quantity":"1","name":"Demo 28","unit_amount":"currency_code":"USD","value":"12.22","quantity":"1","name":"Addon 33","unit_amount":"currency_code":"USD","value":"15.41","quantity":"1"]],"create_time":"2021-09-30T22:59:31Z","links":["href":"https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/10M47599SM3059709","rel":"self","method":"GET","href":"https:\/\/www.sandbox.paypal.com\/checkoutnow?token=10M47599SM3059709","rel":"approve","method":"GET","href":"https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/10M47599SM3059709","rel":"update","method":"PATCH","href":"https:\/\/api.sandbox.paypal.com\/v2\/checkout\/orders\/10M47599SM3059709\/capture","rel":"capture","method":"POST"],"headers":"":"","Content-Type":"application\/json","Content-Length":"1085","Connection":"keep-alive","Date":"Thu, 30 Sep 2021 22","Application_id":"APP-80W284485P519543T","Cache-Control":"max-age=0, no-cache, no-store, must-revalidate","Caller_acct_num":"XEH8BEAE3FXPW","Paypal-Debug-Id":"95be3b11c12e7","Strict-Transport-Security":"max-age=31536000; includeSubDomains"
然后我可以得到orderID,我将它存储在会话中。接下来,我将买家重定向到来自 Paypal 响应的 approve
url。
接下来,买家付款,Paypal 将买家带到我上面的退货网址。
在return.php中我通过这段代码捕获订单
$env = new SandboxEnvironment($clientId, $secretKey);
$client = new PayPalHttpClient($env);
//$orderId can get from session or from `token` param in return url
$request = new OrdersCaptureRequest($orderId);
$request->prefer('return=representation');
$response = $client->execute($request);
来自 OrdersCaptureRequest 的新响应:
"name":"NOT_AUTHORIZED","details":["issue":"PERMISSION_DENIED","description":"You do not have permission to access or perform operations on this resource."],"message":"Authorization failed due to insufficient permissions.","debug_id":"e8021203038f1","links":["href":"https://developer.paypal.com/docs/api/orders/v2/#error-PERMISSION_DENIED","rel":"information_link"] "exception":"[object] (PayPalHttp\\HttpException(code: 0): \"name\":\"NOT_AUTHORIZED\",\"details\":[\"issue\":\"PERMISSION_DENIED\",\"description\":\"You do not have permission to access or perform operations on this resource.\"],\"message\":\"Authorization failed due to insufficient permissions.\",\"debug_id\":\"e8021203038f1\",\"links\":[\"href\":\"https://developer.paypal.com/docs/api/orders/v2/#error-PERMISSION_DENIED\",\"rel\":\"information_link\"]
我的回复是(旧的):
"name":"NOT_AUTHORIZED","details":["issue":"PERMISSION_DENIED","description":"You do not have permission to access or perform operations on this resource."],"message":"Authorization failed due to insufficient permissions.","debug_id":"ff1bfd34831cb","links":["href":"https://developer.paypal.com/docs/api/orders/v2/#error-PERMISSION_DENIED","rel":"information_link"] "exception":"[object] (PayPalHttp\\HttpException(code: 0): \"name\":\"NOT_AUTHORIZED\",\"details\":[\"issue\":\"PERMISSION_DENIED\",\"description\":\"You do not have permission to access or perform operations on this resource.\"],\"message\":\"Authorization failed due to insufficient permissions.\",\"debug_id\":\"ff1bfd34831cb\",\"links\":[\"href\":\"https://developer.paypal.com/docs/api/orders/v2/#error-PERMISSION_DENIED\",\"rel\":\"information_link\"]
然后我提出了在客户端和服务器之间结合的解决方案
-
我嵌入了 Paypal 结帐按钮
从服务器创建订单
处理来自 js 客户端的批准
通过 Paypal js 函数捕获订单。
Paypal 以
COMPLETED
状态回复。
<script
src="https://www.paypal.com/sdk/js?client-id=[SANDBOX_CLIENT_ID]"></script>
<script>
paypal.Buttons(
createOrder: function(data, actions)
return fetch('create-order.php',
method: 'post',
headers:
'content-type': 'application/json'
,
).then(function(res)
return res.json();
).then(function(data)
return data.token;
);
,
onApprove: function(data, actions)
return actions.order.capture().then(function(details)
console.log(details);
);
);
</script>
即使我尝试将 Paypal js 的 onApprove
事件中的 orderID 发送到我的服务器以捕获订单,PERMISSION-DENIED
也会发生同样的问题。
请帮忙。
【问题讨论】:
【参考方案1】:重定向到 rel:approve URL 适用于旧网站。您应该使用 PayPal 按钮而不是重定向,这对买家来说是一种更好、更现代的上下文体验,让您的网站在后台加载/灯箱褪色。
您在服务器端捕获订单时遇到的问题似乎是使用了错误的请求对象:
//$orderId can get from session or from `token` param in return url
$request = new OrdersCreateRequest($orderId);
在这个阶段,您需要一个 OrdersCaptureRequest。请参阅示例bundled as part of the SDK。
【讨论】:
感谢您的建议。我使用了 Paypal 按钮,但我想从服务器而不是 Paypal javascript 捕获订单。对于 OrdersCreateRequest,这是我复制粘贴的错误。事实上,我使用了 OrdersCaptureRequest,编辑了我的问题。 (1) 在 paypal.com/… 中创建一个新的沙盒业务帐户 (2) 在 paypal.com/… 中为该帐户创建一个新的 REST 应用程序 (3) 在任何地方使用新APP的Client ID和Secret,包括在你的API调用和JS SDK中。如果问题仍然存在,请记录您的完整订单 创建和订购 Capture API 调用(包括请求和响应文本)并使用此信息以及您正在使用的新沙盒客户端 ID 和秘密凭据更新您的问题。 我创建了新的企业帐户,为该企业帐户创建了新的应用程序。我用更多细节编辑了这个问题。谢谢@Preston 我在您的编辑中没有看到任何不正确的地方,但您没有包含您正在使用的沙盒客户端 ID 和密码,因此无法对其进行测试以进行重现。接下来您应该尝试的是从paypal.com/… 新创建的个人帐户,以确保买家帐户正常以上是关于Paypal 结帐 - 订单捕获从服务器获得 PERMISSION-DENIED 但在 javascript 客户端中工作的主要内容,如果未能解决你的问题,请参考以下文章