From b013acb22a8a560aec3750a524ba9cf274a8cc30 Mon Sep 17 00:00:00 2001 From: Michael Shafrir Date: Tue, 5 Mar 2019 15:03:44 -0500 Subject: [PATCH] Support save to customer param on PaymentIntent confirm **Summary** Add support for setting the `save_payment_method` param when using PaymentMethod, or `save_source_to_customer` when using Source. **Motivation** ANDROID-331 **Testing** Wrote unit tests --- .../android/model/PaymentIntentParams.java | 111 ++++++++++++++++-- .../model/PaymentIntentParamsTest.java | 61 +++++++++- 2 files changed, 160 insertions(+), 12 deletions(-) diff --git a/stripe/src/main/java/com/stripe/android/model/PaymentIntentParams.java b/stripe/src/main/java/com/stripe/android/model/PaymentIntentParams.java index 949e962b411..f8742b6ddb4 100644 --- a/stripe/src/main/java/com/stripe/android/model/PaymentIntentParams.java +++ b/stripe/src/main/java/com/stripe/android/model/PaymentIntentParams.java @@ -18,6 +18,9 @@ public class PaymentIntentParams { static final String API_PARAM_RETURN_URL = "return_url"; static final String API_PARAM_CLIENT_SECRET = "client_secret"; + static final String API_PARAM_SAVE_PAYMENT_METHOD = "save_payment_method"; + static final String API_PARAM_SAVE_SOURCE_TO_CUSTOMER = "save_source_to_customer"; + @Nullable private PaymentMethodCreateParams mPaymentMethodCreateParams; @Nullable private String mPaymentMethodId; @Nullable private SourceParams mSourceParams; @@ -27,6 +30,8 @@ public class PaymentIntentParams { @Nullable private String mClientSecret; @Nullable private String mReturnUrl; + private boolean mSaveToCustomer; + private PaymentIntentParams() { } @@ -42,7 +47,6 @@ public static PaymentIntentParams createCustomParams() { return new PaymentIntentParams(); } - /** * Create the parameters necessary for confirming a PaymentIntent while attaching a * PaymentMethod that already exits. @@ -52,17 +56,33 @@ public static PaymentIntentParams createCustomParams() { * @param clientSecret client secret from the PaymentIntent being confirmed * @param returnUrl the URL the customer should be redirected to after the authorization * process + * @param saveToCustomer Set to {@code true} to save this PaymentIntent’s payment method to the + * associated Customer, if the payment method is not already attached. + * This parameter only applies to the payment method passed in the same + * request or the current payment method attached to the PaymentIntent and + * must be specified again if a new payment method is added. * @return params that can be use to confirm a PaymentIntent */ @NonNull public static PaymentIntentParams createConfirmPaymentIntentWithPaymentMethodId( @Nullable String paymentMethodId, @NonNull String clientSecret, - @NonNull String returnUrl) { + @NonNull String returnUrl, + boolean saveToCustomer) { return new PaymentIntentParams() .setPaymentMethodId(paymentMethodId) .setClientSecret(clientSecret) - .setReturnUrl(returnUrl); + .setReturnUrl(returnUrl) + .setSaveToCustomer(saveToCustomer); + } + + @NonNull + public static PaymentIntentParams createConfirmPaymentIntentWithPaymentMethodId( + @Nullable String paymentMethodId, + @NonNull String clientSecret, + @NonNull String returnUrl) { + return createConfirmPaymentIntentWithPaymentMethodId(paymentMethodId, clientSecret, + returnUrl, false); } /** @@ -74,17 +94,33 @@ public static PaymentIntentParams createConfirmPaymentIntentWithPaymentMethodId( * @param clientSecret client secret from the PaymentIntent that is to be confirmed * @param returnUrl the URL the customer should be redirected to after the authorization * process + * @param saveToCustomer Set to {@code true} to save this PaymentIntent’s payment method to the + * associated Customer, if the payment method is not already attached. + * This parameter only applies to the payment method passed in the same + * request or the current payment method attached to the PaymentIntent and + * must be specified again if a new payment method is added. * @return params that can be use to confirm a PaymentIntent */ @NonNull public static PaymentIntentParams createConfirmPaymentIntentWithPaymentMethodCreateParams( @Nullable PaymentMethodCreateParams paymentMethodCreateParams, @NonNull String clientSecret, - @NonNull String returnUrl) { + @NonNull String returnUrl, + boolean saveToCustomer) { return new PaymentIntentParams() .setPaymentMethodCreateParams(paymentMethodCreateParams) .setClientSecret(clientSecret) - .setReturnUrl(returnUrl); + .setReturnUrl(returnUrl) + .setSaveToCustomer(saveToCustomer); + } + + @NonNull + public static PaymentIntentParams createConfirmPaymentIntentWithPaymentMethodCreateParams( + @Nullable PaymentMethodCreateParams paymentMethodCreateParams, + @NonNull String clientSecret, + @NonNull String returnUrl) { + return createConfirmPaymentIntentWithPaymentMethodCreateParams(paymentMethodCreateParams, + clientSecret, returnUrl, false); } /** @@ -96,17 +132,33 @@ public static PaymentIntentParams createConfirmPaymentIntentWithPaymentMethodCre * @param clientSecret client secret from the PaymentIntent being confirmed * @param returnUrl the URL the customer should be redirected to after the authorization * process + * @param saveToCustomer Set to {@code true} to save this PaymentIntent’s source to the + * associated Customer, if the source is not already attached. + * This parameter only applies to the source passed in the same request + * or the current source attached to the PaymentIntent and must be + * specified again if a new source is added. * @return params that can be use to confirm a PaymentIntent */ @NonNull public static PaymentIntentParams createConfirmPaymentIntentWithSourceIdParams( @Nullable String sourceId, @NonNull String clientSecret, - @NonNull String returnUrl) { + @NonNull String returnUrl, + boolean saveToCustomer) { return new PaymentIntentParams() .setSourceId(sourceId) .setClientSecret(clientSecret) - .setReturnUrl(returnUrl); + .setReturnUrl(returnUrl) + .setSaveToCustomer(saveToCustomer); + } + + @NonNull + public static PaymentIntentParams createConfirmPaymentIntentWithSourceIdParams( + @Nullable String sourceId, + @NonNull String clientSecret, + @NonNull String returnUrl) { + return createConfirmPaymentIntentWithSourceIdParams(sourceId, clientSecret, returnUrl, + false); } /** @@ -116,17 +168,33 @@ public static PaymentIntentParams createConfirmPaymentIntentWithSourceIdParams( * @param clientSecret client secret from the PaymentIntent that is to be confirmed * @param returnUrl the URL the customer should be redirected to after the authorization * process + * @param saveToCustomer Set to {@code true} to save this PaymentIntent’s source to the + * associated Customer, if the source is not already attached. + * This parameter only applies to the source passed in the same request + * or the current source attached to the PaymentIntent and must be + * specified again if a new source is added. * @return params that can be use to confirm a PaymentIntent */ @NonNull public static PaymentIntentParams createConfirmPaymentIntentWithSourceDataParams( @Nullable SourceParams sourceParams, @NonNull String clientSecret, - @NonNull String returnUrl) { + @NonNull String returnUrl, + boolean saveToCustomer) { return new PaymentIntentParams() .setSourceParams(sourceParams) .setClientSecret(clientSecret) - .setReturnUrl(returnUrl); + .setReturnUrl(returnUrl) + .setSaveToCustomer(saveToCustomer); + } + + @NonNull + public static PaymentIntentParams createConfirmPaymentIntentWithSourceDataParams( + @Nullable SourceParams sourceParams, + @NonNull String clientSecret, + @NonNull String returnUrl) { + return createConfirmPaymentIntentWithSourceDataParams(sourceParams, clientSecret, returnUrl, + false); } /** @@ -138,7 +206,8 @@ public static PaymentIntentParams createConfirmPaymentIntentWithSourceDataParams @NonNull public static PaymentIntentParams createRetrievePaymentIntentParams( @NonNull String clientSecret) { - return new PaymentIntentParams().setClientSecret(clientSecret); + return new PaymentIntentParams() + .setClientSecret(clientSecret); } /** @@ -228,6 +297,12 @@ public PaymentIntentParams setExtraParams(@Nullable Map extraPar return this; } + @NonNull + public PaymentIntentParams setSaveToCustomer(boolean saveToCustomer) { + mSaveToCustomer = saveToCustomer; + return this; + } + /** * Create a string-keyed map representing this object that is * ready to be sent over the network. @@ -256,6 +331,18 @@ public Map toParamMap() { if (mExtraParams != null) { networkReadyMap.putAll(mExtraParams); } + + if (mSaveToCustomer) { + final String saveToCustomerParam; + if (mPaymentMethodCreateParams != null || mPaymentMethodId != null) { + saveToCustomerParam = API_PARAM_SAVE_PAYMENT_METHOD; + } else { + saveToCustomerParam = API_PARAM_SAVE_SOURCE_TO_CUSTOMER; + } + + networkReadyMap.put(saveToCustomerParam, true); + } + return networkReadyMap; } @@ -315,4 +402,8 @@ public String getPaymentMethodId() { public String getReturnUrl() { return mReturnUrl; } + + public boolean shouldSaveToCustomer() { + return mSaveToCustomer; + } } diff --git a/stripe/src/test/java/com/stripe/android/model/PaymentIntentParamsTest.java b/stripe/src/test/java/com/stripe/android/model/PaymentIntentParamsTest.java index 65ef3899cf8..de3ecd9d13a 100644 --- a/stripe/src/test/java/com/stripe/android/model/PaymentIntentParamsTest.java +++ b/stripe/src/test/java/com/stripe/android/model/PaymentIntentParamsTest.java @@ -10,6 +10,9 @@ import java.util.Map; import static com.stripe.android.view.CardInputTestActivity.VALID_VISA_NO_SPACES; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; @RunWith(RobolectricTestRunner.class) public class PaymentIntentParamsTest { @@ -46,6 +49,7 @@ public void createConfirmPaymentIntentWithSourceDataParams_withAllFields_hasExpe Assert.assertEquals(TEST_CLIENT_SECRET, params.getClientSecret()); Assert.assertEquals(TEST_RETURN_URL, params.getReturnUrl()); Assert.assertEquals(sourceParams, params.getSourceParams()); + assertFalse(params.shouldSaveToCustomer()); } @Test @@ -57,6 +61,22 @@ public void createConfirmPaymentIntentWithSourceIdParams_withAllFields_hasExpect Assert.assertEquals(TEST_CLIENT_SECRET, params.getClientSecret()); Assert.assertEquals(TEST_RETURN_URL, params.getReturnUrl()); Assert.assertEquals(TEST_SOURCE_ID, params.getSourceId()); + assertFalse(params.shouldSaveToCustomer()); + } + + @Test + public void createConfirmPaymentIntentWithSourceIdParams_withSaveToCustomer_hasExpectedFields() { + final PaymentIntentParams params = PaymentIntentParams + .createConfirmPaymentIntentWithSourceIdParams( + TEST_SOURCE_ID, TEST_CLIENT_SECRET, TEST_RETURN_URL, true); + + Assert.assertEquals(TEST_CLIENT_SECRET, params.getClientSecret()); + Assert.assertEquals(TEST_RETURN_URL, params.getReturnUrl()); + Assert.assertEquals(TEST_SOURCE_ID, params.getSourceId()); + assertTrue(params.shouldSaveToCustomer()); + + assertEquals(Boolean.TRUE, + params.toParamMap().get(PaymentIntentParams.API_PARAM_SAVE_SOURCE_TO_CUSTOMER)); } @Test @@ -69,10 +89,11 @@ public void createRetrievePaymentIntentWithSourceIdParams_hasExpectedFields() { Assert.assertNull(params.getExtraParams()); Assert.assertNull(params.getSourceId()); Assert.assertNull(params.getSourceParams()); + assertFalse(params.shouldSaveToCustomer()); } @Test - public void createRetrievePaymentIntent_withPaymentMethodCreateParams_hasExpectedFields() { + public void createRetrievePaymentIntentwithPaymentMethodCreateParams_hasExpectedFields() { final PaymentMethodCreateParams paymentMethodCreateParams = PaymentMethodCreateParams.create(new PaymentMethodCreateParams.Card.Builder() .build(), null); @@ -83,10 +104,11 @@ public void createRetrievePaymentIntent_withPaymentMethodCreateParams_hasExpecte Assert.assertEquals(TEST_CLIENT_SECRET, params.getClientSecret()); Assert.assertEquals(TEST_RETURN_URL, params.getReturnUrl()); Assert.assertEquals(paymentMethodCreateParams, params.getPaymentMethodCreateParams()); + assertFalse(params.shouldSaveToCustomer()); } @Test - public void createRetrievePaymentIntent_withPaymentMethodId_hasExpectedFields() { + public void createConfirmPaymentIntentWithPaymentMethodId_hasExpectedFields() { final PaymentIntentParams params = PaymentIntentParams .createConfirmPaymentIntentWithPaymentMethodId( TEST_PAYMENT_METHOD_ID, TEST_CLIENT_SECRET, TEST_RETURN_URL); @@ -94,6 +116,37 @@ public void createRetrievePaymentIntent_withPaymentMethodId_hasExpectedFields() Assert.assertEquals(TEST_CLIENT_SECRET, params.getClientSecret()); Assert.assertEquals(TEST_RETURN_URL, params.getReturnUrl()); Assert.assertEquals(TEST_PAYMENT_METHOD_ID, params.getPaymentMethodId()); + assertFalse(params.shouldSaveToCustomer()); + } + + @Test + public void createConfirmPaymentIntentWithPaymentMethodCreateParams_withSaveToCustomer_hasExpectedFields() { + final PaymentMethodCreateParams paymentMethodCreateParams = + PaymentMethodCreateParams.create(new PaymentMethodCreateParams.Card.Builder() + .build(), null); + final PaymentIntentParams params = PaymentIntentParams + .createConfirmPaymentIntentWithPaymentMethodCreateParams(paymentMethodCreateParams, + TEST_CLIENT_SECRET, TEST_RETURN_URL, true); + + Assert.assertEquals(TEST_CLIENT_SECRET, params.getClientSecret()); + Assert.assertEquals(TEST_RETURN_URL, params.getReturnUrl()); + Assert.assertEquals(paymentMethodCreateParams, params.getPaymentMethodCreateParams()); + assertTrue(params.shouldSaveToCustomer()); + } + + @Test + public void createConfirmPaymentIntentWithPaymentMethodId_withSaveToCustomer_hasExpectedFields() { + final PaymentIntentParams params = PaymentIntentParams + .createConfirmPaymentIntentWithPaymentMethodId( + TEST_PAYMENT_METHOD_ID, TEST_CLIENT_SECRET, TEST_RETURN_URL, true); + + Assert.assertEquals(TEST_CLIENT_SECRET, params.getClientSecret()); + Assert.assertEquals(TEST_RETURN_URL, params.getReturnUrl()); + Assert.assertEquals(TEST_PAYMENT_METHOD_ID, params.getPaymentMethodId()); + assertTrue(params.shouldSaveToCustomer()); + + assertEquals(Boolean.TRUE, + params.toParamMap().get(PaymentIntentParams.API_PARAM_SAVE_PAYMENT_METHOD)); } @Test @@ -110,6 +163,8 @@ public void createCustomParams_toParamMap_createsExpectedMap() { paramMap.get(PaymentIntentParams.API_PARAM_CLIENT_SECRET), TEST_CLIENT_SECRET); Assert.assertEquals( paramMap.get(PaymentIntentParams.API_PARAM_RETURN_URL), TEST_RETURN_URL); + assertFalse(paramMap.containsKey(PaymentIntentParams.API_PARAM_SAVE_PAYMENT_METHOD)); + assertFalse(paramMap.containsKey(PaymentIntentParams.API_PARAM_SAVE_SOURCE_TO_CUSTOMER)); } @Test @@ -133,5 +188,7 @@ public void toParamMap_whenExtraParamsProvided_createsExpectedMap() { paramMap.get(extraParamKey1), extraParamValue1); Assert.assertEquals( paramMap.get(extraParamKey2), extraParamValue2); + assertFalse(paramMap.containsKey(PaymentIntentParams.API_PARAM_SAVE_PAYMENT_METHOD)); + assertFalse(paramMap.containsKey(PaymentIntentParams.API_PARAM_SAVE_SOURCE_TO_CUSTOMER)); } }