From 87281399d4afb14cb90b3a31675cb10f799f9949 Mon Sep 17 00:00:00 2001 From: Charlie Cruzan Date: Tue, 1 Nov 2022 16:33:40 -0700 Subject: [PATCH 1/3] add cta button label to payment sheet --- .../PaymentSheetFragment.kt | 4 +- example/ios/Podfile | 2 +- example/ios/Podfile.lock | 81 ++++++++++++------- .../project.pbxproj | 10 ++- .../src/screens/PaymentsUICompleteScreen.tsx | 1 + ios/ApplePayUtils.swift | 2 +- ios/CardFieldView.swift | 6 +- ios/Mappers.swift | 1 + ios/PaymentMethodFactory.swift | 13 ++- ios/PaymentSheetAppearance.swift | 10 +-- ios/StripeSdk.swift | 24 ++++-- src/types/PaymentSheet.ts | 19 +++++ stripe-react-native.podspec | 8 +- 13 files changed, 123 insertions(+), 58 deletions(-) diff --git a/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt b/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt index cc72e884a..5baf412f1 100644 --- a/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt +++ b/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt @@ -56,6 +56,7 @@ class PaymentSheetFragment( initPromise.resolve(createError(ErrorType.Failed.toString(), "merchantDisplayName cannot be empty or null.")) return } + val primaryButtonLabel = arguments?.getString("primaryButtonLabel") val customerId = arguments?.getString("customerId").orEmpty() val customerEphemeralKeySecret = arguments?.getString("customerEphemeralKeySecret").orEmpty() val googlePayConfig = buildGooglePayConfig(arguments?.getBundle("googlePay")) @@ -126,7 +127,8 @@ class PaymentSheetFragment( ephemeralKeySecret = customerEphemeralKeySecret ) else null, googlePay = googlePayConfig, - appearance = appearance + appearance = appearance, + primaryButtonLabel = primaryButtonLabel ) if (arguments?.getBoolean("customFlow") == true) { diff --git a/example/ios/Podfile b/example/ios/Podfile index 5635cac6f..da77cc887 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,4 +1,4 @@ -platform :ios, '12.4' +platform :ios, '13.0' install! 'cocoapods', deterministic_uuids: false diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index f31437f52..0e032111f 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -368,31 +368,50 @@ PODS: - React-Core - React-RCTImage - SocketRocket (0.6.0) - - Stripe (22.8.4): - - Stripe/Stripe3DS2 (= 22.8.4) - - StripeApplePay (= 22.8.4) - - StripeCore (= 22.8.4) - - StripeUICore (= 22.8.4) + - Stripe (23.1.0): + - StripeApplePay (= 23.1.0) + - StripeCore (= 23.1.0) + - StripePayments (= 23.1.0) + - StripePaymentsUI (= 23.1.0) + - StripeUICore (= 23.1.0) - stripe-react-native (0.19.0): - React-Core - - Stripe (~> 22.8.4) - - StripeFinancialConnections (~> 22.8.4) + - Stripe (~> 23.1.0) + - StripeApplePay (~> 23.1.0) + - StripeFinancialConnections (~> 23.1.0) + - StripePayments (~> 23.1.0) + - StripePaymentSheet (~> 23.1.0) + - StripePaymentsUI (~> 23.1.0) - stripe-react-native/Tests (0.19.0): - React-Core - - Stripe (~> 22.8.4) - - StripeFinancialConnections (~> 22.8.4) - - Stripe/Stripe3DS2 (22.8.4): - - StripeApplePay (= 22.8.4) - - StripeCore (= 22.8.4) - - StripeUICore (= 22.8.4) - - StripeApplePay (22.8.4): - - StripeCore (= 22.8.4) - - StripeCore (22.8.4) - - StripeFinancialConnections (22.8.4): - - StripeCore (= 22.8.4) - - StripeUICore (= 22.8.4) - - StripeUICore (22.8.4): - - StripeCore (= 22.8.4) + - Stripe (~> 23.1.0) + - StripeApplePay (~> 23.1.0) + - StripeFinancialConnections (~> 23.1.0) + - StripePayments (~> 23.1.0) + - StripePaymentSheet (~> 23.1.0) + - StripePaymentsUI (~> 23.1.0) + - StripeApplePay (23.1.0): + - StripeCore (= 23.1.0) + - StripeCore (23.1.0) + - StripeFinancialConnections (23.1.0): + - StripeCore (= 23.1.0) + - StripeUICore (= 23.1.0) + - StripePayments (23.1.0): + - StripeCore (= 23.1.0) + - StripePayments/Stripe3DS2 (= 23.1.0) + - StripePayments/Stripe3DS2 (23.1.0): + - StripeCore (= 23.1.0) + - StripePaymentSheet (23.1.0): + - StripeApplePay (= 23.1.0) + - StripeCore (= 23.1.0) + - StripePayments (= 23.1.0) + - StripePaymentsUI (= 23.1.0) + - StripePaymentsUI (23.1.0): + - StripeCore (= 23.1.0) + - StripePayments (= 23.1.0) + - StripeUICore (= 23.1.0) + - StripeUICore (23.1.0): + - StripeCore (= 23.1.0) - Yoga (1.14.0) - YogaKit (1.18.1): - Yoga (~> 1.14) @@ -482,6 +501,9 @@ SPEC REPOS: - StripeApplePay - StripeCore - StripeFinancialConnections + - StripePayments + - StripePaymentSheet + - StripePaymentsUI - StripeUICore - YogaKit @@ -614,15 +636,18 @@ SPEC CHECKSUMS: RNCPicker: abc646b53a3d28ccfa3232c927a0ca52e0cf024d RNScreens: 4a1af06327774490d97342c00aee0c2bafb497b7 SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 - Stripe: 59f6659e8ea413def19c97c57e23f5ec6ea48cf8 - stripe-react-native: 48ad0866973ed214c3a4424de85b00ed006cf116 - StripeApplePay: 6e9aebd3d248464836e9fbdaef6e5fb1817d56a6 - StripeCore: 193f27552fb98108ebfe0df11651fe5f38948305 - StripeFinancialConnections: 955c345ada7d0dff1a9bd15c4ebc97eacce4ac75 - StripeUICore: 6a5bbea0164d63bd91000f001903e7901859e1a4 + Stripe: 6e1b3bbe0224636ee06a7c032d5392be0a10ac0a + stripe-react-native: 750cfa646f177126de4c07fd5f09c9aee6ad94dc + StripeApplePay: 0c8b29f4914ce260ce85302df58dacbfcee6c2e0 + StripeCore: 88d19cb8d1f6a10be0af5cff384d77261a0f04a2 + StripeFinancialConnections: e54978d7450686af6a1532258c04d4721c93a522 + StripePayments: 25e0303adcaf584efb4617a70a0123553fcd3069 + StripePaymentSheet: 7ce65414fc5a65ddcabee1571336b2de5f60ec6a + StripePaymentsUI: 503d43f56fd5faaed502427ef57e6919759658c8 + StripeUICore: 3864423d3595403cc9349eedd4911c0d7e251e48 Yoga: 236056dd74cda4d9d76c20306fd8c20bb087614d YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 17106566f645fc6d606ce750e3389c566170dbf4 +PODFILE CHECKSUM: 4eaaad013a6f099aabc8d8e69940bf881c4db33e COCOAPODS: 1.11.3 diff --git a/example/ios/StripeSdkExample.xcodeproj/project.pbxproj b/example/ios/StripeSdkExample.xcodeproj/project.pbxproj index 45a9a8947..76f85f636 100644 --- a/example/ios/StripeSdkExample.xcodeproj/project.pbxproj +++ b/example/ios/StripeSdkExample.xcodeproj/project.pbxproj @@ -263,18 +263,24 @@ "${PODS_ROOT}/Target Support Files/Pods-StripeSdkExample/Pods-StripeSdkExample-resources.sh", "${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}/StripeCore/StripeCore.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/StripeFinancialConnections/StripeFinancialConnections.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/StripePaymentSheet/StripePaymentSheet.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments/StripePayments.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/StripePayments/Stripe3DS2.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/StripePaymentsUI/StripePaymentsUI.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}/StripeCore.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripeFinancialConnections.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripePaymentSheet.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripePayments.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Stripe3DS2.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripePaymentsUI.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/StripeUICore.bundle", ); runOnlyForDeploymentPostprocessing = 0; diff --git a/example/src/screens/PaymentsUICompleteScreen.tsx b/example/src/screens/PaymentsUICompleteScreen.tsx index 72f7f7687..c986a6f19 100644 --- a/example/src/screens/PaymentsUICompleteScreen.tsx +++ b/example/src/screens/PaymentsUICompleteScreen.tsx @@ -93,6 +93,7 @@ export default function PaymentsUICompleteScreen() { defaultBillingDetails: billingDetails, allowsDelayedPaymentMethods: true, appearance, + primaryButtonLabel: 'purchase! 😃', }); if (!error) { setPaymentSheetEnabled(true); diff --git a/ios/ApplePayUtils.swift b/ios/ApplePayUtils.swift index e8dc6fb18..bdc73f953 100644 --- a/ios/ApplePayUtils.swift +++ b/ios/ApplePayUtils.swift @@ -6,7 +6,7 @@ // import Foundation -import Stripe +import StripePaymentSheet class ApplePayUtils { diff --git a/ios/CardFieldView.swift b/ios/CardFieldView.swift index 0f9284381..95397cb04 100644 --- a/ios/CardFieldView.swift +++ b/ios/CardFieldView.swift @@ -9,7 +9,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate { private var cardField = STPPaymentCardTextField() - public var cardParams: STPPaymentMethodCardParams? = nil + public var cardParams: STPPaymentMethodParams? = nil public var cardPostalCode: String? = nil @objc var postalCodeEnabled: Bool = true { @@ -144,7 +144,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate { "expiryYear": textField.expirationYear, "complete": textField.isValid, "brand": Mappers.mapFromCardBrand(brand) ?? NSNull(), - "last4": textField.cardParams.last4 ?? "", + "last4": textField.paymentMethodParams.card!.last4 ?? "", "validExpiryDate": Mappers.mapFromCardValidationState(state: validExpiryDate), "validCVC": Mappers.mapFromCardValidationState(state: validCVC), "validNumber": Mappers.mapFromCardValidationState(state: validNumber) @@ -159,7 +159,7 @@ class CardFieldView: UIView, STPPaymentCardTextFieldDelegate { onCardChange!(cardData as [AnyHashable : Any]) } if (textField.isValid) { - self.cardParams = textField.cardParams + self.cardParams = textField.paymentMethodParams self.cardPostalCode = textField.postalCode } else { self.cardParams = nil diff --git a/ios/Mappers.swift b/ios/Mappers.swift index 0146b5038..d9eeeaf4b 100644 --- a/ios/Mappers.swift +++ b/ios/Mappers.swift @@ -1,4 +1,5 @@ import Stripe +import StripePaymentSheet class Mappers { class func createResult(_ key: String, _ value: NSDictionary?) -> NSDictionary { diff --git a/ios/PaymentMethodFactory.swift b/ios/PaymentMethodFactory.swift index 4370cbb17..608988d51 100644 --- a/ios/PaymentMethodFactory.swift +++ b/ios/PaymentMethodFactory.swift @@ -162,11 +162,7 @@ class PaymentMethodFactory { return STPPaymentMethodParams(card: methodParams, billingDetails: billingDetailsParams, metadata: nil) } - guard let cardParams = cardFieldView?.cardParams ?? cardFormView?.cardParams else { - throw PaymentMethodError.cardPaymentMissingParams - } - - if cardFieldView?.cardParams != nil { + if let params = cardFieldView?.cardParams as? STPPaymentMethodParams { if let postalCode = cardFieldView?.cardPostalCode{ if (billingDetailsParams == nil) { let bd = STPPaymentMethodBillingDetails() @@ -177,8 +173,10 @@ class PaymentMethodFactory { billingDetailsParams?.address?.postalCode = postalCode } } + params.billingDetails = billingDetailsParams + return params } - if cardFormView?.cardParams != nil { + if let params = cardFormView?.cardParams as? STPPaymentMethodCardParams { if let address = cardFormView?.cardForm?.cardParams?.billingDetails?.address { if (billingDetailsParams == nil) { let bd = STPPaymentMethodBillingDetails() @@ -191,9 +189,10 @@ class PaymentMethodFactory { billingDetailsParams?.address?.country = address.country } } + return STPPaymentMethodParams(card: params, billingDetails: billingDetailsParams, metadata: nil) } - return STPPaymentMethodParams(card: cardParams, billingDetails: billingDetailsParams, metadata: nil) + throw PaymentMethodError.cardPaymentMissingParams } diff --git a/ios/PaymentSheetAppearance.swift b/ios/PaymentSheetAppearance.swift index ad5121fb4..467a9c576 100644 --- a/ios/PaymentSheetAppearance.swift +++ b/ios/PaymentSheetAppearance.swift @@ -4,7 +4,7 @@ // // Created by Charles Cruzan on 5/11/22. // -import Stripe +import StripePaymentSheet extension StripeSdk { func buildPaymentSheetAppearance(userParams: NSDictionary) throws -> PaymentSheet.Appearance { @@ -30,8 +30,8 @@ extension StripeSdk { return appearance } - private func buildFont(params: NSDictionary) throws -> Stripe.PaymentSheet.Appearance.Font { - var font = Stripe.PaymentSheet.Appearance.Font() + private func buildFont(params: NSDictionary) throws -> PaymentSheet.Appearance.Font { + var font = PaymentSheet.Appearance.Font() if let fontName = params[PaymentSheetAppearanceKeys.FAMILY] as? String { guard let customFont = UIFont(name: fontName, size: UIFont.systemFontSize) else { throw PaymentSheetAppearanceError.missingFont(fontName) @@ -42,8 +42,8 @@ extension StripeSdk { return font } - private func buildColors(params: NSDictionary) throws -> Stripe.PaymentSheet.Appearance.Colors { - var colors = Stripe.PaymentSheet.Appearance.Colors() + private func buildColors(params: NSDictionary) throws -> PaymentSheet.Appearance.Colors { + var colors = PaymentSheet.Appearance.Colors() if (params.object(forKey: PaymentSheetAppearanceKeys.LIGHT) != nil && params.object(forKey: PaymentSheetAppearanceKeys.DARK) == nil || params.object(forKey: PaymentSheetAppearanceKeys.DARK) != nil && params.object(forKey: PaymentSheetAppearanceKeys.LIGHT) == nil) { diff --git a/ios/StripeSdk.swift b/ios/StripeSdk.swift index b661955ce..fcee219e4 100644 --- a/ios/StripeSdk.swift +++ b/ios/StripeSdk.swift @@ -1,5 +1,6 @@ import PassKit import Stripe +import StripePaymentSheet import StripeFinancialConnections @objc(StripeSdk) @@ -77,6 +78,8 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi rejecter reject: @escaping RCTPromiseRejectBlock) -> Void { var configuration = PaymentSheet.Configuration() self.paymentSheetFlowController = nil + + configuration.primaryButtonLabel = params["primaryButtonLabel"] as? String if let appearanceParams = params["appearance"] as? NSDictionary { do { @@ -673,17 +676,22 @@ class StripeSdk: RCTEventEmitter, STPApplePayContextDelegate, STPBankSelectionVi resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void { - guard let cardParams = cardFieldView?.cardParams ?? cardFormView?.cardParams else { + let address = params["address"] as? NSDictionary + let cardSourceParams = STPCardParams() + if let params = cardFieldView?.cardParams as? STPPaymentMethodParams { + cardSourceParams.number = params.card!.number + cardSourceParams.cvc = params.card!.cvc + cardSourceParams.expMonth = UInt(truncating: params.card!.expMonth ?? 0) + cardSourceParams.expYear = UInt(truncating: params.card!.expYear ?? 0) + } else if let params = cardFormView?.cardParams as? STPPaymentMethodCardParams { + cardSourceParams.number = params.number + cardSourceParams.cvc = params.cvc + cardSourceParams.expMonth = UInt(truncating: params.expMonth ?? 0) + cardSourceParams.expYear = UInt(truncating: params.expYear ?? 0) + } else { resolve(Errors.createError(ErrorType.Failed, "Card details not complete")) return } - - let address = params["address"] as? NSDictionary - let cardSourceParams = STPCardParams() - cardSourceParams.number = cardParams.number - cardSourceParams.cvc = cardParams.cvc - cardSourceParams.expMonth = UInt(truncating: cardParams.expMonth ?? 0) - cardSourceParams.expYear = UInt(truncating: cardParams.expYear ?? 0) cardSourceParams.address = Mappers.mapToAddress(address: address) cardSourceParams.name = params["name"] as? String cardSourceParams.currency = params["currency"] as? String diff --git a/src/types/PaymentSheet.ts b/src/types/PaymentSheet.ts index dfd0aad60..f2e4139e6 100644 --- a/src/types/PaymentSheet.ts +++ b/src/types/PaymentSheet.ts @@ -4,18 +4,35 @@ import type { CartSummaryItem } from './ApplePay'; export type SetupParams = ClientSecretParams & { /** Your customer-facing business name. On Android, this is required and cannot be an empty string. */ merchantDisplayName: string; + /** The identifier of the Stripe Customer object. See https://stripe.com/docs/api/customers/object#customer_object-id */ customerId?: string; + /** A short-lived token that allows the SDK to access a Customer’s payment methods. */ customerEphemeralKeySecret?: string; + /** When set to true, separates out the payment method selection & confirmation steps. + * If true, you must call `confirmPaymentSheetPayment` on your own. Defaults to false. */ customFlow?: boolean; /** iOS only. Enable Apple Pay in the Payment Sheet by passing an ApplePayParams object. */ applePay?: ApplePayParams; /** Android only. Enable Google Pay in the Payment Sheet by passing a GooglePayParams object. */ googlePay?: GooglePayParams; + /** The color styling to use for PaymentSheet UI. Defaults to 'automatic'. */ style?: 'alwaysLight' | 'alwaysDark' | 'automatic'; + /** A URL that redirects back to your app that PaymentSheet can use to auto-dismiss web views used for additional authentication, e.g. 3DS2 */ returnURL?: string; + /** PaymentSheet pre-populates the billing fields with the values provided. */ defaultBillingDetails?: BillingDetails; + /** If true, allows payment methods that do not move money at the end of the checkout. Defaults to false. + * + * Some payment methods can’t guarantee you will receive funds from your customer at the end of the checkout + * because they take time to settle (eg. most bank debits, like SEPA or ACH) or require customer action to + * complete (e.g. OXXO, Konbini, Boleto). If this is set to true, make sure your integration listens to webhooks + * for notifications on whether a payment has succeeded or not. + */ allowsDelayedPaymentMethods?: boolean; + /** Customizes the appearance of PaymentSheet */ appearance?: AppearanceParams; + /** The label to use for the primary button. If not set, Payment Sheet will display suitable default labels for payment and setup intents. */ + primaryButtonLabel?: string; }; export type ClientSecretParams = @@ -35,6 +52,8 @@ export type ApplePayParams = { * An array of CartSummaryItem item objects that summarize the amount of the payment. If you're using a SetupIntent * for a recurring payment, you should set this to display the amount you intend to charge. */ paymentSummaryItems?: CartSummaryItem[]; + // TODO: Uncomment when https://github.com/stripe/stripe-react-native/pull/1164 lands + // buttonType: ButtonType }; export type GooglePayParams = { diff --git a/stripe-react-native.podspec b/stripe-react-native.podspec index 8db19f1c0..b59ba4b42 100644 --- a/stripe-react-native.podspec +++ b/stripe-react-native.podspec @@ -1,7 +1,7 @@ require 'json' package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) -stripe_version = '~> 22.8.4' +stripe_version = '~> 23.1.0' Pod::Spec.new do |s| s.name = 'stripe-react-native' @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.license = package['license'] s.authors = package['author'] - s.platforms = { ios: '12.0' } + s.platforms = { ios: '13.0' } s.source = { git: 'https://github.com/stripe/stripe-react-native.git', tag: s.version.to_s } s.source_files = 'ios/**/*.{h,m,mm,swift}' @@ -23,5 +23,9 @@ Pod::Spec.new do |s| s.dependency 'React-Core' s.dependency 'Stripe', stripe_version + s.dependency 'StripePaymentSheet', stripe_version + s.dependency 'StripePayments', stripe_version + s.dependency 'StripePaymentsUI', stripe_version + s.dependency 'StripeApplePay', stripe_version s.dependency 'StripeFinancialConnections', stripe_version end From 3bd86e97c4478df65bf90f62717b96018b861da5 Mon Sep 17 00:00:00 2001 From: Charlie Cruzan Date: Tue, 1 Nov 2022 16:38:11 -0700 Subject: [PATCH 2/3] [skip actions] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dd469dee..263fd1f4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,17 +4,21 @@ ### Breaking changes +- This library now supports iOS 13 and up, due to `stripe-ios` increasing the deployment target. If you would like to build for iOS 12, please continue to use `@stripe/stripe-react-native@0.19.0`. [#1190](https://github.com/stripe/stripe-react-native/pull/1190) + ### New features - Added [Link](https://stripe.com/docs/payments/link) support in Payment Sheet. [#1176](https://github.com/stripe/stripe-react-native/pull/1176) - Added the `resetPaymentSheetCustomer` method to clear persisted authentication state in the PaymentSheet. [#1176](https://github.com/stripe/stripe-react-native/pull/1176) - Added `preferredNetwork` and `availableNetworks` fields to the `CardResult` payment method. [#1176](https://github.com/stripe/stripe-react-native/pull/1176) - Added support for custom fonts to `CardForm` and `CardView` on Android. [#1150](https://github.com/stripe/stripe-react-native/pull/1150) +- Added support for customizing the call to action button label in Payment Sheet by providing the `primaryButtonLabel` property to `initPaymentSheet()`. [#1190](https://github.com/stripe/stripe-react-native/pull/1190) ## Fixes - Fixed an issue on iOS where `confirmSetupIntent` would throw an error if the `Card` payment method was provided with the `paymentMethodId` parameter. [#1151](https://github.com/stripe/stripe-react-native/pull/1151) - Upgraded `stripe-android` to 20.15.+. [#1176](https://github.com/stripe/stripe-react-native/pull/1176) +- Upgraded `stripe-ios` to 23.1.+. [#1190](https://github.com/stripe/stripe-react-native/pull/1190) - Fixed `FinancialConnections.Subcategory` and `FinancialConnections.Permission` types to be camel-case instead of snake case. [#1176](https://github.com/stripe/stripe-react-native/pull/1176) - Fixed an issue with Financial Connections on iOS where the app wouldn't properly redirect back after authentication. [#1178](https://github.com/stripe/stripe-react-native/pull/1178) - Fixed `borderWidth` and `borderRadius` for `` and `CardForm />` was inconsistent across iOS and Android. [#1182](https://github.com/stripe/stripe-react-native/pull/1182) From 9b72fb5191aaae322cce195fc146f2328b15c5d7 Mon Sep 17 00:00:00 2001 From: Charlie Cruzan Date: Wed, 2 Nov 2022 13:17:04 -0700 Subject: [PATCH 3/3] fix tests --- e2e/FinancialConnections.test.ts | 5 ++++- e2e/buyNowPayLater.test.ts | 4 ++++ e2e/screenObject/BasicPaymentScreen.ts | 8 ++++---- wdio.android.js | 12 +++++++++++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/e2e/FinancialConnections.test.ts b/e2e/FinancialConnections.test.ts index 84f4af008..87057f033 100644 --- a/e2e/FinancialConnections.test.ts +++ b/e2e/FinancialConnections.test.ts @@ -53,7 +53,10 @@ describe('Financial Connections', () => { }); function authorizeBankAccount() { - driver.pause(5000); + driver.waitUntil(() => getAllWebviewContexts().length > 0, { + timeout: 10000, + interval: 1000, + }); const webviewContexts = getAllWebviewContexts(); for (const context of webviewContexts) { try { diff --git a/e2e/buyNowPayLater.test.ts b/e2e/buyNowPayLater.test.ts index 8094ad5a2..718d8d942 100644 --- a/e2e/buyNowPayLater.test.ts +++ b/e2e/buyNowPayLater.test.ts @@ -49,6 +49,10 @@ describe('Payment scenarios with redirects', () => { BasicPaymentScreen.pay({ email: 'test@stripe.com' }); driver.pause(10000); + driver.waitUntil(() => getAllWebviewContexts().length > 0, { + timeout: 10000, + interval: 1000, + }); const webviewContexts = getAllWebviewContexts(); expect(webviewContexts.length).toBeGreaterThan(0); }); diff --git a/e2e/screenObject/BasicPaymentScreen.ts b/e2e/screenObject/BasicPaymentScreen.ts index ed342b919..4535f9b3c 100644 --- a/e2e/screenObject/BasicPaymentScreen.ts +++ b/e2e/screenObject/BasicPaymentScreen.ts @@ -73,7 +73,10 @@ class BasicPaymentScreen { } authorizeACH() { - driver.pause(5000); + driver.waitUntil(() => getAllWebviewContexts().length > 0, { + timeout: 10000, + interval: 1000, + }); const webviewContexts = getAllWebviewContexts(); for (const context of webviewContexts) { try { @@ -132,9 +135,6 @@ export function getAllWebviewContexts(): string[] { const webviewContext = allContexts.filter((contextName) => contextName.toLowerCase().includes('webview') ); - if (!webviewContext.length) { - throw new Error('No webview context was found.'); - } return webviewContext.sort((a, b) => { if (a.includes('stripe') && !b.includes('stripe')) { diff --git a/wdio.android.js b/wdio.android.js index 6cbca56a2..40c36e6ed 100644 --- a/wdio.android.js +++ b/wdio.android.js @@ -23,7 +23,16 @@ exports.config = { waitforTimeout: 8000, connectionRetryTimeout: 200000, connectionRetryCount: 4, - services: ['appium'], + services: [ + [ + 'appium', + { + args: { + allowInsecure: 'chromedriver_autodownload', + }, + }, + ], + ], framework: 'mocha', reporters: ['spec'], mochaOpts: { @@ -45,6 +54,7 @@ exports.config = { avdArgs: '-wipe-data', autoGrantPermissions: true, androidInstallTimeout: 200000, + chromeOptions: { w3c: false }, }, ], afterTest: function (test, _context, { passed }) {