jlevers / selling-partner-api

A PHP client library for Amazon's Selling Partner API
BSD 3-Clause "New" or "Revised" License
404 stars 198 forks source link

RDT Token is invalid when using the SDK #533

Closed Blazevoir closed 1 year ago

Blazevoir commented 1 year ago

Hello everyone, im having the following issue:

I'm trying to access Order data using the OrdersV0API and getting some data_elements (buyer_info or shipping_address). When I try to use the SDK, i get an "Access to requested resource is denied" message, like lots of users around the forums. I've previously used Postman with successful results with the same calls and the same config data. When I use the SDK, however, I've come to realize that it gives me a wrong Restricted Data Token (RDT) since it doesn't work in Postman either. Let me show you:

Postman usage

First of all, I need to get an Access token using my LWA Refresh token with the following call: https://api.amazon.com/auth/o2/token

image

When we obtain the access_token (from now on let's call it "Atza" token) we can make simple calls through both the SDK and Postman successfully. However, when we face Restricted Data calls we need an RDT, which we can get through the following call:

image

Using the Atza token as a header whose name is "x-amz-access-token" we can obtain a new RDT (Atz.sprdt) and with that we can make Restricted calls:

image

Perfect, we're getting the data flawlessly through this method. When I try to use the SDK, however, I get the Access denied/Unauthorized error. I've been debugging the process and, at some point, I get the RDT that it's being used on the SDK call, but if I try to use it on Postman it doesn't work either. The RDT itself seems to be the problem.

Note that every single configuration option (tokens, IDs, marketplaces...) are exactly the same as the ones I've used on Postman, so there shouldn't be any problems regarding AWS credentials or any others.

        $this->config = new Configuration([
            'lwaClientId'        => 'amzn1.application-oa2-client.83317******5bc',
            'lwaClientSecret'    => 'amzn1.oa2-cs.v1.d0b27a7d790******d34',
            'lwaRefreshToken'    => 'Atzr|IwEBIDlwijCSkqks1UjJUG*******',
            'awsAccessKeyId'     => 'AKIAYZTYWZ******',
            'awsSecretAccessKey' => '/dkR88******wlRic/m**',
            'endpoint'           => Endpoint::EU
        ]);
        $api = new OrdersApi($this->config);
        $order_id = $parametros['id_pedido']; // string | An Amazon-defined order identifier, in 3-7-7 format.
        $data_elements = array('buyer_info'); // string[] | An array of restricted order data elements to retrieve (valid array elements are \"buyerInfo\" and \"shippingAddress\")

        try {
            $result = $api->getOrder($order_id, $data_elements);
            dd($result);
            return $result;
        } catch (\Exception $e) {
            echo 'Exception when calling OrdersV0Api->getOrder: ', $e->getMessage(), PHP_EOL;
        }

Important thing I've read in another user's post in this forum, and it might be part of the problem: In the Authentication.php class, line 319~ there's an instance of the Tokens API whose params are the following:

               $body = new Tokens\CreateRestrictedDataTokenRequest([
            "restricted_resources" => [$restrictedResource],
        ]);

It seems that, at least in Europe, the restricted_resources index requires an Object, and not an Objects array, so I removed the [] and it seems to work (I get the RDT, althought it doesn't work as I said before). If I keep the array it doesn't return an RDT; instead it throws a new error:

Application does not have access to one or more requested data elements: [buyer_info]

Changing it to an Object returns an atz.sprdt-like token (RDT):

image

But it still doesn't work in Postman:

image

What's the difference? Reading through the code it seems to do the exact same thing as I'm doing manually in Postman, same calls and same data, so I dont understand why the SDK token is invalid.

I hope i've been clear enough (and not too much) and I can both help any of you having the same issue and get help in order to get it to work.

I'm looking forward to your responses.

EDIT

I've checked my Postman body and I, too, send restricted_resources as an object array, since they patched it not too long ago in the Amazon side. Even so, calling with the same data works in Postman but returns the following through the SDK:

"code": "InvalidInput",
      "message": "Application does not have access to one or more requested data elements: [buyer_info]",
      "details": ""
jlevers commented 1 year ago

@Blazevoir, try changing buyer_info to buyerInfo in your code and see if that fixes the problem.

Blazevoir commented 1 year ago

As dumb as it sounds, it definitely solved the problem. I've been changing everything I thought it could be different from the Postman test and I left it with a wrong name.

I'm closing the issue, thank you so much! I'll be helping other people out since I see lots of issues I previously had too. Kind regards, Miguel.