diff --git a/CHANGES.txt b/CHANGES.txt index 43d93a0..a3eff2f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,9 @@ +Version 3.5.0 - February 2019 +- ConfirmOrderReference API has four new request parameters: + SuccessUrl, FailureUrl, AuthorizationAmount, and AuthorizationCurrencyCode + For usage instructions, please consult the + Amazon Pay Strong Customer Authentication (SCA) Upgrade Integration Guide + Version 3.4.1 - October 2018 - Updated XMLInputFactory.newFactory() to XMLInputFactory.newInstance() in generateErrorException method (now consistent with 3.0.1 release). - Add parameter SupplementaryData to SetOrderAttributes and SetOrderReferenceDetails API calls. Only use this field at the specific direction of Amazon Pay. diff --git a/dist/amazon-pay-3.4.1.jar b/dist/amazon-pay-3.5.0.jar similarity index 82% rename from dist/amazon-pay-3.4.1.jar rename to dist/amazon-pay-3.5.0.jar index 9fab6f7..0655eb8 100644 Binary files a/dist/amazon-pay-3.4.1.jar and b/dist/amazon-pay-3.5.0.jar differ diff --git a/pom.xml b/pom.xml index fdce8f3..e754013 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.amazon.pay amazon-pay-java-sdk jar - 3.4.1 + 3.5.0 commons-codec diff --git a/src/com/amazon/pay/request/ConfirmOrderReferenceRequest.java b/src/com/amazon/pay/request/ConfirmOrderReferenceRequest.java index ffea2b5..1550b2d 100644 --- a/src/com/amazon/pay/request/ConfirmOrderReferenceRequest.java +++ b/src/com/amazon/pay/request/ConfirmOrderReferenceRequest.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2016-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ */ package com.amazon.pay.request; +import com.amazon.pay.types.CurrencyCode; import java.io.Serializable; /** @@ -32,15 +33,22 @@ protected ConfirmOrderReferenceRequest getThis() { //required parameters private String amazonOrderReferenceId; + //optional parameters + private String successUrl; + private String failureUrl; + private String authorizationAmount; + private CurrencyCode authorizationCurrencyCode; + /** - * + * Constructor requires an order reference identifier. * @param amazonOrderReferenceId The order reference identifier. */ - public ConfirmOrderReferenceRequest(String amazonOrderReferenceId){ + public ConfirmOrderReferenceRequest(String amazonOrderReferenceId) { this.amazonOrderReferenceId = amazonOrderReferenceId; } /** + * The order reference identifier. * * @return AmazonOrderReferenceId */ @@ -48,6 +56,98 @@ public String getAmazonOrderReferenceId() { return amazonOrderReferenceId; } + /** + * @param currencyCode + * Three-digit currency code. In ISO 4217 format. + * + * @return ConfirmOrderReferenceRequest + * Container holding Confirm Order Reference operation parameters + */ + public ConfirmOrderReferenceRequest setAuthorizationCurrencyCode(final CurrencyCode currencyCode) { + this.authorizationCurrencyCode = currencyCode; + return this; + } + + /** + * Represents currency code for Confirm Order Reference request + * + * @return CurrencyCode + * Enum representing three-character currency code (ISO 4217) + */ + public CurrencyCode getAuthorizationCurrencyCode() { + return authorizationCurrencyCode; + } + + /** + * @param authorizationAmount + * The amount to authorize during MFA completion. + * Use this parameter if you want to set a payment + * amount that is different than the OrderTotal + * provided in the SetOrderReferenceDetails + * operation call. + * + * If this parameter is not set, the amount authorized + * during MFA will be equal to the OrderTotal. + * + * @return ConfirmOrderReferenceRequest + * Container holding Confirm Order Reference operation parameters + */ + public ConfirmOrderReferenceRequest setAuthorizationAmount(final String authorizationAmount) { + this.authorizationAmount = authorizationAmount; + return this; + } + + /** + * Represents the amount to be authorized during MFA completion. + * + * @return String + */ + public String getAuthorizationAmount() { + return authorizationAmount; + } + + /** + * @param successUrl + * The buyer is redirected to this URL if the MFA is successful. + * + * @return ConfirmOrderReferenceRequest + * Container holding Confirm Order Reference operation parameters + */ + public ConfirmOrderReferenceRequest setSuccessUrl(final String successUrl) { + this.successUrl = successUrl; + return this; + } + + /** + * Represents the URL buyer is redirected to when MFA is successful. + * + * @return String + */ + public String getSuccessUrl() { + return successUrl; + } + + /** + * @param failureUrl + * The buyer is redirected to this URL if the MFA is not successful. + * + * @return ConfirmOrderReferenceRequest + * Container holding Confirm Order Reference operation parameters + */ + public ConfirmOrderReferenceRequest setFailureUrl(final String failureUrl) { + this.failureUrl = failureUrl; + return this; + } + + /** + * Represents the URL buyer is redirected to when MFA is not successful. + * + * @return String + */ + public String getFailureUrl() { + return failureUrl; + } + /** * Returns a string representation of this object; useful for testing and * debugging. @@ -60,6 +160,10 @@ public String getAmazonOrderReferenceId() { public String toString() { return "ConfirmOrderReferenceRequest{" + "amazonOrderReferenceId=" + amazonOrderReferenceId + + ", authorizationAmount=" + authorizationAmount + + ", authorizationCurrencyCode=" + authorizationCurrencyCode + + ", successUrl=" + successUrl + + ", failureUrl=" + failureUrl + ", mwsAuthToken=" + getMwsAuthToken() + '}'; } diff --git a/src/com/amazon/pay/request/RequestHelper.java b/src/com/amazon/pay/request/RequestHelper.java index 96d893a..a47edca 100644 --- a/src/com/amazon/pay/request/RequestHelper.java +++ b/src/com/amazon/pay/request/RequestHelper.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2016-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. @@ -252,6 +252,22 @@ public String getPostURL(ConfirmOrderReferenceRequest request) { if (request.getAmazonOrderReferenceId() != null) { parameters.put(ServiceConstants.AMAZON_ORDER_REFERENCE_ID, request.getAmazonOrderReferenceId()); } + if (request.getSuccessUrl() != null) { + parameters.put(ServiceConstants.SUCCESS_URL, request.getSuccessUrl()); + } + if (request.getFailureUrl() != null) { + parameters.put(ServiceConstants.FAILURE_URL, request.getFailureUrl()); + } + + if (request.getAuthorizationAmount() != null) { + parameters.put(ServiceConstants.AUTHORIZATION_AMOUNT, request.getAuthorizationAmount()); + + if (request.getAuthorizationCurrencyCode() == null) { + request.setAuthorizationCurrencyCode(payConfig.getCurrencyCode()); + } + parameters.put(ServiceConstants.AUTHORIZATION_CURRENCEYCODE, request.getAuthorizationCurrencyCode().toString()); + } + addClientParameters(parameters, request); return Util.convertParameterMapToString(parameters); } @@ -298,9 +314,9 @@ public String getPostURL(CloseAuthorizationRequest request) { public String getPostURL(RefundRequest request) { Map parameters = new TreeMap(); parameters.put(ServiceConstants.ACTION, ServiceConstants.REFUND); - if (request.getRefundCurrencyCode() == null) + if (request.getRefundCurrencyCode() == null) { request.setRefundCurrencyCode(payConfig.getCurrencyCode()); - + } if (request.getAmazonCaptureId() != null) { parameters.put(ServiceConstants.AMAZON_CAPTURE_ID, request.getAmazonCaptureId()); } @@ -432,13 +448,13 @@ public String getPostURL(AuthorizeOnBillingAgreementRequest request) { request.setAuthorizationCurrencyCode(payConfig.getCurrencyCode()); if (request.getAmazonBillingAgreementId() != null) parameters.put(ServiceConstants.AMAZON_BILLING_AGREEMENT_ID, request.getAmazonBillingAgreementId()); - if (request.getAuthorizationReferenceId() != null) + if (request.getAuthorizationReferenceId() != null) parameters.put(ServiceConstants.AUTHORIZATION_REFERENCE_ID, request.getAuthorizationReferenceId()); - if (request.getAuthorizationAmount() != null) + if (request.getAuthorizationAmount() != null) parameters.put(ServiceConstants.AUTHORIZATION_AMOUNT, request.getAuthorizationAmount()); - if (request.getAuthorizationCurrencyCode() != null) + if (request.getAuthorizationCurrencyCode() != null) parameters.put(ServiceConstants.AUTHORIZATION_CURRENCEYCODE, request.getAuthorizationCurrencyCode().toString()); - if (request.getSellerAuthorizationNote() != null) + if (request.getSellerAuthorizationNote() != null) parameters.put(ServiceConstants.SELLER_AUTHORIZATION_NOTE, request.getSellerAuthorizationNote()); if (request.getTransactionTimeout() != null) parameters.put(ServiceConstants.TRANSACTION_TIMEOUT, request.getTransactionTimeout()); diff --git a/src/com/amazon/pay/types/ServiceConstants.java b/src/com/amazon/pay/types/ServiceConstants.java index e496eca..074c376 100644 --- a/src/com/amazon/pay/types/ServiceConstants.java +++ b/src/com/amazon/pay/types/ServiceConstants.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2016-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. @@ -93,6 +93,8 @@ public class ServiceConstants { public static final String ORDER_ATTRIBUTES_SELLER_ORDER_ID = "OrderAttributes.SellerOrderAttributes.SellerOrderId"; public static final String ORDER_ATTRIBUTES_STORE_NAME = "OrderAttributes.SellerOrderAttributes.StoreName"; public static final String ORDER_ATTRIBUTES_SUPPLEMENTARY_DATA = "OrderAttributes.SellerOrderAttributes.SupplementaryData"; + public static final String SUCCESS_URL = "SuccessUrl"; + public static final String FAILURE_URL = "FailureUrl"; // API Request Parameters - (Mostly) Required Parameters public static final String ACTION = "Action"; @@ -147,7 +149,7 @@ public class ServiceConstants { public static final String GET_MERCHANT_ACCOUNT_STATUS = "GetMerchantAccountStatus"; // SDK version - public static final String APPLICATION_LIBRARY_VERSION = "3.4.1"; + public static final String APPLICATION_LIBRARY_VERSION = "3.5.0"; public static final String GITHUB_SDK_NAME = "amazon-pay-sdk-java"; // Exponential backoff wait times (milliseconds) for retry operations diff --git a/tst/com/amazon/pay/TestConstants.java b/tst/com/amazon/pay/TestConstants.java index 97e7c62..6e192bb 100644 --- a/tst/com/amazon/pay/TestConstants.java +++ b/tst/com/amazon/pay/TestConstants.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2016-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. @@ -57,5 +57,8 @@ public class TestConstants { public static final int pageSize = 5; public static final String nextPageToken = "1eUc0QkJMVnJpcGgrbDNHclpIUT09IiwibWFya2V0cGxhY2VJZCI6IkEzQlhCMFlOM1hIMTdIIn0="; public static final String SUPPLEMENTARY_DATA = "{\"AirlineMetaData\" : {\"version\": 1.0, \"airlineCode\": \"PAX\", \"flightDate\": \"2018-03-24T20:29:19.22Z\", \"departureAirport\": \"CDG\", \"destinationAirport\": \"LUX\", \"bookedLastTime\": -1, \"classOfTravel\": \"F\", \"passengers\": {\"numberOfPassengers\": 4, \"numberOfChildren\": 1, \"numberOfInfants\": 1 }}, \"AccommodationMetaData\": {\"version\": 1.0, \"startDate\": \"2018-03-24T20:29:19.22Z\", \"endDate\": \"2018-03-24T20:29:19.22Z\", \"lengthOfStay\": 5, \"numberOfGuests\": 4, \"class\": \"Standard\", \"starRating\": 5, \"bookedLastTime\": -1 }, \"OrderMetaData\": {\"version\": 1.0, \"numberOfItems\": 3, \"type\": \"Digital\" }, \"BuyerMetaData\": {\"version\" : 1.0, \"isFirstTimeCustomer\" : true, \"numberOfPastPurchases\" : 2, \"numberOfDisputedPurchases\" : 3, \"hasOpenDispute\" : true, \"riskScore\" : 0.75 }}"; + public static final String AUTHORIZE_AMOUNT = "0.01"; + public static final String SUCCESS_URL = "https://pay.amazon.com/success.html"; + public static final String FAILURE_URL = "https://pay.amazon.com/failure.html"; } diff --git a/tst/com/amazon/pay/impl/SignatureAndURLTest.java b/tst/com/amazon/pay/impl/SignatureAndURLTest.java index d233769..8773aca 100644 --- a/tst/com/amazon/pay/impl/SignatureAndURLTest.java +++ b/tst/com/amazon/pay/impl/SignatureAndURLTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ import com.amazon.pay.request.RequestHelper; import com.amazon.pay.TestConstants; +import com.amazon.pay.request.ConfirmOrderReferenceRequest; import com.amazon.pay.request.GetOrderReferenceDetailsRequest; import com.amazon.pay.request.SetOrderReferenceDetailsRequest; import com.amazon.pay.response.model.Environment; @@ -117,4 +118,76 @@ public void testRequestParameterConstructorSignature_2() throws Exception { Assert.assertEquals(expectedURL, this.helper.getPostURL(request)); } + @Test + public void testRequestUrlAndSignatureForConfirmOrderReference() throws Exception { + // Non-MFA Confirm request + this.helper = new RequestHelper(config); + PowerMockito.stub(PowerMockito.method(Util.class, "getTimestamp")).toReturn(TestConstants.timeStamp); + final ConfirmOrderReferenceRequest request = + new ConfirmOrderReferenceRequest(TestConstants.amazonOrderReferenceId) + .setSellerId(TestConstants.overrideSellerId) + .setMWSAuthToken(TestConstants.mwsAuthToken); + final String action = "ConfirmOrderReference"; + final String signature = "mbJBrZKC4Jz8J%2BrhRqyfYsY6TkSapWOvCTlC%2BUDUTok%3D"; + final String expectedURL = + "AWSAccessKeyId=" + TestConstants.accessKey + + "&Action=" + action + + "&AmazonOrderReferenceId=" + TestConstants.amazonOrderReferenceId + + "&MWSAuthToken=" + TestConstants.mwsAuthToken + + "&SellerId=" + TestConstants.overrideSellerId + + "&Signature=" + signature + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&Timestamp=" + TestConstants.urlEncoded_TimeStamp + + "&Version=2013-01-01"; + Assert.assertEquals(expectedURL, this.helper.getPostURL(request)); + + // Adding a curency code without an amount should result in same request + request.setAuthorizationCurrencyCode(CurrencyCode.EUR); + Assert.assertEquals(expectedURL, this.helper.getPostURL(request)); + + // Full MFA parameter set + final String mfaSignature = "KeZbecFqPMxhR4g35iFWsdLmq1rAgwdn4B2WTIFMTHg%3D"; + request.setSuccessUrl(TestConstants.SUCCESS_URL); + request.setFailureUrl(TestConstants.FAILURE_URL); + request.setAuthorizationAmount(TestConstants.AUTHORIZE_AMOUNT); + final String expectedURLforMFA = + "AWSAccessKeyId=" + TestConstants.accessKey + + "&Action=" + action + + "&AmazonOrderReferenceId=" + TestConstants.amazonOrderReferenceId + + "&AuthorizationAmount.Amount=" + TestConstants.AUTHORIZE_AMOUNT + + "&AuthorizationAmount.CurrencyCode=" + CurrencyCode.EUR + + "&FailureUrl=" + Util.urlEncode(TestConstants.FAILURE_URL) + + "&MWSAuthToken=" + TestConstants.mwsAuthToken + + "&SellerId=" + TestConstants.overrideSellerId + + "&Signature=" + mfaSignature + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&SuccessUrl=" + Util.urlEncode(TestConstants.SUCCESS_URL) + + "&Timestamp=" + TestConstants.urlEncoded_TimeStamp + + "&Version=2013-01-01"; + Assert.assertEquals(expectedURLforMFA, this.helper.getPostURL(request)); + + // Partial MFA parameter set - not including FailureURL or CurrencyCode + // Should default to the Config object currency code in this scenario (USD instead of EUR) + final String partialMfaSignature = "vGiWtNsdtNKx3QGB%2BcNNq8tLisqwOeg2a5aIy3p6exw%3D"; + request.setAuthorizationCurrencyCode(null); + request.setFailureUrl(null); + final String expectedURLforPartialMFA = + "AWSAccessKeyId=" + TestConstants.accessKey + + "&Action=" + action + + "&AmazonOrderReferenceId=" + TestConstants.amazonOrderReferenceId + + "&AuthorizationAmount.Amount=" + TestConstants.AUTHORIZE_AMOUNT + + "&AuthorizationAmount.CurrencyCode=" + CurrencyCode.USD + + "&MWSAuthToken=" + TestConstants.mwsAuthToken + + "&SellerId=" + TestConstants.overrideSellerId + + "&Signature=" + partialMfaSignature + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&SuccessUrl=" + Util.urlEncode(TestConstants.SUCCESS_URL) + + "&Timestamp=" + TestConstants.urlEncoded_TimeStamp + + "&Version=2013-01-01"; + Assert.assertEquals(expectedURLforPartialMFA, this.helper.getPostURL(request)); + } + } diff --git a/tst/com/amazon/pay/request/PaymentsAPIRequestTest.java b/tst/com/amazon/pay/request/PaymentsAPIRequestTest.java index df4f285..5c42fc0 100644 --- a/tst/com/amazon/pay/request/PaymentsAPIRequestTest.java +++ b/tst/com/amazon/pay/request/PaymentsAPIRequestTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. @@ -118,10 +118,18 @@ public void testCloseOrderReferenceRequest() { @Test public void testConfirmOrderReferenceRequest() { final ConfirmOrderReferenceRequest request = new ConfirmOrderReferenceRequest(TestConstants.amazonOrderReferenceId) - .setMWSAuthToken(TestConstants.mwsAuthToken); + .setMWSAuthToken(TestConstants.mwsAuthToken) + .setAuthorizationAmount(TestConstants.AUTHORIZE_AMOUNT) + .setAuthorizationCurrencyCode(CurrencyCode.EUR) + .setSuccessUrl(TestConstants.SUCCESS_URL) + .setFailureUrl(TestConstants.FAILURE_URL); Assert.assertEquals(request.getAmazonOrderReferenceId(),TestConstants.amazonOrderReferenceId); Assert.assertEquals(request.getMwsAuthToken(), TestConstants.mwsAuthToken); + Assert.assertEquals(request.getAuthorizationAmount(), TestConstants.AUTHORIZE_AMOUNT); + Assert.assertEquals(request.getAuthorizationCurrencyCode(), CurrencyCode.EUR); + Assert.assertEquals(request.getSuccessUrl(), TestConstants.SUCCESS_URL); + Assert.assertEquals(request.getFailureUrl(), TestConstants.FAILURE_URL); } @Test