Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

breaking: use a cardDetails prop for AddToWalletButton component #913

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## Unreleased

- [#913](https://github.com/stripe/stripe-react-native/pull/913) BREAKING CHANGE: Changed props for the `<AddToWalletButton />` component. Instead of passing `cardHolderName`, `cardLastFour`, `cardDescription`, and `cardBrand` directly as props, you will instead pass a `cardDetails` prop, which is an object containing the following fields:
- `primaryAccountIdentifier`: The `wallet.primary_account_identifier` value from the issued card.
charliecruzan-stripe marked this conversation as resolved.
Show resolved Hide resolved
- `name`: The card holder name (previously `cardHolderName`).
- `description`: A user-facing description of the card (previously `cardDescription`).
- `lastFour`: Last 4 digits of the card, optional (previously `cardLastFour`).
- `brand`: The card brand, optional (previously `cardBrand`).
- [#913](https://github.com/stripe/stripe-react-native/pull/913) chore: Updated `stripe-ios` from 22.0.0 to 22.2.0.
- [#914](https://github.com/stripe/stripe-react-native/pull/914) fix: add `fingerprint` to Card result object on Android (already present on iOS)
- [#912](https://github.com/stripe/stripe-react-native/pull/912) fix: allow for providing zip code straight from `CardField` component on Android

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,9 @@ class AddToWalletButtonManager(applicationContext: ReactApplicationContext) : Si
view.setSourceMap(source)
}

@ReactProp(name = "cardDescription")
fun cardDescription(view: AddToWalletButtonView, cardDescription: String) {
view.setCardDescription(cardDescription)
}

@ReactProp(name = "cardLastFour")
fun cardLastFour(view: AddToWalletButtonView, last4: String) {
view.setCardLastFour(last4)
@ReactProp(name = "cardDetails")
fun cardDetails(view: AddToWalletButtonView, cardDetails: ReadableMap) {
view.setCardDetails(cardDetails)
}

@ReactProp(name = "ephemeralKey")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import com.reactnativestripesdk.createError


class AddToWalletButtonView(private val context: ThemedReactContext, private val requestManager: RequestManager) : AppCompatImageView(context) {
private var cardDescription: String? = null
private var cardLastFour: String? = null
private var cardDetails: ReadableMap? = null
private var ephemeralKey: String? = null
private var sourceMap: ReadableMap? = null
private var token: ReadableMap? = null
Expand All @@ -35,7 +34,8 @@ class AddToWalletButtonView(private val context: ThemedReactContext, private val

override fun performClick(): Boolean {
super.performClick()
cardDescription?.let { cardDescription ->

cardDetails?.getString("description")?.let { cardDescription ->
ephemeralKey?.let { ephemeralKey ->
PushProvisioningProxy.invoke(
context.reactApplicationContext,
Expand All @@ -50,7 +50,7 @@ class AddToWalletButtonView(private val context: ThemedReactContext, private val
}
} ?: run {
dispatchEvent(
createError("Failed", "Missing parameters. `cardDescription` must be supplied in the props to <AddToWalletButton />")
createError("Failed", "Missing parameters. `cardDetails.cardDescription` must be supplied in the props to <AddToWalletButton />")
)
}
return true
Expand Down Expand Up @@ -125,12 +125,8 @@ class AddToWalletButtonView(private val context: ThemedReactContext, private val
sourceMap = map
}

fun setCardDescription(description: String) {
cardDescription = description
}

fun setCardLastFour(last4: String) {
cardLastFour = last4
fun setCardDetails(detailsMap: ReadableMap) {
cardDetails = detailsMap
}

fun setEphemeralKey(map: ReadableMap) {
Expand Down
46 changes: 32 additions & 14 deletions e2e/payments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ describe('Common payment scenarios', () => {
});

it('ACH Payment', function () {
this.retries(3);
this.retries(2);

homeScreen.goTo('Bank Debits');
homeScreen.goTo('ACH payment');
Expand All @@ -230,25 +230,34 @@ describe('Common payment scenarios', () => {
clickButtonContainingText('Collect bank account');

BasicPaymentScreen.authorizeACH();
driver.pause(3000);

expect(driver.getAlertText()).toContain('RequiresConfirmation');
driver.dismissAlert();
let alert = getElementByText('Requires Confirmation');
alert.waitForDisplayed({
timeout: 20000,
});
alert.dismissAlert();

clickButtonContainingText('Confirm');
driver.pause(3000);

expect(driver.getAlertText()).toContain('Awaiting verification');
driver.dismissAlert();
alert = getElementByText('Awaiting verification');
alert.waitForDisplayed({
timeout: 20000,
});
alert.dismissAlert();

getElementByText('Verify microdeposit').click();
driver.pause(3000);

expect(driver.getAlertText()).toContain('Processing');
alert = getElementByText('Processing');
alert.waitForDisplayed({
timeout: 20000,
});
alert.dismissAlert();
});

it('ACH Setup', function () {
this.retries(3);
this.retries(2);

homeScreen.goTo('Bank Debits');
homeScreen.goTo('ACH setup');
Expand All @@ -257,20 +266,29 @@ describe('Common payment scenarios', () => {
clickButtonContainingText('Collect bank account');

BasicPaymentScreen.authorizeACH();
driver.pause(3000);

expect(driver.getAlertText()).toContain('RequiresConfirmation');
driver.dismissAlert();
let alert = getElementByText('Requires Confirmation');
alert.waitForDisplayed({
timeout: 20000,
});
alert.dismissAlert();

clickButtonContainingText('Confirm');
driver.pause(3000);

expect(driver.getAlertText()).toContain('Awaiting verification');
driver.dismissAlert();
alert = getElementByText('Awaiting verification');
alert.waitForDisplayed({
timeout: 20000,
});
alert.dismissAlert();

getElementByText('Verify microdeposit').click();
driver.pause(3000);

expect(driver.getAlertText()).toContain('Succeeded');
alert = getElementByText('Succeeded');
alert.waitForDisplayed({
timeout: 20000,
});
alert.dismissAlert();
});
});
7 changes: 5 additions & 2 deletions e2e/screenObject/BasicPaymentScreen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,24 @@ class BasicPaymentScreen {
let button = $(`button*=Manually verify instead`);
if (button.isDisplayed()) {
button.click();
driver.pause(5000);
driver.pause(2000);

button = $(`//input[@name='confirmAccountNumber']`);
button.click();
button.sendKeys(['000123456789\n']);
driver.pause(2000);

button = $(`//input[@name='routingNumber']`);
button.click();
button.click();
button.sendKeys(['110000000\n']);
driver.pause(2000);

button = $(`//input[@name='accountNumber']`);
button.click();
button.click();
button.sendKeys(['000123456789\n']);
driver.pause(2000);

button = $(`button*=Continue`);
button.click();
Expand All @@ -104,7 +107,6 @@ class BasicPaymentScreen {

button = $(`button*=Done`);
button.click();
driver.pause(5000);
break;
}
} catch (e) {
Expand All @@ -114,6 +116,7 @@ class BasicPaymentScreen {
}
}
driver.switchContext(getNativeContext());
driver.pause(5000);
}
}

Expand Down
40 changes: 20 additions & 20 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -287,27 +287,27 @@ PODS:
- RNScreens (3.10.2):
- React-Core
- React-RCTImage
- Stripe (22.0.0):
- Stripe/Stripe3DS2 (= 22.0.0)
- StripeApplePay (= 22.0.0)
- StripeCore (= 22.0.0)
- StripeUICore (= 22.0.0)
- Stripe (22.2.0):
- Stripe/Stripe3DS2 (= 22.2.0)
- StripeApplePay (= 22.2.0)
- StripeCore (= 22.2.0)
- StripeUICore (= 22.2.0)
- stripe-react-native (0.8.0):
- React-Core
- Stripe (~> 22.0.0)
- StripeConnections (~> 22.0.0)
- Stripe/Stripe3DS2 (22.0.0):
- StripeApplePay (= 22.0.0)
- StripeCore (= 22.0.0)
- StripeUICore (= 22.0.0)
- StripeApplePay (22.0.0):
- StripeCore (= 22.0.0)
- StripeConnections (22.0.0):
- StripeCore (= 22.0.0)
- StripeUICore (= 22.0.0)
- StripeCore (22.0.0)
- StripeUICore (22.0.0):
- StripeCore (= 22.0.0)
- Stripe (~> 22.2.0)
- StripeFinancialConnections (~> 22.2.0)
- Stripe/Stripe3DS2 (22.2.0):
- StripeApplePay (= 22.2.0)
- StripeCore (= 22.2.0)
- StripeUICore (= 22.2.0)
- StripeApplePay (22.2.0):
- StripeCore (= 22.2.0)
- StripeCore (22.2.0)
- StripeFinancialConnections (22.2.0):
- StripeCore (= 22.2.0)
- StripeUICore (= 22.2.0)
- StripeUICore (22.2.0):
- StripeCore (= 22.2.0)
- Yoga (1.14.0)

DEPENDENCIES:
Expand Down Expand Up @@ -355,8 +355,8 @@ SPEC REPOS:
- fmt
- Stripe
- StripeApplePay
- StripeConnections
- StripeCore
- StripeFinancialConnections
- StripeUICore

EXTERNAL SOURCES:
Expand Down
4 changes: 2 additions & 2 deletions example/ios/StripeSdkExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -228,17 +228,17 @@
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/Stripe/Stripe.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/Stripe/Stripe3DS2.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/StripeConnections/StripeConnections.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/StripeCore/StripeCore.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/StripeFinancialConnections/StripeFinancialConnections.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/StripeUICore/StripeUICore.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Stripe.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Stripe3DS2.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripeConnections.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripeCore.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripeFinancialConnections.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripeUICore.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
6 changes: 3 additions & 3 deletions example/src/screens/ACHPaymentScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default function ACHPaymentScreen() {
) {
setAwaitingVerification(true);
Alert.alert(
'Awaiting verification:',
'Awaiting verification',
'The payment must be verified. Please provide the verification input values below.'
);
} else {
Expand Down Expand Up @@ -116,7 +116,7 @@ export default function ACHPaymentScreen() {
) {
setAwaitingVerification(true);
Alert.alert(
'Awaiting verification:',
'Awaiting verification',
'The payment must be verified. Please provide the verification input values below.'
);
} else {
Expand Down Expand Up @@ -155,7 +155,7 @@ export default function ACHPaymentScreen() {
} else if (paymentIntent) {
if (paymentIntent.status === PaymentIntent.Status.RequiresConfirmation) {
Alert.alert(
'Payment status: RequiresConfirmation',
'Requires Confirmation',
"You may now press the first 'Confirm' button."
);
} else {
Expand Down
6 changes: 3 additions & 3 deletions example/src/screens/ACHSetupScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default function ACHSetupScreen() {
) {
setAwaitingVerification(true);
Alert.alert(
'Awaiting verification:',
'Awaiting verification',
'The setup must be verified. Please provide the verification input values below.'
);
} else {
Expand Down Expand Up @@ -108,7 +108,7 @@ export default function ACHSetupScreen() {
) {
setAwaitingVerification(true);
Alert.alert(
'Awaiting verification:',
'Awaiting verification',
'The setup must be verified. Please provide the verification input values below.'
);
} else {
Expand Down Expand Up @@ -147,7 +147,7 @@ export default function ACHSetupScreen() {
} else if (setupIntent) {
if (setupIntent.status === SetupIntent.Status.RequiresConfirmation) {
Alert.alert(
'Setup status: RequiresConfirmation',
'Requires Confirmation',
"You may now press the first 'Confirm' button."
);
} else {
Expand Down
10 changes: 7 additions & 3 deletions example/src/screens/ApplePayScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,13 @@ export default function ApplePayScreen() {
testEnv={true}
style={styles.payButton}
iOSButtonStyle="onLightBackground"
cardHolderName={cardDetails?.cardholder?.name}
cardDescription={'Added by Stripe'}
cardLastFour={cardDetails?.last4}
cardDetails={{
name: cardDetails?.cardholder?.name,
primaryAccountIdentifier:
cardDetails?.wallets?.primary_account_identifier,
lastFour: cardDetails?.last4,
description: 'Added by Stripe',
}}
ephemeralKey={ephemeralKey}
onComplete={({ error }) => {
Alert.alert(
Expand Down
10 changes: 7 additions & 3 deletions example/src/screens/GooglePayScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,13 @@ export default function GooglePayScreen() {
<AddToWalletButton
androidAssetSource={Image.resolveAssetSource(AddToGooglePayPNG)}
style={styles.payButton}
cardHolderName={cardDetails?.cardholder?.name}
cardDescription={'Added by Stripe'}
cardLastFour={cardDetails?.last4}
cardDetails={{
name: cardDetails?.cardholder?.name,
primaryAccountIdentifier:
cardDetails?.wallet?.primary_account_identifier,
lastFour: cardDetails?.last4,
description: 'Added by Stripe',
}}
token={androidCardToken}
ephemeralKey={ephemeralKey}
onComplete={({ error }) => {
Expand Down
5 changes: 1 addition & 4 deletions ios/pushprovisioning/AddToWalletButtonManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
@interface RCT_EXTERN_MODULE(AddToWalletButtonManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(testEnv, BOOL)
RCT_EXPORT_VIEW_PROPERTY(iOSButtonStyle, NSString)
RCT_EXPORT_VIEW_PROPERTY(cardHolderName, NSString)
RCT_EXPORT_VIEW_PROPERTY(cardDescription, NSString)
RCT_EXPORT_VIEW_PROPERTY(cardLastFour, NSString)
RCT_EXPORT_VIEW_PROPERTY(cardBrand, NSString)
RCT_EXPORT_VIEW_PROPERTY(cardDetails, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(ephemeralKey, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(onCompleteAction, RCTDirectEventBlock)
@end