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

10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# CHANGELOG

## 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.

## 0.8.0

- [#902](https://github.com/stripe/stripe-react-native/pull/902) fix: create custom babel plugin for package.json imports in src/
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
54 changes: 27 additions & 27 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-react-native (0.7.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 Expand Up @@ -469,12 +469,12 @@ SPEC CHECKSUMS:
RNCMaskedView: c298b644a10c0c142055b3ae24d83879ecb13ccd
RNCPicker: cb57c823d5ce8d2d0b5dfb45ad97b737260dc59e
RNScreens: d6da2b9e29cf523832c2542f47bf1287318b1868
Stripe: ee32e594fa4dee4bdf2a8a3039f7fb07a21075dc
stripe-react-native: 165df7efcedb14f15b8e2ddff20cedd6e6c42fca
StripeApplePay: e09964f3e2c6b318e53a05c12f3cb7efc592484d
StripeConnections: d3068bf688679a51932abb94d956d8a73c213bd7
StripeCore: 689b9605ccb78e507f59ddc5e677615e0af16583
StripeUICore: f5fe5ad283e132b40077b5eb85b625ebf7de034a
Stripe: 33cb13d41868ad64a6eabda23c920c5ffa724fa6
stripe-react-native: bff4d8028167e1cbf67cc870bc2075f2db7ed315
StripeApplePay: 77bbdb76f77e5e387c393e1512d111ee4818e384
StripeCore: 5703818b3a9949d8fce1a1b09e51fbe8953eb0ed
StripeFinancialConnections: 115d05b11a627e64d2402065b816e1aebae10951
StripeUICore: e1829301ad5de8831bc269a8ce8f73c31c26ce42
Yoga: e7dc4e71caba6472ff48ad7d234389b91dadc280

PODFILE CHECKSUM: 72bfeab5bf84b6ab4999227a1d3e012ee6b3f46e
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
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
26 changes: 12 additions & 14 deletions ios/pushprovisioning/AddToWalletButtonView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ class AddToWalletButtonView: UIView {

@objc var testEnv: Bool = false
@objc var iOSButtonStyle: NSString?
@objc var cardHolderName: NSString?
@objc var cardDescription: NSString?
@objc var cardLastFour: NSString?
@objc var cardBrand: NSString?
@objc var cardDetails: NSDictionary?
@objc var ephemeralKey: NSDictionary?
@objc var onCompleteAction: RCTDirectEventBlock?

Expand Down Expand Up @@ -65,40 +62,41 @@ class AddToWalletButtonView: UIView {
)
return
}
guard let cardHolderName = cardHolderName as String? else {

guard let cardHolderName = cardDetails?["name"] as? String else {
onCompleteAction!(
Errors.createError(
ErrorType.Failed,
"Missing parameters. `cardHolderName` must be supplied in the props to <AddToWalletButton />"
"Missing parameters. `cardDetails.name` must be supplied in the props to <AddToWalletButton />"
) as? [AnyHashable : Any]
)
return
}

if (cardHolderName.isEmpty) {
onCompleteAction!(
Errors.createError(
ErrorType.Failed,
"`cardHolderName` is required, but the passed string was empty"
"`cardDetails.name` is required, but the passed string was empty"
) as? [AnyHashable : Any]
)
return
}

let config = STPPushProvisioningContext.requestConfiguration(
withName: cardHolderName,
description: cardDescription as String?,
last4: cardLastFour as String?,
brand: Mappers.mapToCardBrand(cardBrand as String?)
description: cardDetails?["description"] as? String,
last4: cardDetails?["lastFour"] as? String,
brand: Mappers.mapToCardBrand(cardDetails?["brand"] as? String),
primaryAccountIdentifier: cardDetails?["primaryAccountIdentifier"] as? String
)

// We can use STPFakeAddPaymentPassViewController ONLY IN TEST MODE. If STPFakeAddPaymentPassViewController is
// used with a live mode card, the flow will fail and show a 'Signing certificate was invalid' error.
let controller = {
return self.testEnv ? STPFakeAddPaymentPassViewController(requestConfiguration: config, delegate: self) : PKAddPaymentPassViewController(requestConfiguration: config, delegate: self)
}()

let vc = findViewControllerPresenter(from: UIApplication.shared.delegate?.window??.rootViewController ?? UIViewController())
vc.present(controller!, animated: true, completion: nil)
}
Expand Down
29 changes: 18 additions & 11 deletions src/components/AddToWalletButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@ export interface Props extends AccessibilityProps {
testID?: string;
/** Only set to `false` when shipping through TestFlight || App Store */
testEnv?: boolean;
/** Sets the card holder name (used only on iOS) */
cardHolderName: string;
/** Last 4 digits of the card. Required on Android. */
cardLastFour: string;
/** Sets the card holder name (used only on iOS) */
cardDescription?: string;
/** Optional, only used on iOS */
cardBrand?: Token.CardBrand;
/** Details of the Issued Card you'd like added to the device's wallet */
cardDetails: {
/** The `primary_account_identifier` value from the issued card. */
primaryAccountIdentifier: string | null;
/** The card holder name (used only on iOS) */
name: string;
/** A user-facing description of the card. Required on Android.*/
description: string;
/** Last 4 digits of the card, only used on iOS */
lastFour?: string;
/** Optional, only used on iOS */
brand?: Token.CardBrand;
};
// Optional, only for Android and only for cards that are in the "yellow path" (as defined by Google- https://developers.google.com/pay/issuers/apis/push-provisioning/android/wallet-operations#resolving_yellow_path). Obtain this value via the `isCardInWallet` method.
token?: GooglePayCardToken | null;
/** Used by stripe to securely obtain card info of the card being provisioned. */
Expand All @@ -54,9 +59,11 @@ export interface Props extends AccessibilityProps {
* testEnv={true}
* style={styles.myButtonStyle}
* iOSButtonStyle="onLightBackground"
* cardHolderName="David Wallace"
* cardLastFour="4242"
* cardBrand="Visa"
* cardDetails={{
* primaryAccountIdentifier: "V-123",
* name: "David Wallace",
* lastFour: "4242",
* }}
* ephemeralKey={myEphemeralKey} // This object is retrieved from your server. See https://stripe.com/docs/issuing/cards/digital-wallets?platform=react-native#update-your-backend
* onComplete={(error) => {
* Alert.alert(
Expand Down
4 changes: 2 additions & 2 deletions stripe-react-native.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ Pod::Spec.new do |s|
s.source_files = 'ios/**/*.{h,m,mm,swift}'

s.dependency 'React-Core'
s.dependency 'Stripe', '~> 22.0.0'
s.dependency 'StripeConnections', '~> 22.0.0'
s.dependency 'Stripe', '~> 22.2.0'
s.dependency 'StripeFinancialConnections', '~> 22.2.0'
end