PayPal 交易搜索 API:PERMISSION_DENIED,无权进行请求的操作。

7
我正在编写一个服务(使用.NET Core 3.1和Refit,如果有影响),从我的PayPal商业账户中获取指定日期范围内的交易活动,以在管理仪表板上使用。目前,我正在按照这里的教程进行操作:

https://developer.paypal.com/docs/api/get-an-access-token-postman/

这里:

https://developer.paypal.com/docs/api/transaction-search/v1/

首先,我可以轻松获取授权密钥(使用curl或postman,下面是curl命令)。

curl --location --request POST 'https://api.paypal.com/v1/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic <my client id>:<my secret>' \
--header 'Content-Type: application/x-www-form-urlencoded' \

// not sure what this is, postman specific maybe? 
--header 'Cookie: tsrce=devdiscoverynodeweb; ts=vr%3D0cee9361171ac120001362adffec14c3%26vreXpYrS%3D1679730671%26vteXpYrS%3D1585061694%26vt%3D0cee9390171ac120001362adffec14c2' \
--data-urlencode 'grant_type=client_credentials'

这让我在Postman和我的自定义服务中都成功获取了授权令牌。接下来,当我尝试拉取交易记录时(无论是在Postman还是代码中),我都会收到错误提示。
cUrl:
curl --location --request GET 'https://api.paypal.com/v1/reporting/transactions?start_date=2020-03-01T00:00:00Z&end_date=2020-03-31T23:59:59Z' \
--header 'Authorization: Bearer <my token>' \
// Postman???
--header 'Cookie: tsrce=devdiscoverynodeweb; ts=vr%3D0cee9361171ac120001362adffec14c3%26vreXpYrS%3D1679730671%26vteXpYrS%3D1585061694%26vt%3D0cee9390171ac120001362adffec14c2'

错误:

{
    "localizedMessage": "No permission for the requested operation. ",
    "suppressed": [],
    "name": "PERMISSION_DENIED",
    "message": "No permission for the requested operation. ",
    "details": [
        {
            "field": null,
            "value": null,
            "location": null,
            "issue": "No permission for the requested operation. "
        }
    ],
    "information_link": "https://developer.paypal.com/docs/classic/products/permissions/",
    "debug_id": "7e315038e8073"
}

错误信息中的信息链接开始谈论第三方权限,我不确定是否适用,因为这是我的商业账户。有人有什么想法吗?我在PayPal的应用程序中检查了交易历史记录,所以我很困惑。
提前感谢。

3
你的oauth2调用实际返回了什么?我认为你需要包含作用域 https://uri.paypal.com/services/reporting/search/read .. 如果没有,请双检你的REST应用设置是否为LIVE(不是sandbox)。 - Preston PHX
谢谢您的快速回复。这是范围参数{ "scope": "https://uri.paypal.com/services/payments/initiatepayment openid https://uri.paypal.com/services/applications/webhooks", ... } - Kristof
1
@PrestonPHX 我通过删除并重新创建应用程序来修复了它。更改设置对原始版本毫无作用。你能否将你的回复创建为答案,以便我可以将其标记为答案? - Kristof
3个回答

19
你需要范围 https://uri.paypal.com/services/reporting/search/read .. 如果在oauth2响应中没有出现,请仔细检查你的REST应用程序的权限,并确保启用了交易搜索权限(选中框已勾选)。如果最近有更改,请参阅:

刷新访问令牌

现有的访问令牌被缓存了9小时,所以如果你在过去的9小时内使用了API,并且最近为你的应用程序启用了交易搜索权限,那么在下一个access_token生成时,该权限的新范围可能需要最多9小时才能反映出来。

为了避免等待9小时,你可以通过以下方式终止当前缓存的令牌:

curl -X POST https://api.sandbox.paypal.com/v1/oauth2/token/terminate \
     -u "yourclientid:yoursecret" \
     -d "token=REPLACE_WITH_YOUR_TOKEN"

终止后,您下一次获取令牌的调用将获得一个新生成的令牌,其中包括刚刚添加到REST应用程序的新范围。

1
更新了有关缓存的说明,并提供了刷新访问令牌的指示。 - Preston PHX
1
这个PayPal文档到底在哪里?使用谷歌搜索“https://uri.paypal.com/services/reporting/search/read”(包括引号)只返回2个结果——这篇SO帖子和另一个随机网站。 - David Jones
顺便说一下,我不需要终止旧令牌。一旦我请求了新的范围,就会发放新的令牌。 - David Jones
如果您手动指定所需的范围,那当然也可以。我不认为这更容易解释 - 部分原因是因为正如您提到的,实际的范围名称没有记录(它们没有太多理由被记录,这更像是一个故障排除细节,以检查您是否实际上获得了所需的权限)。 - Preston PHX
现在面临相同的问题,使用终止端点没有任何作用 - 仍然得到相同的范围。 - Omer Levi Hevroni
显示剩余2条评论

5

我曾经遇到过同样的问题,在大量搜索之后,以下操作解决了我的问题:

  1. 在支付开发账户的API中勾选“交易搜索”
  2. 将Accept-Language: en_US和Content-Type: application/json添加到头文件中,这是主要的困难。以下是我的最终代码(使用PHP):
<?
    $clientId = 'AfC.....';
    $secret = "EJs......";
    $url_base= 'https://api-m.sandbox.paypal.com/';
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url_base . "v1/oauth2/token");
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json','Accept-Language: en_US'));
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERPWD, $clientId.":".$secret);
    curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
    
    $result = curl_exec($ch);
    
    if(empty($result))die("Error: No response.");
    else
    {//token received
        $json = json_decode($result, true);
        print_r($json['scope']);
    
                  //place a call
                  $ch = curl_init();
                  curl_setopt($ch, CURLOPT_URL, $url_base . "v1/reporting/transactions?start_date=2020-12-01T00:00:00-0700&end_date=2020-12-30T23:59:59-0700&fields=all");
                  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json',"Authorization: Bearer ".$json['access_token']."", 'Accept-Language: en_US', 'Content-Type: application/json'));
                  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                  //curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($test));
    
                  $result = curl_exec($ch);
                  if(empty($result))die("Error: No response.");
                  else
                  {
                      $result= json_decode($result, true);
                    print_r($result);
                  }
    
    }//end of token received
    
    curl_close($ch);

希望这能帮助到其他人,我知道这个问题很古老!

1

它帮助我完成以下任务:

  1. 在开发应用程序中添加权限。 enter image description here

  2. 重新生成令牌。

然后就完成了!!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接