diff --git a/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt b/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt index 1c9b27b04f..b88acdafb6 100644 --- a/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +++ b/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt @@ -38,6 +38,7 @@ class PaymentMethodCreateParamsFactory( PaymentMethod.Type.PayPal -> createPayPalParams() PaymentMethod.Type.Affirm -> createAffirmParams() PaymentMethod.Type.CashAppPay -> createCashAppParams() + PaymentMethod.Type.BacsDebit -> createBacsParams() PaymentMethod.Type.RevolutPay -> createRevolutPayParams() else -> { throw Exception("This paymentMethodType is not supported yet") @@ -98,6 +99,28 @@ class PaymentMethodCreateParamsFactory( throw PaymentMethodCreateParamsException("You must provide billing details") } + @Throws(PaymentMethodCreateParamsException::class) + private fun createBacsParams(): PaymentMethodCreateParams { + billingDetailsParams?.let { + val accountNumber = getValOr(paymentMethodData, "accountNumber", null) ?: run { + throw PaymentMethodCreateParamsException("You must provide Account number") + } + val sortCode = getValOr(paymentMethodData, "sortCode", null) ?: run { + throw PaymentMethodCreateParamsException("You must provide Sort code") + } + + return PaymentMethodCreateParams.create( + bacsDebit = PaymentMethodCreateParams.BacsDebit( + accountNumber = accountNumber, + sortCode = sortCode + ), + billingDetails = it + ) + } + + throw PaymentMethodCreateParamsException("You must provide billing details") + } + @Throws(PaymentMethodCreateParamsException::class) private fun createOXXOParams(): PaymentMethodCreateParams { billingDetailsParams?.let { @@ -236,6 +259,7 @@ class PaymentMethodCreateParamsFactory( PaymentMethod.Type.AuBecsDebit, PaymentMethod.Type.Klarna, PaymentMethod.Type.PayPal, + PaymentMethod.Type.BacsDebit, PaymentMethod.Type.CashAppPay, PaymentMethod.Type.RevolutPay -> { val params = createPaymentMethodParams(paymentMethodType) diff --git a/e2e-tests/bacs-payment.yml b/e2e-tests/bacs-payment.yml new file mode 100644 index 0000000000..0f7b37138e --- /dev/null +++ b/e2e-tests/bacs-payment.yml @@ -0,0 +1,22 @@ +appId: ${APP_ID} +--- +- launchApp +- tapOn: 'Bank Debits' +- tapOn: 'Bacs Direct Debit payment' +- assertVisible: + text: 'E-mail' +- tapOn: + text: 'E-mail' +- inputText: 'test@stripe.com' +- tapOn: + text: 'sortCode' +- inputText: '108800' +- tapOn: + text: 'accountNumber' +- inputText: '90012345' +- tapOn: + text: 'Pay' + retryTapIfNoChange: false +- assertVisible: + text: 'Processing' +- tapOn: 'OK' diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 1cf9fb13a2..e7ce636ce3 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -642,4 +642,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: d98ea981c14c48ddbbd4f2d6bcf130927b15a93f -COCOAPODS: 1.11.3 +COCOAPODS: 1.12.0 diff --git a/example/server/index.ts b/example/server/index.ts index 33c06e01be..d51cc10792 100644 --- a/example/server/index.ts +++ b/example/server/index.ts @@ -71,6 +71,7 @@ function getKeys(payment_method?: string) { secret_key = process.env.STRIPE_SECRET_KEY_WECHAT; break; case 'paypal': + case 'bacs_debit': case 'revolut_pay': publishable_key = process.env.STRIPE_PUBLISHABLE_KEY_UK; secret_key = process.env.STRIPE_SECRET_KEY_UK; diff --git a/example/src/App.tsx b/example/src/App.tsx index ecfb207337..e6b2c0bf07 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -41,11 +41,13 @@ import PayPalScreen from './screens/PayPalScreen'; import AffirmScreen from './screens/AffirmScreen'; import CollectBankAccountScreen from './screens/CollectBankAccountScreen'; import CashAppScreen from './screens/CashAppScreen'; +import BacsDebitPaymentScreen from './screens/BacsDebitPaymentScreen'; import PaymentSheetDeferredIntentScreen from './screens/PaymentSheetDeferredIntentScreen'; import PaymentSheetDeferredIntentMultiStepScreen from './screens/PaymentSheetDeferredIntentMultiStepScreen'; import CustomerSheetScreen from './screens/CustomerSheetScreen'; import RevolutPayScreen from './screens/RevolutPayScreen'; + const Stack = createNativeStackNavigator(); export type RootStackParamList = { @@ -87,6 +89,7 @@ export type RootStackParamList = { CashAppScreen: undefined; AffirmScreen: undefined; CollectBankAccountScreen: undefined; + BacsDebitPaymentScreen: undefined; PaymentSheetDeferredIntentScreen: undefined; PaymentSheetDeferredIntentMultiStepScreen: undefined; CustomerSheetScreen: undefined; @@ -216,6 +219,10 @@ export default function App() { name="SepaPaymentScreen" component={SepaPaymentScreen} /> + { + const response = await fetch(`${API_URL}/create-payment-intent`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + email, + currency: 'gbp', + items: ['id-1'], + payment_method_types: ['bacs_debit'], + }), + }); + const { clientSecret, error } = await response.json(); + + return { clientSecret, error }; + }; + + const handlePayPress = async () => { + const { clientSecret, error: clientSecretError } = + await fetchPaymentIntentClientSecret(); + + if (clientSecretError) { + Alert.alert(`Error`, clientSecretError); + return; + } + + const billingDetails: BillingDetails = { + name: 'John Doe', + email: email, + address: { + country: 'UK', + line1: 'test', + city: 'test', + }, + }; + setCanPay(false); + + const { error, paymentIntent } = await confirmPayment(clientSecret, { + paymentMethodType: 'BacsDebit', + paymentMethodData: { billingDetails, sortCode, accountNumber }, + }); + + if (error) { + Alert.alert(`Error code: ${error.code}`, error.message); + } else if (paymentIntent) { + if (paymentIntent.status === PaymentIntent.Status.Processing) { + Alert.alert( + 'Processing', + `The debit has been successfully submitted and is now processing.` + ); + } else if (paymentIntent.status === PaymentIntent.Status.Succeeded) { + Alert.alert( + 'Success', + `The payment was confirmed successfully! currency: ${paymentIntent.currency}` + ); + } else { + Alert.alert('Payment status:', paymentIntent.status); + } + } + setCanPay(true); + }; + + return ( + + setEmail(value.nativeEvent.text)} + style={styles.input} + /> + setSortCode(value.nativeEvent.text.toLowerCase())} + style={styles.input} + /> + + + setAccountNumber(value.nativeEvent.text.toLowerCase()) + } + style={styles.input} + /> +