Skip to content

Commit

Permalink
Overload PaymentSession#presentPaymentMethodSelection to require post…
Browse files Browse the repository at this point in the history
…al code (#1001)

* Overload PaymentSession#presentPaymentMethodSelection to require postal field

- `PaymentSession#presentPaymentMethodSelection()` will not require postal code
  for the added payment method (existing behavior)

- `PaymentSession#presentPaymentMethodSelection(true)` will require postal code
  for the added payment method

If true, require postal field when adding a payment method

* Update MIGRATING.md
  • Loading branch information
mshafrir-stripe authored May 28, 2019
1 parent ee9584e commit b9ec651
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 72 deletions.
5 changes: 5 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
### Migration from versions < 9.1.0
- `CustomerSession#getPaymentMethods()` and `CustomerSession#attachPaymentMethod()` have been added
- `PaymentSessionData#getSelectedPaymentMethodId()` is now `PaymentSessionData#getPaymentMethod()` and returns a `PaymentMethod`. See usage in the samplestore app's [PaymentActivity.java](https://github.com/stripe/stripe-android/blob/194fef4c1c1981b8423125f26abf4b23f12631f8/samplestore/src/main/java/com/stripe/samplestore/PaymentActivity.java).
- Remove the following unused methods from `PaymentConfiguration`
- `getRequiredBillingAddressFields()`
- `setRequiredBillingAddressFields()`
- `getShouldUseSourcesForCards()`
- `setShouldUseSourcesForCards()`

### Migration from versions < 9.0.0
- `minSdkVersion` is now 19
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,8 @@ private boolean isValidShippingInfo(@NonNull ShippingInformation shippingInfo) {
localBroadcastManager.registerReceiver(mBroadcastReceiver,
new IntentFilter(EVENT_SHIPPING_INFO_SUBMITTED));
mSelectPaymentButton.setOnClickListener(v ->
mPaymentSession.presentPaymentMethodSelection());
mPaymentSession.presentPaymentMethodSelection(true));
mSelectShippingButton.setOnClickListener(v -> mPaymentSession.presentShippingFlow());

}

private void setupCustomerSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
mCompositeDisposable.add(RxView.clicks(mEnterShippingInfo)
.subscribe(aVoid -> mPaymentSession.presentShippingFlow()));
mCompositeDisposable.add(RxView.clicks(mEnterPaymentInfo)
.subscribe(aVoid -> mPaymentSession.presentPaymentMethodSelection()));
.subscribe(aVoid -> mPaymentSession.presentPaymentMethodSelection(true)));
mCompositeDisposable.add(RxView.clicks(mConfirmPaymentButton)
.subscribe(aVoid -> CustomerSession.getInstance().retrieveCurrentCustomer(
new AttemptPurchaseCustomerRetrievalListener(
Expand Down
34 changes: 2 additions & 32 deletions stripe/src/main/java/com/stripe/android/PaymentConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package com.stripe.android;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;

import com.stripe.android.model.Address;

public class PaymentConfiguration {

private static PaymentConfiguration mInstance;

@Nullable private static PaymentConfiguration mInstance;
@NonNull private final String mPublishableKey;
@Address.RequiredBillingAddressFields private int mRequiredBillingAddressFields;
private boolean mShouldUseSourcesForCards; // deprecated- this value is not used.

private PaymentConfiguration(@NonNull String publishableKey) {
mPublishableKey = publishableKey;
Expand All @@ -28,39 +24,13 @@ public static PaymentConfiguration getInstance() {

public static void init(@NonNull String publishableKey) {
mInstance = new PaymentConfiguration(publishableKey);
mInstance.mRequiredBillingAddressFields = Address.RequiredBillingAddressFields.NONE;
mInstance.mShouldUseSourcesForCards = true;
}

@NonNull
public String getPublishableKey() {
return mPublishableKey;
}

@Address.RequiredBillingAddressFields
public int getRequiredBillingAddressFields() {
return mRequiredBillingAddressFields;
}

@NonNull
public PaymentConfiguration setRequiredBillingAddressFields(
@Address.RequiredBillingAddressFields int requiredBillingAddressFields) {
mRequiredBillingAddressFields = requiredBillingAddressFields;
return this;
}

@Deprecated
public boolean getShouldUseSourcesForCards() {
return mShouldUseSourcesForCards;
}

@Deprecated
@NonNull
public PaymentConfiguration setShouldUseSourcesForCards(boolean shouldUseSourcesForCards) {
mShouldUseSourcesForCards = shouldUseSourcesForCards;
return this;
}

@VisibleForTesting
static void clearInstance() {
mInstance = null;
Expand Down
19 changes: 15 additions & 4 deletions stripe/src/main/java/com/stripe/android/PaymentSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import com.stripe.android.model.Customer;
import com.stripe.android.model.PaymentMethod;
import com.stripe.android.view.AddPaymentMethodActivity;
import com.stripe.android.view.PaymentFlowActivity;
import com.stripe.android.view.PaymentMethodsActivity;
import com.stripe.android.view.PaymentMethodsActivityStarter;
Expand Down Expand Up @@ -185,12 +186,22 @@ public boolean init(
* or to add a new one.
*/
public void presentPaymentMethodSelection() {
presentPaymentMethodSelection(false);
}

/**
* @param shouldRequirePostalCode if true, require postal code when adding a payment method
*/
public void presentPaymentMethodSelection(boolean shouldRequirePostalCode) {
final Intent paymentMethodsIntent = mPaymentMethodsActivityStarter.newIntent()
.putExtra(EXTRA_PAYMENT_SESSION_ACTIVE, true);
.putExtra(EXTRA_PAYMENT_SESSION_ACTIVE, true)
.putExtra(AddPaymentMethodActivity.EXTRA_SHOULD_REQUIRE_POSTAL_CODE,
shouldRequirePostalCode);
if (mPaymentSessionData.getPaymentMethod() != null) {
paymentMethodsIntent.putExtra(
PaymentMethodsActivity.EXTRA_INITIAL_SELECTED_PAYMENT_METHOD_ID,
mPaymentSessionData.getPaymentMethod().id);
paymentMethodsIntent
.putExtra(
PaymentMethodsActivity.EXTRA_INITIAL_SELECTED_PAYMENT_METHOD_ID,
mPaymentSessionData.getPaymentMethod().id);
}
mHostActivity.startActivityForResult(paymentMethodsIntent, PAYMENT_METHOD_REQUEST);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@
*/
public class AddPaymentMethodActivity extends StripeActivity {

public static final String TOKEN_ADD_PAYMENT_METHOD_ACTIVITY = "AddPaymentMethodActivity";

public static final String EXTRA_NEW_PAYMENT_METHOD = "new_payment_method";
public static final String EXTRA_SHOULD_REQUIRE_POSTAL_CODE = "require_postal";

public static final String TOKEN_ADD_PAYMENT_METHOD_ACTIVITY = "AddPaymentMethodActivity";
static final String EXTRA_SHOW_ZIP = "show_zip";
static final String EXTRA_PROXY_DELAY = "proxy_delay";
static final String EXTRA_UPDATE_CUSTOMER = "update_customer";

Expand All @@ -52,18 +53,18 @@ public class AddPaymentMethodActivity extends StripeActivity {
* Create an {@link Intent} to start a {@link AddPaymentMethodActivity}.
*
* @param context the {@link Context} used to launch the activity
* @param requirePostalField {@code true} to require a postal code field
* @param shouldRequirePostalCode {@code true} to require the postal code
* @param updatesCustomer {@code true} if the activity should update using an
* already-initialized {@link CustomerSession}, or {@code false} if it should just
* return a source.
* @return an {@link Intent} that can be used to start this activity
*/
@NonNull
public static Intent newIntent(@NonNull Context context,
boolean requirePostalField,
boolean shouldRequirePostalCode,
boolean updatesCustomer) {
return new Intent(context, AddPaymentMethodActivity.class)
.putExtra(EXTRA_SHOW_ZIP, requirePostalField)
.putExtra(EXTRA_SHOULD_REQUIRE_POSTAL_CODE, shouldRequirePostalCode)
.putExtra(EXTRA_UPDATE_CUSTOMER, updatesCustomer);
}

Expand All @@ -75,11 +76,12 @@ protected void onCreate(Bundle savedInstanceState) {
mViewStub.inflate();
mCardMultilineWidget = findViewById(R.id.add_source_card_entry_widget);
initEnterListeners(mCardMultilineWidget);
final boolean showZip = getIntent().getBooleanExtra(EXTRA_SHOW_ZIP, false);
final boolean shouldShowPostalCode = getIntent()
.getBooleanExtra(EXTRA_SHOULD_REQUIRE_POSTAL_CODE, false);
mUpdatesCustomer = getIntent().getBooleanExtra(EXTRA_UPDATE_CUSTOMER, false);
mStartedFromPaymentSession =
getIntent().getBooleanExtra(EXTRA_PAYMENT_SESSION_ACTIVE, true);
mCardMultilineWidget.setShouldShowPostalCode(showZip);
mCardMultilineWidget.setShouldShowPostalCode(shouldShowPostalCode);

if (mUpdatesCustomer && !getIntent().getBooleanExtra(EXTRA_PROXY_DELAY, false)) {
initCustomerSessionTokens();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static Intent newIntent(@NonNull Activity activity) {
}

@Override
protected void onCreate(Bundle savedInstanceState) {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment_methods);

Expand All @@ -73,17 +73,19 @@ protected void onCreate(Bundle savedInstanceState) {
mCustomerSession = CustomerSession.getInstance();
mStartedFromPaymentSession = getIntent().hasExtra(EXTRA_PAYMENT_SESSION_ACTIVE);

final boolean shouldShowPostalField = getIntent()
.getBooleanExtra(AddPaymentMethodActivity.EXTRA_SHOULD_REQUIRE_POSTAL_CODE, false);
addCardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(@NonNull View view) {
final Intent addSourceIntent = AddPaymentMethodActivity.newIntent(
final Intent addPaymentMethodIntent = AddPaymentMethodActivity.newIntent(
PaymentMethodsActivity.this,
false,
shouldShowPostalField,
true);
if (mStartedFromPaymentSession) {
addSourceIntent.putExtra(EXTRA_PAYMENT_SESSION_ACTIVE, true);
addPaymentMethodIntent.putExtra(EXTRA_PAYMENT_SESSION_ACTIVE, true);
}
startActivityForResult(addSourceIntent, REQUEST_CODE_ADD_CARD);
startActivityForResult(addPaymentMethodIntent, REQUEST_CODE_ADD_CARD);
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.stripe.android;

import com.stripe.android.model.Address;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -31,19 +29,7 @@ public void getInstance_beforeInit_throwsRuntimeException() {
@Test
public void getInstance_withPublicKey_returnsDefaultInstance() {
PaymentConfiguration.init("pk_test_key");
PaymentConfiguration payConfig = PaymentConfiguration.getInstance();
assertEquals("pk_test_key", payConfig.getPublishableKey());
assertEquals(Address.RequiredBillingAddressFields.NONE, payConfig.getRequiredBillingAddressFields());
}

@Test
public void setValues_setsForSingletonInstance() {
PaymentConfiguration.init("pk_test_key");
PaymentConfiguration.getInstance()
.setRequiredBillingAddressFields(Address.RequiredBillingAddressFields.FULL);

assertEquals("pk_test_key", PaymentConfiguration.getInstance().getPublishableKey());
assertEquals(Address.RequiredBillingAddressFields.FULL,
PaymentConfiguration.getInstance().getRequiredBillingAddressFields());
assertEquals("pk_test_key",
PaymentConfiguration.getInstance().getPublishableKey());
}
}
26 changes: 21 additions & 5 deletions stripe/src/test/java/com/stripe/android/PaymentSessionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.stripe.android.model.PaymentMethodCreateParams;
import com.stripe.android.model.PaymentMethodTest;
import com.stripe.android.testharness.TestEphemeralKeyProvider;
import com.stripe.android.view.AddPaymentMethodActivity;
import com.stripe.android.view.PaymentMethodsActivity;

import org.junit.Before;
Expand Down Expand Up @@ -156,7 +157,6 @@ public void setCartTotal_setsExpectedValueAndNotifiesListener() {

@Test
public void handlePaymentData_whenPaymentMethodRequest_notifiesListenerAndFetchesCustomer() {
mEphemeralKeyProvider.setNextRawEphemeralKey(FIRST_SAMPLE_KEY_RAW);
CustomerSession.setInstance(createCustomerSession());

PaymentSession paymentSession = new PaymentSession(mActivity);
Expand All @@ -182,7 +182,6 @@ public void handlePaymentData_whenPaymentMethodRequest_notifiesListenerAndFetche

@Test
public void selectPaymentMethod_launchesPaymentMethodsActivityWithLog() {
mEphemeralKeyProvider.setNextRawEphemeralKey(FIRST_SAMPLE_KEY_RAW);
CustomerSession.setInstance(createCustomerSession());

final PaymentSession paymentSession = new PaymentSession(mActivity);
Expand All @@ -198,11 +197,30 @@ public void selectPaymentMethod_launchesPaymentMethodsActivityWithLog() {
assertEquals(PaymentMethodsActivity.class.getName(),
intent.getComponent().getClassName());
assertTrue(intent.hasExtra(EXTRA_PAYMENT_SESSION_ACTIVE));
assertFalse(
intent.getBooleanExtra(AddPaymentMethodActivity.EXTRA_SHOULD_REQUIRE_POSTAL_CODE,
false));
}

@Test
public void presentPaymentMethodSelection_withShouldRequirePostalCode_shouldPassInIntent() {
CustomerSession.setInstance(createCustomerSession());

final PaymentSession paymentSession = new PaymentSession(mActivity);
paymentSession.init(mPaymentSessionListener, new PaymentSessionConfig.Builder().build());
paymentSession.presentPaymentMethodSelection(true);

verify(mActivity).startActivityForResult(mIntentArgumentCaptor.capture(),
eq(PaymentSession.PAYMENT_METHOD_REQUEST));

final Intent intent = mIntentArgumentCaptor.getValue();
assertTrue(
intent.getBooleanExtra(AddPaymentMethodActivity.EXTRA_SHOULD_REQUIRE_POSTAL_CODE,
false));
}

@Test
public void init_withoutSavedState_clearsLoggingTokensAndStartsWithPaymentSession() {
mEphemeralKeyProvider.setNextRawEphemeralKey(FIRST_SAMPLE_KEY_RAW);
final CustomerSession customerSession = createCustomerSession();
CustomerSession.setInstance(customerSession);
customerSession
Expand All @@ -221,7 +239,6 @@ public void init_withoutSavedState_clearsLoggingTokensAndStartsWithPaymentSessio

@Test
public void init_withSavedStateBundle_doesNotClearLoggingTokens() {
mEphemeralKeyProvider.setNextRawEphemeralKey(FIRST_SAMPLE_KEY_RAW);
final CustomerSession customerSession = createCustomerSession();
CustomerSession.setInstance(customerSession);
customerSession
Expand All @@ -241,7 +258,6 @@ public void init_withSavedStateBundle_doesNotClearLoggingTokens() {

@Test
public void completePayment_withLoggedActions_clearsLoggingTokensAndSetsResult() {
mEphemeralKeyProvider.setNextRawEphemeralKey(FIRST_SAMPLE_KEY_RAW);
final CustomerSession customerSession = createCustomerSession();
CustomerSession.setInstance(customerSession);
customerSession
Expand Down

0 comments on commit b9ec651

Please sign in to comment.