Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PayPal Transaction Search API: PERMISSION_DENIED, No Permission for the requested operation

I'm writing a service (in .NET Core 3.1 and Refit if it matters) that pulls transaction activities from my PayPal business account for a given date range to use on an admin dashboard. Currently I'm following the tutorial here:

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

and here:

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

The first part, I can get an authorization key just fine (using curl or postman, curl below

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'

This gives me an auth token both in postman and my custom service just fine. Next, when I try to pull the transactions (both in Postman and in code), I get an error

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'

Error:

{
    "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"
}

The info link in the error starts talking about 3rd party permissions, which I'm not sure is applicable because it is my Business account. Anyone have any ideas? I checked transaction history on my app in PayPal, so I'm at a lost.

Thanks in advance

like image 550
Kristof Avatar asked Mar 25 '20 01:03

Kristof


3 Answers

You need the scope https://uri.paypal.com/services/reporting/search/read .. if it's not there in the oauth2 response, double check your REST App's permissions.

Refreshing an access token

Existing access tokens are cached for 9 hours--so if you already requested an API token and then just added this permission to your app, it can take up to 9 hours for that permission's new scope to be reflected in the next token's generation.

To avoid waiting 9 hours, you can terminate that existing cached token with:

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

After termination, your next call to get a token will get a newly-generated one, including the new scope that was just added to the REST app.

like image 152
Preston PHX Avatar answered Nov 20 '22 17:11

Preston PHX


I have had the same issue and after much looking around I fixed it by:

  1. ticking the "Transaction Search" in the API in the payment dev account
  2. Adding Accept-Language: en_US and Content-Type: application/json to the headers which was the main struggle. Here is my final code (in 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);

Hope this helps someone else, I know the question is old!

like image 38
user1620090 Avatar answered Nov 20 '22 17:11

user1620090


It helped me to do the following:

  1. Add the permissions in the development app. enter image description here

  2. Generate the token again

and ready!!

like image 1
Yudner Avatar answered Nov 20 '22 17:11

Yudner