@stripe/stripe-react-native 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/android/src/main/java/com/reactnativestripesdk/Mappers.kt +46 -0
  3. package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherFragment.kt +15 -8
  4. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +1 -1
  5. package/ios/.DS_Store +0 -0
  6. package/ios/Errors.swift +9 -35
  7. package/ios/Mappers.swift +105 -2
  8. package/ios/PaymentMethodFactory.swift +46 -1
  9. package/ios/StripeSdk.m +14 -0
  10. package/ios/StripeSdk.swift +284 -103
  11. package/lib/commonjs/NativeStripeSdk.js.map +1 -1
  12. package/lib/commonjs/functions.js +1 -1
  13. package/lib/commonjs/functions.js.map +1 -1
  14. package/lib/commonjs/hooks/useStripe.js +1 -1
  15. package/lib/commonjs/hooks/useStripe.js.map +1 -1
  16. package/lib/commonjs/types/NextAction.js +2 -0
  17. package/lib/commonjs/types/NextAction.js.map +1 -0
  18. package/lib/commonjs/types/PaymentIntents.js.map +1 -1
  19. package/lib/commonjs/types/PaymentMethods.js.map +1 -1
  20. package/lib/commonjs/types/SetupIntent.js.map +1 -1
  21. package/lib/commonjs/types/index.js.map +1 -1
  22. package/lib/module/NativeStripeSdk.js.map +1 -1
  23. package/lib/module/functions.js +1 -1
  24. package/lib/module/functions.js.map +1 -1
  25. package/lib/module/hooks/useStripe.js +1 -1
  26. package/lib/module/hooks/useStripe.js.map +1 -1
  27. package/lib/module/types/NextAction.js +2 -0
  28. package/lib/module/types/NextAction.js.map +1 -0
  29. package/lib/module/types/PaymentIntents.js.map +1 -1
  30. package/lib/module/types/PaymentMethods.js.map +1 -1
  31. package/lib/module/types/SetupIntent.js.map +1 -1
  32. package/lib/module/types/index.js.map +1 -1
  33. package/lib/typescript/e2e/helpers.d.ts +1 -0
  34. package/lib/typescript/e2e/screenObject/BasicPaymentScreen.d.ts +1 -0
  35. package/lib/typescript/e2e/screenObject/HomeScreen.d.ts +1 -1
  36. package/lib/typescript/example/src/App.d.ts +2 -0
  37. package/lib/typescript/example/src/screens/ACHPaymentScreen.d.ts +1 -0
  38. package/lib/typescript/example/src/screens/ACHSetupScreen.d.ts +1 -0
  39. package/lib/typescript/src/NativeStripeSdk.d.ts +3 -1
  40. package/lib/typescript/src/functions.d.ts +5 -1
  41. package/lib/typescript/src/hooks/useStripe.d.ts +5 -1
  42. package/lib/typescript/src/types/NextAction.d.ts +32 -0
  43. package/lib/typescript/src/types/PaymentIntents.d.ts +2 -0
  44. package/lib/typescript/src/types/PaymentMethods.d.ts +28 -2
  45. package/lib/typescript/src/types/SetupIntent.d.ts +4 -2
  46. package/lib/typescript/src/types/index.d.ts +15 -1
  47. package/package.json +3 -3
  48. package/src/NativeStripeSdk.tsx +12 -0
  49. package/src/functions.ts +146 -0
  50. package/src/hooks/useStripe.tsx +50 -0
  51. package/src/types/NextAction.ts +44 -0
  52. package/src/types/PaymentIntents.ts +2 -0
  53. package/src/types/PaymentMethods.ts +31 -2
  54. package/src/types/SetupIntent.ts +9 -2
  55. package/src/types/index.ts +24 -1
  56. package/stripe-react-native.podspec +3 -2
package/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.6.0
4
+
5
+ - [#861](https://github.com/stripe/stripe-react-native/pull/861) BREAKING: This library now supports iOS 12 and up, due to `stripe-ios` increasing the deployment target. If you would like to build for iOS 11, please continue to use `@stripe/stripe-react-native@0.5.0`.
6
+ - To upgrade your iOS deployment target to 12.0, you can either do so in Xcode under your `Build Settings`, or by modifying `IPHONEOS_DEPLOYMENT_TARGET` in your `project.pbxproj` directly. You will also need to update your Podfile to target `:ios, '12.0'`.
7
+ - [#861](https://github.com/stripe/stripe-react-native/pull/861) Feat: Add support for ACHv2 payments **on iOS only**.
8
+ - [#861](https://github.com/stripe/stripe-react-native/pull/861) Chore: Upgrade `stripe-ios` to 22.0.0.
9
+
3
10
  ## 0.5.0
11
+
4
12
  - [#863](https://github.com/stripe/stripe-react-native/pull/863) Feat: add card ID and bankAccount ID to token response
5
13
  - [#862](https://github.com/stripe/stripe-react-native/pull/862) Feat: Add support for setting a card's `currency` when creating a Token
6
14
  - [#854](https://github.com/stripe/stripe-react-native/pull/854) Chore: Upgrade `stripe-ios` to 21.13.0. Upgrade `stripe-android` to 19.3.0.
@@ -5,6 +5,8 @@ import android.util.Log
5
5
  import com.facebook.react.bridge.*
6
6
  import com.stripe.android.PaymentAuthConfig
7
7
  import com.stripe.android.model.*
8
+ import com.stripe.android.model.StripeIntent.NextActionType
9
+ import com.stripe.android.model.StripeIntent.NextActionData
8
10
 
9
11
  internal fun createResult(key: String, value: WritableMap): WritableMap {
10
12
  val map = WritableNativeMap()
@@ -344,6 +346,7 @@ internal fun mapFromPaymentIntentResult(paymentIntent: PaymentIntent): WritableM
344
346
  map.putString("created", convertToUnixTimestamp(paymentIntent.created))
345
347
  map.putString("captureMethod", mapCaptureMethod(paymentIntent.captureMethod))
346
348
  map.putString("confirmationMethod", mapConfirmationMethod(paymentIntent.confirmationMethod))
349
+ map.putMap("nextAction", mapNextAction(paymentIntent.nextActionType, paymentIntent.nextActionData))
347
350
  map.putNull("lastPaymentError")
348
351
  map.putNull("shipping")
349
352
  map.putNull("amount")
@@ -374,6 +377,48 @@ internal fun mapFromPaymentIntentResult(paymentIntent: PaymentIntent): WritableM
374
377
  return map
375
378
  }
376
379
 
380
+ internal fun mapNextAction(type: NextActionType?, data: NextActionData?): WritableNativeMap? {
381
+ val nextActionMap = WritableNativeMap()
382
+ when (type) {
383
+ NextActionType.RedirectToUrl -> {
384
+ (data as? NextActionData.RedirectToUrl)?.let {
385
+ nextActionMap.putString("type", "urlRedirect")
386
+ nextActionMap.putString("redirectUrl", it.url.toString())
387
+ }
388
+ }
389
+ // TODO: This is currently private. Uncomment when ACHv2 is available on Android.
390
+ // NextActionType.VerifyWithMicrodeposits -> {
391
+ // (data as? NextActionData.VerifyWithMicrodeposits)?.let {
392
+ // nextActionMap.putString("type", "verifyWithMicrodeposits")
393
+ // nextActionMap.putString("arrivalDate", it.arrivalDate.toString())
394
+ // nextActionMap.putString("redirectUrl", it.hostedVerificationUrl)
395
+ // nextActionMap.putString("microdepositType", it.microdepositType.toString())
396
+ // }
397
+ // }
398
+ NextActionType.DisplayOxxoDetails -> {
399
+ (data as? NextActionData.DisplayOxxoDetails)?.let {
400
+ nextActionMap.putString("type", "oxxoVoucher")
401
+ nextActionMap.putInt("expiration", it.expiresAfter)
402
+ nextActionMap.putString("voucherURL", it.hostedVoucherUrl)
403
+ nextActionMap.putString("voucherNumber", it.number)
404
+ }
405
+ }
406
+ NextActionType.WeChatPayRedirect -> {
407
+ (data as? NextActionData.WeChatPayRedirect)?.let {
408
+ nextActionMap.putString("type", "weChatRedirect")
409
+ nextActionMap.putString("redirectUrl", it.weChat.qrCodeUrl)
410
+ }
411
+ }
412
+ NextActionType.AlipayRedirect -> { // TODO: Can't access, private
413
+ return null
414
+ }
415
+ NextActionType.BlikAuthorize, NextActionType.UseStripeSdk, null -> {
416
+ return null
417
+ }
418
+ }
419
+ return nextActionMap
420
+ }
421
+
377
422
  internal fun mapFromPaymentIntentLastErrorType(errorType: PaymentIntent.Error.Type?): String? {
378
423
  return when (errorType) {
379
424
  PaymentIntent.Error.Type.ApiConnectionError -> "api_connection_error"
@@ -684,6 +729,7 @@ internal fun mapFromSetupIntentResult(setupIntent: SetupIntent): WritableMap {
684
729
  map.putString("paymentMethodId", setupIntent.paymentMethodId)
685
730
  map.putString("usage", mapSetupIntentUsage(setupIntent.usage))
686
731
  map.putString("created", convertToUnixTimestamp(setupIntent.created))
732
+ map.putMap("nextAction", mapNextAction(setupIntent.nextActionType, setupIntent.nextActionData))
687
733
 
688
734
  setupIntent.lastSetupError?.let {
689
735
  val setupError: WritableMap = WritableNativeMap()
@@ -70,7 +70,7 @@ class PaymentLauncherFragment(
70
70
  promise.resolve(paymentIntent)
71
71
  }
72
72
  StripeIntent.Status.RequiresAction -> {
73
- if (isPaymentIntentNextActionVoucherBased(result.nextActionType)) {
73
+ if (isNextActionSuccessState(result.nextActionType)) {
74
74
  val paymentIntent = createResult("paymentIntent", mapFromPaymentIntentResult(result))
75
75
  promise.resolve(paymentIntent)
76
76
  } else {
@@ -102,14 +102,21 @@ class PaymentLauncherFragment(
102
102
  })
103
103
  }
104
104
 
105
- /// Check paymentIntent.nextAction is voucher-based payment method.
106
- /// If it's voucher-based, the paymentIntent status stays in requiresAction until the voucher is paid or expired.
107
- /// Currently only OXXO payment is voucher-based.
108
- private fun isPaymentIntentNextActionVoucherBased(nextAction: StripeIntent.NextActionType?): Boolean {
109
- nextAction?.let {
110
- return it == StripeIntent.NextActionType.DisplayOxxoDetails
105
+ /**
106
+ * Check if paymentIntent.nextAction is out-of-band, such as voucher-based or waiting
107
+ * on customer verification. If it is, then being in this state is considered "successful".
108
+ */
109
+ private fun isNextActionSuccessState(nextAction: StripeIntent.NextActionType?): Boolean {
110
+ return when (nextAction) {
111
+ StripeIntent.NextActionType.DisplayOxxoDetails,
112
+ StripeIntent.NextActionType.VerifyWithMicrodeposits -> true
113
+ StripeIntent.NextActionType.RedirectToUrl,
114
+ StripeIntent.NextActionType.UseStripeSdk,
115
+ StripeIntent.NextActionType.AlipayRedirect,
116
+ StripeIntent.NextActionType.BlikAuthorize,
117
+ StripeIntent.NextActionType.WeChatPayRedirect,
118
+ null -> false
111
119
  }
112
- return false
113
120
  }
114
121
  }
115
122
 
@@ -154,7 +154,7 @@ class PaymentMethodCreateParamsFactory(
154
154
  val sepaParams = PaymentMethodCreateParams.SepaDebit(iban)
155
155
  val createParams =
156
156
  PaymentMethodCreateParams.create(
157
- sepaDebit = sepaParams,
157
+ sepaDebit = sepaParams,
158
158
  billingDetails = it
159
159
  )
160
160
 
package/ios/.DS_Store ADDED
Binary file
package/ios/Errors.swift CHANGED
@@ -1,35 +1,9 @@
1
1
  import Stripe
2
2
 
3
- enum ConfirmPaymentErrorType: String {
4
- case Failed, Canceled, Unknown
5
- }
6
-
7
- enum ApplePayErrorType: String {
8
- case Failed, Canceled, Unknown
9
- }
10
-
11
- enum NextPaymentActionErrorType: String {
12
- case Failed, Canceled, Unknown
13
- }
14
-
15
- enum ConfirmSetupIntentErrorType: String {
16
- case Failed, Canceled, Unknown
17
- }
18
-
19
- enum RetrievePaymentIntentErrorType: String {
20
- case Unknown
21
- }
22
-
23
- enum RetrieveSetupIntentErrorType: String {
24
- case Unknown
25
- }
26
-
27
- enum PaymentSheetErrorType: String {
28
- case Failed, Canceled
29
- }
30
-
31
- enum CreateTokenErrorType: String {
32
- case Failed
3
+ enum ErrorType {
4
+ static let Failed = "Failed"
5
+ static let Canceled = "Canceled"
6
+ static let Unknown = "Unknown"
33
7
  }
34
8
 
35
9
  class Errors {
@@ -76,11 +50,11 @@ class Errors {
76
50
  class func createError (_ code: String, _ error: NSError?) -> NSDictionary {
77
51
  let value: NSDictionary = [
78
52
  "code": code,
79
- "message": error?.userInfo["com.stripe.lib:ErrorMessageKey"] ?? error?.userInfo["NSLocalizedDescription"] ?? NSNull(),
80
- "localizedMessage": error?.userInfo["NSLocalizedDescription"] ?? NSNull(),
81
- "declineCode": error?.userInfo["com.stripe.lib:DeclineCodeKey"] ?? NSNull(),
82
- "stripeErrorCode": error?.userInfo["com.stripe.lib:StripeErrorCodeKey"] ?? NSNull(),
83
- "type": error?.userInfo["com.stripe.lib:StripeErrorTypeKey"] ?? NSNull(),
53
+ "message": error?.userInfo[STPError.errorMessageKey] ?? NSNull(),
54
+ "localizedMessage": error?.localizedDescription ?? NSNull(),
55
+ "declineCode": error?.userInfo[STPError.stripeDeclineCodeKey] ?? NSNull(),
56
+ "stripeErrorCode": error?.userInfo[STPError.stripeErrorCodeKey] ?? NSNull(),
57
+ "type": error?.userInfo[STPError.stripeErrorTypeKey] ?? NSNull(),
84
58
  ]
85
59
 
86
60
  return ["error": value]
package/ios/Mappers.swift CHANGED
@@ -282,6 +282,7 @@ class Mappers {
282
282
  case STPPaymentMethodType.UPI: return "Upi"
283
283
  case STPPaymentMethodType.afterpayClearpay: return "AfterpayClearpay"
284
284
  case STPPaymentMethodType.klarna: return "Klarna"
285
+ case STPPaymentMethodType.USBankAccount: return "USBankAccount"
285
286
  case STPPaymentMethodType.unknown: return "Unknown"
286
287
  default: return "Unknown"
287
288
  }
@@ -309,6 +310,7 @@ class Mappers {
309
310
  case "AfterpayClearpay": return STPPaymentMethodType.afterpayClearpay
310
311
  case "Klarna": return STPPaymentMethodType.klarna
311
312
  case "WeChatPay": return STPPaymentMethodType.weChatPay
313
+ case "USBankAccount": return STPPaymentMethodType.USBankAccount
312
314
  default: return STPPaymentMethodType.unknown
313
315
  }
314
316
  }
@@ -374,7 +376,8 @@ class Mappers {
374
376
  "amount": paymentIntent.amount,
375
377
  "lastPaymentError": NSNull(),
376
378
  "shipping": NSNull(),
377
- "canceledAt": NSNull()
379
+ "canceledAt": NSNull(),
380
+ "nextAction": mapNextAction(nextAction: paymentIntent.nextAction) ?? NSNull(),
378
381
  ]
379
382
 
380
383
  if let lastPaymentError = paymentIntent.lastPaymentError {
@@ -400,6 +403,55 @@ class Mappers {
400
403
  return intent;
401
404
  }
402
405
 
406
+ class func mapNextAction(nextAction: STPIntentAction?) -> NSDictionary? {
407
+ if let it = nextAction {
408
+ switch it.type {
409
+ case .verifyWithMicrodeposits:
410
+ return [
411
+ "type": "verifyWithMicrodeposits",
412
+ "redirectUrl": it.verifyWithMicrodeposits?.hostedVerificationURL.absoluteString ?? NSNull(),
413
+ "microdepositType": it.verifyWithMicrodeposits?.microdepositType.description ?? NSNull(),
414
+ "arrivalDate": it.verifyWithMicrodeposits?.arrivalDate.timeIntervalSince1970.description ?? NSNull(),
415
+ ]
416
+ case .redirectToURL:
417
+ return [
418
+ "type": "urlRedirect",
419
+ "redirectUrl": it.redirectToURL?.url.absoluteString ?? NSNull()
420
+ ]
421
+ case .weChatPayRedirectToApp:
422
+ return [
423
+ "type": "weChatRedirect",
424
+ "redirectUrl": it.weChatPayRedirectToApp?.nativeURL?.absoluteString ?? NSNull()
425
+ ]
426
+ case .alipayHandleRedirect:
427
+ return [
428
+ "type": "alipayRedirect",
429
+ "redirectUrl": it.alipayHandleRedirect?.url.absoluteString ?? NSNull(),
430
+ "nativeRedirectUrl": it.alipayHandleRedirect?.nativeURL?.absoluteString ?? NSNull(),
431
+ ]
432
+ case .OXXODisplayDetails:
433
+ return [
434
+ "type": "oxxoVoucher",
435
+ "expiration": it.oxxoDisplayDetails?.expiresAfter.timeIntervalSince1970 ?? NSNull(),
436
+ "voucherURL": it.oxxoDisplayDetails?.hostedVoucherURL.absoluteString ?? NSNull(),
437
+ "voucherNumber": it.oxxoDisplayDetails?.number ?? NSNull(),
438
+ ]
439
+ // TODO: Not supported on Android
440
+ // case .boletoDisplayDetails:
441
+ // return [
442
+ // "type": "boletoVoucher",
443
+ // "expiration": it.boletoDisplayDetails?.expiresAt.timeIntervalSince1970.description ?? NSNull(),
444
+ // "voucherURL": it.boletoDisplayDetails?.hostedVoucherURL.absoluteString ?? NSNull(),
445
+ // "voucherNumber": it.boletoDisplayDetails?.number ?? NSNull(),
446
+ // ]
447
+ default: // .useStripeSDK, .BLIKAuthorize, .unknown
448
+ return nil
449
+ }
450
+ } else {
451
+ return nil
452
+ }
453
+ }
454
+
403
455
  class func mapFromPaymentIntentLastPaymentErrorType(_ errorType: STPPaymentIntentLastPaymentErrorType?) -> String? {
404
456
  if let errorType = errorType {
405
457
  switch errorType {
@@ -539,6 +591,17 @@ class Mappers {
539
591
  "fingerprint": paymentMethod.auBECSDebit?.fingerprint ?? NSNull(),
540
592
  "last4": paymentMethod.auBECSDebit?.last4 ?? NSNull()
541
593
  ]
594
+ let USBankAccount: NSDictionary = [
595
+ "routingNumber": paymentMethod.usBankAccount?.routingNumber ?? NSNull(),
596
+ "accountHolderType": mapFromUSBankAccountHolderType(type: paymentMethod.usBankAccount?.accountHolderType),
597
+ "accountType": mapFromUSBankAccountType(type: paymentMethod.usBankAccount?.accountType),
598
+ "last4": paymentMethod.usBankAccount?.last4 ?? NSNull(),
599
+ "bankName": paymentMethod.usBankAccount?.bankName ?? NSNull(),
600
+ "linkedAccount": paymentMethod.usBankAccount?.linkedAccount ?? NSNull(),
601
+ "fingerprint": paymentMethod.usBankAccount?.fingerprint ?? NSNull(),
602
+ "preferredNetworks": paymentMethod.usBankAccount?.networks?.preferred ?? NSNull(),
603
+ "supportedNetworks": paymentMethod.usBankAccount?.networks?.supported ?? NSNull(),
604
+ ]
542
605
  let method: NSDictionary = [
543
606
  "id": paymentMethod.stripeId,
544
607
  "type": Mappers.mapPaymentMethodType(type: paymentMethod.type),
@@ -562,6 +625,7 @@ class Mappers {
562
625
  "Upi": [
563
626
  "vpa": paymentMethod.upi?.vpa
564
627
  ],
628
+ "USBankAccount": USBankAccount
565
629
  ]
566
630
  return method
567
631
  }
@@ -619,7 +683,8 @@ class Mappers {
619
683
  "usage": mapFromSetupIntentUsage(usage: setupIntent.usage),
620
684
  "paymentMethodId": setupIntent.paymentMethodID ?? NSNull(),
621
685
  "created": NSNull(),
622
- "lastSetupError": NSNull()
686
+ "lastSetupError": NSNull(),
687
+ "nextAction": mapNextAction(nextAction: setupIntent.nextAction) ?? NSNull(),
623
688
  ]
624
689
 
625
690
 
@@ -853,4 +918,42 @@ class Mappers {
853
918
  }
854
919
  return "Unknown"
855
920
  }
921
+
922
+ class func mapFromUSBankAccountHolderType(type: STPPaymentMethodUSBankAccountHolderType?) -> String {
923
+ if let type = type {
924
+ switch type {
925
+ case STPPaymentMethodUSBankAccountHolderType.company: return "Company"
926
+ case STPPaymentMethodUSBankAccountHolderType.individual: return "Individual"
927
+ case STPPaymentMethodUSBankAccountHolderType.unknown: return "Unknown"
928
+ }
929
+ }
930
+ return "Unknown"
931
+ }
932
+
933
+ class func mapToUSBankAccountHolderType(type: String?) -> STPPaymentMethodUSBankAccountHolderType {
934
+ switch type {
935
+ case "Company": return STPPaymentMethodUSBankAccountHolderType.company
936
+ case "Individual": return STPPaymentMethodUSBankAccountHolderType.individual
937
+ default: return STPPaymentMethodUSBankAccountHolderType.individual
938
+ }
939
+ }
940
+
941
+ class func mapFromUSBankAccountType(type: STPPaymentMethodUSBankAccountType?) -> String {
942
+ if let type = type {
943
+ switch type {
944
+ case STPPaymentMethodUSBankAccountType.savings: return "Savings"
945
+ case STPPaymentMethodUSBankAccountType.checking: return "Checking"
946
+ case STPPaymentMethodUSBankAccountType.unknown: return "Unknown"
947
+ }
948
+ }
949
+ return "Unknown"
950
+ }
951
+
952
+ class func mapToUSBankAccountType(type: String?) -> STPPaymentMethodUSBankAccountType {
953
+ switch type {
954
+ case "Savings": return STPPaymentMethodUSBankAccountType.savings
955
+ case "Checking": return STPPaymentMethodUSBankAccountType.checking
956
+ default: return STPPaymentMethodUSBankAccountType.checking
957
+ }
958
+ }
856
959
  }
@@ -47,6 +47,8 @@ class PaymentMethodFactory {
47
47
  return try createAfterpayClearpayPaymentMethodParams()
48
48
  case STPPaymentMethodType.klarna:
49
49
  return try createKlarnaPaymentMethodParams()
50
+ case STPPaymentMethodType.USBankAccount:
51
+ return try createUSBankAccountPaymentMethodParams()
50
52
  // case STPPaymentMethodType.weChatPay:
51
53
  // return try createWeChatPayPaymentMethodParams()
52
54
  default:
@@ -92,6 +94,8 @@ class PaymentMethodFactory {
92
94
  return nil
93
95
  case STPPaymentMethodType.weChatPay:
94
96
  return try createWeChatPayPaymentMethodOptions()
97
+ case STPPaymentMethodType.USBankAccount:
98
+ return try createUSBankAccountPaymentMethodOptions()
95
99
  default:
96
100
  throw PaymentMethodError.paymentNotSupported
97
101
  }
@@ -105,6 +109,16 @@ class PaymentMethodFactory {
105
109
  // return STPPaymentMethodParams(weChatPay: params, billingDetails: billingDetailsParams, metadata: nil)
106
110
  // }
107
111
  //
112
+
113
+ private func createUSBankAccountPaymentMethodOptions() throws -> STPConfirmPaymentMethodOptions {
114
+ let paymentOptions = STPConfirmPaymentMethodOptions()
115
+ if let usage = self.params?["setupFutureUsage"] as? String {
116
+ paymentOptions.usBankAccountOptions = STPConfirmUSBankAccountOptions(setupFutureUsage: Mappers.mapToPaymentIntentFutureUsage(usage: usage))
117
+ }
118
+
119
+ return paymentOptions
120
+ }
121
+
108
122
  private func createWeChatPayPaymentMethodOptions() throws -> STPConfirmPaymentMethodOptions {
109
123
  guard let appId = self.params?["appId"] as? String else {
110
124
  throw PaymentMethodError.weChatPayPaymentMissingParams
@@ -307,13 +321,35 @@ class PaymentMethodFactory {
307
321
 
308
322
  private func createKlarnaPaymentMethodParams() throws -> STPPaymentMethodParams {
309
323
  let params = STPPaymentMethodKlarnaParams()
310
-
324
+
311
325
  if let billingDetails = billingDetailsParams, billingDetails.address?.country != nil, billingDetails.email != nil {
312
326
  return STPPaymentMethodParams(klarna: params, billingDetails: billingDetails, metadata: nil)
313
327
  } else {
314
328
  throw PaymentMethodError.klarnaPaymentMissingParams
315
329
  }
316
330
  }
331
+
332
+ private func createUSBankAccountPaymentMethodParams() throws -> STPPaymentMethodParams {
333
+ let params = STPPaymentMethodUSBankAccountParams()
334
+
335
+ guard let accountNumber = self.params?["accountNumber"] as? String else {
336
+ throw PaymentMethodError.usBankAccountPaymentMissingAccountNumber
337
+ }
338
+ guard let routingNumber = self.params?["routingNumber"] as? String else {
339
+ throw PaymentMethodError.usBankAccountPaymentMissingRoutingNumber
340
+ }
341
+
342
+ params.accountNumber = accountNumber
343
+ params.routingNumber = routingNumber
344
+ params.accountHolderType = Mappers.mapToUSBankAccountHolderType(type: self.params?["accountHolderType"] as? String)
345
+ params.accountType = Mappers.mapToUSBankAccountType(type: self.params?["accountType"] as? String)
346
+
347
+ if let billingDetails = billingDetailsParams, billingDetails.name != nil {
348
+ return STPPaymentMethodParams(usBankAccount: params, billingDetails: billingDetails, metadata: nil)
349
+ } else {
350
+ throw PaymentMethodError.usBankAccountPaymentMissingParams
351
+ }
352
+ }
317
353
  }
318
354
 
319
355
  enum PaymentMethodError: Error {
@@ -330,6 +366,9 @@ enum PaymentMethodError: Error {
330
366
  case afterpayClearpayPaymentMissingParams
331
367
  case klarnaPaymentMissingParams
332
368
  case weChatPayPaymentMissingParams
369
+ case usBankAccountPaymentMissingParams
370
+ case usBankAccountPaymentMissingAccountNumber
371
+ case usBankAccountPaymentMissingRoutingNumber
333
372
  }
334
373
 
335
374
  extension PaymentMethodError: LocalizedError {
@@ -361,6 +400,12 @@ extension PaymentMethodError: LocalizedError {
361
400
  return NSLocalizedString("You must provide appId", comment: "Create payment error")
362
401
  case .klarnaPaymentMissingParams:
363
402
  return NSLocalizedString("Klarna requires that you provide the following billing details: email, country", comment: "Create payment error")
403
+ case .usBankAccountPaymentMissingParams:
404
+ return NSLocalizedString("When creating a US bank account payment method, you must provide the following billing details: name", comment: "Create payment error")
405
+ case .usBankAccountPaymentMissingAccountNumber:
406
+ return NSLocalizedString("When creating a US bank account payment method, you must provide the bank account number", comment: "Create payment error")
407
+ case .usBankAccountPaymentMissingRoutingNumber:
408
+ return NSLocalizedString("When creating a US bank account payment method, you must provide the bank routing number", comment: "Create payment error")
364
409
  }
365
410
  }
366
411
  }
package/ios/StripeSdk.m CHANGED
@@ -107,5 +107,19 @@ RCT_EXTERN_METHOD(
107
107
  rejecter: (RCTPromiseRejectBlock)reject
108
108
  )
109
109
 
110
+ RCT_EXTERN_METHOD(
111
+ verifyMicrodeposits:(NSString *)intentType
112
+ clientSecret:(NSString *)clientSecret
113
+ params:(NSDictionary *)params
114
+ resolver: (RCTPromiseResolveBlock)resolve
115
+ rejecter: (RCTPromiseRejectBlock)reject
116
+ )
117
+ RCT_EXTERN_METHOD(
118
+ collectBankAccount:(NSString *)intentType
119
+ clientSecret:(NSString *)clientSecret
120
+ params:(NSDictionary *)params
121
+ resolver: (RCTPromiseResolveBlock)resolve
122
+ rejecter: (RCTPromiseRejectBlock)reject
123
+ )
110
124
 
111
125
  @end