Search code examples
javaamazon-mwsamazon-marketplace

Problem with LWA Token Exchange using Selling-Partner Java SDK


My code

AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
                .accessKeyId("XXXXXXXXXXXXXXX").secretKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                .region("eu-west-1").build();
        
        AWSAuthenticationCredentialsProvider awsAuthenticationCredentialsProvider = AWSAuthenticationCredentialsProvider
                .builder().roleArn("XXXXXXXXXXXXX").roleSessionName("123123123")
                .build();



        LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
                .clientId("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                .clientSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                .endpoint("https://api.amazon.com/auth/o2/token").build();


        SellersApi sellersApi = new SellersApi.Builder().awsAuthenticationCredentials(awsAuthenticationCredentials)
                .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
                .awsAuthenticationCredentialsProvider(awsAuthenticationCredentialsProvider)
                .endpoint("https://sellingpartnerapi-eu.amazon.com").build();

        GetMarketplaceParticipationsResponse res = sellersApi.getMarketplaceParticipations();
        List<MarketplaceParticipation> data = new ArrayList<MarketplaceParticipation>();
        data = res.getPayload();
        for (MarketplaceParticipation obj : data) {
            System.out.println(obj);
        }

Error:

Caused by: java.lang.RuntimeException: Error getting LWA Access Token at com.amazon.SellingPartnerAPIAA.LWAClient.getAccessTokenFromEndpoint(LWAClient.java:74) at com.amazon.SellingPartnerAPIAA.LWAClient.getAccessTokenFromCache(LWAClient.java:51) at com.amazon.SellingPartnerAPIAA.LWAClient.getAccessToken(LWAClient.java:40) at com.amazon.SellingPartnerAPIAA.LWAAuthorizationSigner.sign(LWAAuthorizationSigner.java:69) at com.amazon.sellingpartner.ApiClient.buildRequest(ApiClient.java:1034) at com.amazon.sellingpartner.ApiClient.buildCall(ApiClient.java:973) at com.amazon.sellingpartner.api.SellersApi.getMarketplaceParticipationsCall(SellersApi.java:111) at com.amazon.sellingpartner.api.SellersApi.getMarketplaceParticipationsValidateBeforeCall(SellersApi.java:118) at com.amazon.sellingpartner.api.SellersApi.getMarketplaceParticipationsWithHttpInfo(SellersApi.java:141) at com.amazon.sellingpartner.api.SellersApi.getMarketplaceParticipations(SellersApi.java:130) at com.yash.spapi.TestSpApiApplication.main(TestSpApiApplication.java:47) ... 5 more Caused by: java.io.IOException: Unsuccessful LWA token exchange at com.amazon.SellingPartnerAPIAA.LWAClient.getAccessTokenFromEndpoint(LWAClient.java:63) ... 15 more


Solution

  • You seem not to have provided the refresh token when constructing the LWAAuthorizationCredentials. Try inserting .refreshToken("<your-refresh-token>") after .clientSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX").

    The following code works for me (with self authorization, and correct security parameters of course):

    package amzspapitest;
    
    import com.amazon.SellingPartnerAPIAA.AWSAuthenticationCredentials;
    import com.amazon.SellingPartnerAPIAA.AWSAuthenticationCredentialsProvider;
    import com.amazon.SellingPartnerAPIAA.LWAAuthorizationCredentials;
    import io.swagger.client.ApiException;
    import io.swagger.client.api.SellersApi;
    import io.swagger.client.model.GetMarketplaceParticipationsResponse;
    import io.swagger.client.model.MarketplaceParticipation;
    import java.util.List;
    import java.util.UUID;
    
    public class AmzSPAPITest {
        protected final String awsAccessKeyId = "XXXXXXXXXXXXXXXXXXXX";
        protected final String awsSecretAccessKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        protected final String awsRegion = "us-east-1";
        
        protected final String awsRoleArn = "arn:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        
        protected final String awsClientId = "amzn1.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        protected final String awsClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        protected final String awsRefreshToken = "Atzr|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +
                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +
                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +
                "XXXXXXXXXXXXXXXXXXXXXXXX";
        protected final String awsEndpoint = "https://api.amazon.com/auth/o2/token";
    
        public static void main(String[] args) {
            new AmzSPAPITest().amazonAwsTest();
        }
    
        public void amazonAwsTest() {
            try {
                AWSAuthenticationCredentials aac = AWSAuthenticationCredentials.builder()
                        .accessKeyId(awsAccessKeyId)
                        .secretKey(awsSecretAccessKey)
                        .region(awsRegion)
                        .build();
    
                AWSAuthenticationCredentialsProvider aacp = AWSAuthenticationCredentialsProvider.builder()
                        .roleArn(awsRoleArn)
                        .roleSessionName(UUID.randomUUID().toString())
                        .build();
    
                LWAAuthorizationCredentials lac = LWAAuthorizationCredentials.builder()
                        .clientId(awsClientId)
                        .clientSecret(awsClientSecret)
                        .refreshToken(awsRefreshToken)
                        .endpoint(awsEndpoint)
                        .build();
    
                SellersApi sa = new SellersApi.Builder()
                        .awsAuthenticationCredentials(aac)
                        .lwaAuthorizationCredentials(lac)
                        .awsAuthenticationCredentialsProvider(aacp)
                        .endpoint("https://sellingpartnerapi-na.amazon.com")
                        .build();
    
                GetMarketplaceParticipationsResponse res = sa.getMarketplaceParticipations();
                List<MarketplaceParticipation> data = res.getPayload();
                for (MarketplaceParticipation obj: data) {
                    System.out.println(obj);
                }
            } catch (ApiException e) {
                e.printStackTrace(System.err);
            }
        }
    }