Closed winterstefan closed 2 years ago
Do you actually get a value in forcode
? That is the standard name of the parameter but amazon uses spapi_oauth_code
in the callback.
@rogersv Thanks for the answer! Indeed, the response object for the first call contains (just) the response.code
with an actual token.
That was one point that confused me, because the documentation states the occurance of both an MWS and SP token.
Do you have an idea why?
I'm using the script https://assets.loginwithamazon.com/sdk/na/login1.js
as stated in the documentation.
But the same documentation, just one step forward, also mentions response.code
to be passed from the JavaScript snippet to the server-side code (see here).
<!-- Pass response.code to your server, and use it to request refresh and
access token. -->
Sorry, I do not know. I did not used that script. It seems to be correct with code
in this case.
Hi @winterstefan ,
i am also in the process of implementing the sp-api. What i noticed about calling the /apps/authorize/consent?application_id
endpoint is the following:
version=beta
parameter we get the full link, with mws_auth_token
and spapi_oauth
token. If we omit the version=beta
we only get the spapi_oauth
token, the mws_auth_token
is not returned.spapi_oauth
code we could not yet successfuly retrieve the access and refresh tokens. I suspect it is because our Oauth URLs are still in draft state.spapi_oauth_token
. That is the Alexa integration documentation, but it uses the same service, so try to make sure you do exchange the code for access and refresh tokens within those 4.5 seconds.Let me know if you manage to authenticate successfully, as we're also having issues with it.
Hi @gasper-vrhovsek, thanks for reaching out!
By making the necessary HTTP calls on my own (PHP or CURL) I'm still unable to successfully accessing the SP-API. When using the JavaScript SDK, I'm getting 'some kind of token' and I'm able to fetch the sellers profile information (e.g. their primary email address). Nevertheless, I'm unable to use this token in the SP-API part. Reason: The request signature of the SP-API request is marked as invalid.
Actually I want to have most of this part on server-side. But for the sake of having at least some kind of working example, I fully used the JavaScript SDK. In short, here you can view the JS code that works for me:
authorize()
{status: "complete", code: "ANLXXXXXXX", scope: "profile", onComplete: ƒ}
,code
instead of something like spapi_oauth
retrieveToken()
Atza|XXXXXXX
refresh token
SellerCentral
-> Developer Central
-> clicking authorizing
for my application, I will get a refresh token (for use with eg the Marketplace API). This refresh token also starts with Atza|XXXXXXX
. So I guess mine is a refresh token. ^^retrieveProfile()
Assumption: I have a valid code for using it when calling a SP-API endpoint.
Here I'm using a Guzzle client to make my request in PHP. For signing this request, the official AWS PHP SDK is in use (because both support / need the v4 of request signing).
Here too I tried to stick to the documentation as tightly as possible. But I cannot get further than receiving an signature error. Since this is another dead-end for me, I also tried getting help in the Amazon developer forum as well.
Feel free to visit the forum for a detailed description. If you don't have access, here's a short summary.
$credentials = new Credentials($options['aws_user_key'], $options['aws_user_secret']);
$signatureV4 = new SignatureV4($options['service'], $options['region']);
$request = new Request(
'POST',
'https://sellingpartnerapi-eu.amazon.com/reports/2020-09-04/reports',
[
'x-amz-access-token' => $options['seller_access_token'], // retrieved from JS SDK after seller has approved access to its accoun
'user-agent' => 'My Tool/0.0.1',
],
);
$request = $signatureV4->signRequest($request, $credentials);
$client = new Client();
$requestOptions = [
'Content-Type' => 'application/json',
'Host' => 'https://sellingpartnerapi-eu.amazon.com',
'json' => [
'reportType' => 'GET_FLAT_FILE_OPEN_LISTINGS_DATA', // inventory data
'marketplaceIds' => 'A1PA6795UKMFR9', // german marketplace
],
];
try {
$client->send($request, $requestOptions);
} catch (ClientException $e) {
$exceptionRequest = $e->getRequest();
echo sprintf("\nURI: %s", $exceptionRequest->getUri());
foreach ($exceptionRequest->getHeaders() as $name => $values) {
echo sprintf("\n%s: %s", $name, implode(',', $values));
}
echo sprintf("\n\nMessage: %s", $e->getMessage());
}
I masked credentials. In detail, 'just' the signature itself seems to be wrong. All other params (like described in the guidelines from this very repository look fine to me.
But the great question: What's wrong with this signature? I just use the official AWS SDK for creating the signature, so having a wrong HMAC algorithm should not be the problem. Also, I reached out to Amazon support for actually debugging this very request. They didn't.
URI: https://sellingpartnerapi-eu.amazon.com/reports/2020-09-04/reports
Content-Type: application/json
Host: sellingpartnerapi-eu.amazon.com
x-amz-access-token: Atza|IwEBIAtelq1WRXXXX
user-agent: My Tool/0.0.1
X-Amz-Date: 20201120T142538Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIA3HD5GN6XXXXX/20201120/eu-west-1/execute-api/aws4_request, SignedHeaders=host;x-amz-access-token;x-amz-date, Signature=ca61d60425bc5a6907f2f98f89bb4dXXXX
Message: The request signature we calculated does not match the signature you provided.
Just for the sake of completeness: I debugged the hell out of the mentioned SP-APi request. Here are some samples.
I altered most of the params specified by the docs (credential scope and auth header). With that, I tried to double-check if my originally sent information where correct.
Action | Response |
---|---|
Using invalid AWS region superman |
Credential should be scoped to a valid region, not 'superman'. |
Using invalid Service superman |
Credential should be scoped to correct service: 'execute-api'. |
Using invalid AWS user key | The security token included in the request is invalid. |
Nevertheless, altering the HTTP header x-amz-access-token
does still deliver the signature error from above. So my conclusion is that this token is not valid. I used just the Atza|
style token I received via the JavaScript sdk
Ah, almost forgot:
I'm very confused by what the prerequisites have to be for using the production version of the SP-API. Here some thoughts:
@gasper-vrhovsek You mentioned having an application published
but oAuth URLs in draft state
.
published application
in detail? Is it available in the Amazon App Marketplace? Is there another state of being published?For my understanding:
version=beta
param, I shall be able to test my application (but what exactly means testing? Access to Sandbox? Even to production?sandbox. ...
to the API host.
version=beta
param in Sandbox
mode.Does anybody have valid information about what steps have to be taken with the application to successfully being able to either use Sandbox or (even better) the Production env?
Hi @winterstefan
I'll go from top to bottom and try to answer as best i can :)
As @rogersv mentioned earlier, here it's strange to just get code instead of something like spapi_oauth
I would assume they just save the spapi_oauth value in a new code
field and return that.
retrieveToken() Returns a very long string always starting with Atza|XXXXXXX Don't know if thats the so called refresh token But going to SellerCentral -> Developer Central -> clicking authorizing for my application, I will get a refresh token (for use with eg the Marketplace API). This refresh token also starts with Atza|XXXXXXX. So I guess mine is a refresh token. ^^
This is where i have problems. Without using the JavaScript lib, my requests to /auth/o2/token
get rejected with:
{
"error_description": "Not authorized for requested operation",
"error": "unauthorized_client"
}
Seeing you have more success with the javascript lib i'll try that also.
Here too I tried to stick to the documentation as tightly as possible. But I cannot get further than receiving an signature error. Since this is another dead-end for me, I also tried getting help in the Amazon developer forum as well.
We weren't yet trying the PHP SDK, but we did try the Java one. We could successfully self-authorize and use the API, but when trying to authorize as other sellers (which have already approved us via the old MWS authentication flow) using the AuthorizeApi class we are getting such error responses:
{
"errors": [
{
"code": "InvalidInput",
"message": "Developer ID 35XXXXXXXX is not associated with the application id.",
"details": ""
}
]
}
Regarding this issue, we got a response from amazon support saying, our app should be fully published in Amazon Appstore Marketplace, as our is in draft, pending approval. But the only changes that are in draft are the Oauth URL fields in the application form. That is actually also the answer to your question about our application state.
@gasper-vrhovsek You mentioned having an application published but oAuth URLs in draft state. What do you mean by an published application in detail? Is it available in the Amazon App Marketplace? Is there another state of being published? How can an oAuth URL be just a draft?
We had the application already published, bit it was a MWS app without the SP-API support. Then we changed the app type to MWS & SP-API (hybrid) and published it. I haven't got more info about the process which was taken as i was not at this company at the time. Well after that, we entered the Oauth url settings into our application and those changes are now in draft pending approval.
I'll be trying the Javascript SDK today, i'll post my findings here.
Thanks for the awesome reply @gasper-vrhovsek!
Okay now I understand the 'the oauth url is in draft', ty. Makes sense since your application was published before. My use-case right now is a blank new application (registered as hybrid with MWS and SP-API) where I'm trying to use the SP-API for the very first time. So the entire application is in draft state and hasn't been published in the app store at all.
⚠️ I finally was able to get a valid refresh token by using the HTTP endpoint /auth/o2/token
. I'll post a fresh new comment right below for keeping it structured and readable (hopefully^^).
Whilst searching for a possible solution, I stumbled across this posting in the Amazon forum, with that username I guess it's your post? To be honest, it indeed sounds like a configuration issue. But I do not know any location where you would supposed to 'link' the developer ID with the application Id. Did the support help in any way?
In that forum, another kind person replied trying to help: posting in amazon forum. In the comments of the PHP code, he describes where to get the specific data from. Maybe this helps you for double-checking with yours?
Maybe you're sending the wrong client_id
/ client_secret
pair to the oauth endpoint? I'm using the amzn1.application-oa2-client
. At least I got really confused about client_id
from AWS, from LWA and from my SellerCentral.
Another day, another approach (I guess). After lots of debugging, I'm not so sure about the JavaScript SDK anymore. Even I understand the documentation that I can either use the JavaScript SDK or the manually concatenated consent URL, there seem to be differences.
Atza|
(last char is 'A' for access), a refresh token starts with Atzr|
(last char is 'R' for refresh)
version=beta
M9999
right in the Amazon UI for authorization.4.5s
limit sounds legit (due to docs etc), in my example it didn't affect my auth process.So now I understand the auth part just a bit more (hence: I got a valid refresh token and was able to receive an auth token right on demand). That gets me back to the other problem with calling an SP-API endpoint (see my other posting in this thread).
I reviewed every step and checked my request data. I'm just every time receiving the error, that my signature isn't correct. I'm quite frustrated 😇 .
@gasper-vrhovsek If I can provide any more information that may help you getting through the auth process, keep me posted!
Approach 1️⃣: auth code via JS, refresh token via PHP (❌ not working ❌)
Steps
amazon.Login.authorize
, it gives a 21-char code (named code
, not spapi_oauth...
)code
in the custom oAuth call with grant_type=authorization_code
(docs)Result
400 Bad Request
and this content
{"error_description":"The request has an invalid grant parameter : code","error":"invalid_grant"}
Conclusion
code
from JS SDK is not usable for that.Approach 2️⃣: auth code via JS, refresh token via JS (❌ not working ❌)
Steps
amazon.Login.authorize
like in approach 1️⃣code
to amazon.Login.retrieveToken
(example code in docs)Result
Atza|
!), but no refresh tokenConclusion
3600s
. I need a long-living refresh tokenApproach 3️⃣: Manual concatenated URI, refresh token via PHP (✅ works for me ✅)
Steps
version=beta
spapi_oauth_code
spapi_oauth_code
in the custom oAuth call with grant_type=authorization_code
(docs)Result
Hey @winterstefan
To be honest, it indeed sounds like a configuration issue. But I do not know any location where you would supposed to 'link' the developer ID with the application Id. Did the support help in any way?
We got a reply regarding the issue you linked (that was reproduced using the Java SDK and trying to authenticate with some of our seller partner credentials), amazon support said the issue is the draft state of our app. We asked them if they could speed up the approve process. I'll be testing it again once they do.
In that forum, another kind person replied trying to help: posting in amazon forum. In the comments of the PHP code, he describes where to get the specific data from. Maybe this helps you for double-checking with yours?
Thanks for that, i'll be taking a look.
Maybe you're sending the wrong client_id / client_secret pair to the oauth endpoint? I'm using the amzn1.application-oa2-client. At least I got really confused about client_id from AWS, from LWA and from my SellerCentral.
I got my client_id and client_secret from the seller central, under develop apps and by clicking the "LWA credentials" next to the our app. It also starts with amzn1.application-oa2-client
I'm just able to authorize my own developer account (I guess because my app is in DRAFT state). Any other seller account fails with error code M9999 right in the Amazon UI for authorization.
I got those M9999 errors using the generated Java SDK (AuthorizeApi class). I'm still waiting for our app to be published to test that again.
Approach 3️⃣: Manual concatenated URI, refresh token via PHP (✅ works for me ✅)
I can get the spapi_oauth code by calling the /auth/o2/token
endpoint, it works with a manually generated URL. I have issues in step 4. where i should exchange that code for the two tokens (gives us the "Not authorized for requested operation" error). I'll be trying the Javascript SDK today. Might be, i'll have to open another ticket regarding the token exchange errors we have...
Hello @gasper-vrhovsek
okay, that sounds legit. I hope you find more insights when using the Javascript SDK and getting the application approved. 👍
I got those M9999 errors using the generated Java SDK (AuthorizeApi class). I'm still waiting for our app to be published to test that again.
That indeed IMHO is the error you receive if trying to authorize an 'external seller account' with your application whilst in draft state. I also am just permitted to use my own 'developer seller account' for autorizing the app with. So agreed, getting the app out of draft state should help.
Just one question about the phraseology:
amazon support said the issue is the draft state of our app. We asked them if they could speed up the approve process
I'm still waiting for our app to be published to test that again.
You're speaking of approve
and publish
. Do you mean the process of making the application generally available in the Amazon AppStore? Or is there any other process of 'getting out of the DRAFT state'?
That's the point where I got really confused in the first place:
Our own application is just a prototype right now (because we started implementing the SP-API, we don't have an existing app with MWS integration). So asking Amazon to publish this incomplete application in the App Store would be wrong.
But I'd love using the production SP-API with an actual seller of mine as a test. Since that's not possible because of the DRAFT state (at least this is my understanding of this M9999
error), I wonder if there's an intermediate step between 'in draft mode' and 'published in App Store'.
Hi @winterstefan
Yeah, i'm also generally confused, sorry. I'll just paste a screenshot of the app status in seller central:
I should say we're waiting for amazon to publish the changes we have in draft.
This is a very old issue that is probably not getting as much attention as it deserves. We encourage you to check if this is still an issue after the latest release and if you find that this is still a problem, please feel free to open a new issue and make a reference to this one.
Hi there,
I'm trying to adapt the newly published SP-API for my use-case, having a setup with PHP7 (server-side) and JavaScript (client-side). Unfortunately, right upon authorising my application (still in draft state) with a seller's account (or even my own developer account) fails.
tl;dl The HTTP request of trading a short
code
for a long-living one fails, the error mentions mycode
is wrong somehow. Am I missing a step?My use-case
code
)code
is exchanged for a long-living token via server-sideMy problem
The request for exchanging the
code
fails. See developer docs (in step 4, see sectionTo exchange an LWA authorization code for an LWA refresh token
.The response contains the following hint:
My source code
Part 1 - Javascript
This snippet handles clicking on a button thus opening the Amazon LWA popup where the seller authorises my application.
Part 2 - PHP
The
response.code
from above is taken and send in the request mentioned above (developer docs, step 4, first request).For the sake of simplicity, I'm pasting request and response information created with
curl
. That produces the same error as by using PHP.CURL command - As I read the documentation, it contains all required elements and config.
Request information - gained from CURL verbose output
Response information - gained from CURL verbose output
Summary
I followed the official documentation as accurate as I could. I cannot preclude having made a mistaking in configuring IAM, account, keys and stuff, (to be honest, I hope that this ist just a small config issue)but I double-checked every part of that documentation about it.
So the obvious question: Could anybody shed some light for me what possible issues could lead to this error?
Am I using the wrong origin for the
code
? Have I forgotten an important step somehow?