@stripe/stripe-react-native 0.67.0 → 0.69.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 (230) hide show
  1. package/android/build.gradle +3 -3
  2. package/android/gradle.properties +1 -1
  3. package/android/proguard-rules.txt +4 -0
  4. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorAppearance.kt +229 -0
  5. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementView.kt +8 -1
  6. package/android/src/main/java/com/reactnativestripesdk/CurrencySelectorElementViewManager.kt +11 -0
  7. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +0 -22
  8. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +0 -22
  9. package/android/src/main/java/com/reactnativestripesdk/LinkControllerManager.kt +175 -0
  10. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +11 -4
  11. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +43 -38
  12. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonManager.kt +8 -0
  13. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonView.kt +6 -0
  14. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/PushProvisioningProxy.kt +6 -5
  15. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/TapAndPayProxy.kt +91 -0
  16. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddToWalletButtonManagerDelegate.java +3 -0
  17. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddToWalletButtonManagerInterface.java +1 -0
  18. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerDelegate.java +0 -3
  19. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerInterface.java +0 -1
  20. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerDelegate.java +4 -0
  21. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeCurrencySelectorElementManagerInterface.java +2 -0
  22. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +8 -8
  23. package/android/src/onramp/java/com/reactnativestripesdk/OnrampErrors.kt +9 -28
  24. package/android/src/onramp/java/com/reactnativestripesdk/OnrampSdkModule.kt +10 -9
  25. package/android/src/test/java/com/reactnativestripesdk/CurrencySelectorAppearanceTest.kt +137 -0
  26. package/android/src/test/java/com/reactnativestripesdk/OnrampErrorsTest.kt +20 -18
  27. package/ios/CurrencySelectorAppearance.swift +120 -0
  28. package/ios/CurrencySelectorElementManager.m +1 -0
  29. package/ios/CurrencySelectorElementView.swift +17 -2
  30. package/ios/Mappers+Checkout.swift +3 -3
  31. package/ios/NewArch/EmbeddedPaymentElementViewComponentView.mm +0 -4
  32. package/ios/NewArch/StripeCurrencySelectorElementComponentView.mm +1 -0
  33. package/ios/OnrampErrors.swift +1 -14
  34. package/ios/StripeSdk.mm +15 -22
  35. package/ios/StripeSdkImpl+Checkout.swift +15 -39
  36. package/ios/StripeSdkImpl+Embedded.swift +0 -24
  37. package/ios/StripeSdkImpl+LinkController.swift +108 -0
  38. package/ios/StripeSdkImpl+PaymentSheet.swift +1 -2
  39. package/ios/StripeSdkImpl.swift +8 -3
  40. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  41. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  42. package/lib/commonjs/components/AddressSheet.js +1 -1
  43. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  44. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  45. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  46. package/lib/commonjs/components/CardField.js +1 -1
  47. package/lib/commonjs/components/CardField.js.map +1 -1
  48. package/lib/commonjs/components/CardForm.js +1 -1
  49. package/lib/commonjs/components/CardForm.js.map +1 -1
  50. package/lib/commonjs/components/CurrencySelectorElement.js +1 -1
  51. package/lib/commonjs/components/CurrencySelectorElement.js.map +1 -1
  52. package/lib/commonjs/components/PaymentMethodMessagingElement.js +1 -1
  53. package/lib/commonjs/components/PaymentMethodMessagingElement.js.map +1 -1
  54. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  55. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  56. package/lib/commonjs/components/StripeContainer.js +1 -1
  57. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  58. package/lib/commonjs/connect/Components.js +1 -1
  59. package/lib/commonjs/connect/Components.js.map +1 -1
  60. package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
  61. package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
  62. package/lib/commonjs/connect/EmbeddedComponent.js +2 -2
  63. package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
  64. package/lib/commonjs/connect/ModalCloseButton.js +1 -1
  65. package/lib/commonjs/connect/ModalCloseButton.js.map +1 -1
  66. package/lib/commonjs/connect/NavigationBar.js +1 -1
  67. package/lib/commonjs/connect/NavigationBar.js.map +1 -1
  68. package/lib/commonjs/functions.js +1 -1
  69. package/lib/commonjs/functions.js.map +1 -1
  70. package/lib/commonjs/helpers.js +1 -1
  71. package/lib/commonjs/hooks/useCheckout.js +1 -1
  72. package/lib/commonjs/hooks/useCheckout.js.map +1 -1
  73. package/lib/commonjs/hooks/useLinkController.js +2 -0
  74. package/lib/commonjs/hooks/useLinkController.js.map +1 -0
  75. package/lib/commonjs/index.js +1 -1
  76. package/lib/commonjs/index.js.map +1 -1
  77. package/lib/commonjs/specs/NativeAddToWalletButton.js +1 -1
  78. package/lib/commonjs/specs/NativeAddToWalletButton.js.map +1 -1
  79. package/lib/commonjs/specs/NativeAddressSheet.js +1 -1
  80. package/lib/commonjs/specs/NativeApplePayButton.js +1 -1
  81. package/lib/commonjs/specs/NativeAuBECSDebitForm.js +1 -1
  82. package/lib/commonjs/specs/NativeCardField.js +1 -1
  83. package/lib/commonjs/specs/NativeCardField.js.map +1 -1
  84. package/lib/commonjs/specs/NativeCardForm.js +1 -1
  85. package/lib/commonjs/specs/NativeCardForm.js.map +1 -1
  86. package/lib/commonjs/specs/NativeConnectAccountOnboardingView.js +1 -1
  87. package/lib/commonjs/specs/NativeCurrencySelectorElement.js +1 -1
  88. package/lib/commonjs/specs/NativeCurrencySelectorElement.js.map +1 -1
  89. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +1 -1
  90. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  91. package/lib/commonjs/specs/NativeGooglePayButton.js +1 -1
  92. package/lib/commonjs/specs/NativeNavigationBar.js +1 -1
  93. package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +1 -1
  94. package/lib/commonjs/specs/NativeStripeContainer.js +1 -1
  95. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
  96. package/lib/commonjs/types/EmbeddedPaymentElement.js +1 -1
  97. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
  98. package/lib/commonjs/types/Errors.js +1 -1
  99. package/lib/commonjs/types/Errors.js.map +1 -1
  100. package/lib/commonjs/types/LinkController.js +2 -0
  101. package/lib/commonjs/types/LinkController.js.map +1 -0
  102. package/lib/commonjs/types/PushProvisioning.js.map +1 -1
  103. package/lib/commonjs/types/index.js +1 -1
  104. package/lib/commonjs/types/index.js.map +1 -1
  105. package/lib/module/components/AddToWalletButton.js +1 -1
  106. package/lib/module/components/AddToWalletButton.js.map +1 -1
  107. package/lib/module/components/AddressSheet.js +1 -1
  108. package/lib/module/components/AddressSheet.js.map +1 -1
  109. package/lib/module/components/AuBECSDebitForm.js +1 -1
  110. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  111. package/lib/module/components/CardField.js +1 -1
  112. package/lib/module/components/CardField.js.map +1 -1
  113. package/lib/module/components/CardForm.js +1 -1
  114. package/lib/module/components/CardForm.js.map +1 -1
  115. package/lib/module/components/CurrencySelectorElement.js +1 -1
  116. package/lib/module/components/CurrencySelectorElement.js.map +1 -1
  117. package/lib/module/components/PaymentMethodMessagingElement.js +1 -1
  118. package/lib/module/components/PaymentMethodMessagingElement.js.map +1 -1
  119. package/lib/module/components/PlatformPayButton.js +1 -1
  120. package/lib/module/components/PlatformPayButton.js.map +1 -1
  121. package/lib/module/components/StripeContainer.js +1 -1
  122. package/lib/module/components/StripeContainer.js.map +1 -1
  123. package/lib/module/connect/Components.js +1 -1
  124. package/lib/module/connect/Components.js.map +1 -1
  125. package/lib/module/connect/ConnectComponentsProvider.js +1 -1
  126. package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
  127. package/lib/module/connect/EmbeddedComponent.js +2 -2
  128. package/lib/module/connect/EmbeddedComponent.js.map +1 -1
  129. package/lib/module/connect/ModalCloseButton.js +1 -1
  130. package/lib/module/connect/ModalCloseButton.js.map +1 -1
  131. package/lib/module/connect/NavigationBar.js +1 -1
  132. package/lib/module/connect/NavigationBar.js.map +1 -1
  133. package/lib/module/functions.js +1 -1
  134. package/lib/module/functions.js.map +1 -1
  135. package/lib/module/helpers.js +1 -1
  136. package/lib/module/hooks/useCheckout.js +1 -1
  137. package/lib/module/hooks/useCheckout.js.map +1 -1
  138. package/lib/module/hooks/useLinkController.js +2 -0
  139. package/lib/module/hooks/useLinkController.js.map +1 -0
  140. package/lib/module/index.js +1 -1
  141. package/lib/module/index.js.map +1 -1
  142. package/lib/module/specs/NativeAddToWalletButton.js +1 -1
  143. package/lib/module/specs/NativeAddToWalletButton.js.map +1 -1
  144. package/lib/module/specs/NativeAddressSheet.js +1 -1
  145. package/lib/module/specs/NativeApplePayButton.js +1 -1
  146. package/lib/module/specs/NativeAuBECSDebitForm.js +1 -1
  147. package/lib/module/specs/NativeCardField.js +1 -1
  148. package/lib/module/specs/NativeCardField.js.map +1 -1
  149. package/lib/module/specs/NativeCardForm.js +1 -1
  150. package/lib/module/specs/NativeCardForm.js.map +1 -1
  151. package/lib/module/specs/NativeConnectAccountOnboardingView.js +1 -1
  152. package/lib/module/specs/NativeCurrencySelectorElement.js +1 -1
  153. package/lib/module/specs/NativeCurrencySelectorElement.js.map +1 -1
  154. package/lib/module/specs/NativeEmbeddedPaymentElement.js +1 -1
  155. package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -1
  156. package/lib/module/specs/NativeGooglePayButton.js +1 -1
  157. package/lib/module/specs/NativeNavigationBar.js +1 -1
  158. package/lib/module/specs/NativePaymentMethodMessagingElement.js +1 -1
  159. package/lib/module/specs/NativeStripeContainer.js +1 -1
  160. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
  161. package/lib/module/types/EmbeddedPaymentElement.js +1 -1
  162. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
  163. package/lib/module/types/Errors.js +1 -1
  164. package/lib/module/types/Errors.js.map +1 -1
  165. package/lib/module/types/LinkController.js +2 -0
  166. package/lib/module/types/LinkController.js.map +1 -0
  167. package/lib/module/types/PushProvisioning.js.map +1 -1
  168. package/lib/module/types/index.js +1 -1
  169. package/lib/module/types/index.js.map +1 -1
  170. package/lib/typescript/src/components/AddToWalletButton.d.ts +2 -0
  171. package/lib/typescript/src/components/AddToWalletButton.d.ts.map +1 -1
  172. package/lib/typescript/src/components/CurrencySelectorElement.d.ts +76 -1
  173. package/lib/typescript/src/components/CurrencySelectorElement.d.ts.map +1 -1
  174. package/lib/typescript/src/connect/Components.d.ts +1 -1
  175. package/lib/typescript/src/connect/Components.d.ts.map +1 -1
  176. package/lib/typescript/src/connect/EmbeddedComponent.d.ts +23 -0
  177. package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
  178. package/lib/typescript/src/functions.d.ts +19 -1
  179. package/lib/typescript/src/functions.d.ts.map +1 -1
  180. package/lib/typescript/src/hooks/useCheckout.d.ts.map +1 -1
  181. package/lib/typescript/src/hooks/useLinkController.d.ts +28 -0
  182. package/lib/typescript/src/hooks/useLinkController.d.ts.map +1 -0
  183. package/lib/typescript/src/index.d.ts +1 -0
  184. package/lib/typescript/src/index.d.ts.map +1 -1
  185. package/lib/typescript/src/specs/NativeAddToWalletButton.d.ts +1 -0
  186. package/lib/typescript/src/specs/NativeAddToWalletButton.d.ts.map +1 -1
  187. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts +4 -0
  188. package/lib/typescript/src/specs/NativeCurrencySelectorElement.d.ts.map +1 -1
  189. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts +0 -1
  190. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts.map +1 -1
  191. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +5 -3
  192. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
  193. package/lib/typescript/src/types/Checkout.d.ts +1 -14
  194. package/lib/typescript/src/types/Checkout.d.ts.map +1 -1
  195. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +1 -10
  196. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
  197. package/lib/typescript/src/types/Errors.d.ts +8 -0
  198. package/lib/typescript/src/types/Errors.d.ts.map +1 -1
  199. package/lib/typescript/src/types/LinkController.d.ts +71 -0
  200. package/lib/typescript/src/types/LinkController.d.ts.map +1 -0
  201. package/lib/typescript/src/types/Onramp.d.ts +0 -13
  202. package/lib/typescript/src/types/Onramp.d.ts.map +1 -1
  203. package/lib/typescript/src/types/PaymentMethod.d.ts +2 -0
  204. package/lib/typescript/src/types/PaymentMethod.d.ts.map +1 -1
  205. package/lib/typescript/src/types/PushProvisioning.d.ts +2 -0
  206. package/lib/typescript/src/types/PushProvisioning.d.ts.map +1 -1
  207. package/lib/typescript/src/types/index.d.ts +2 -1
  208. package/lib/typescript/src/types/index.d.ts.map +1 -1
  209. package/package.json +1 -1
  210. package/src/components/AddToWalletButton.tsx +2 -0
  211. package/src/components/CurrencySelectorElement.tsx +101 -1
  212. package/src/connect/Components.tsx +10 -0
  213. package/src/connect/EmbeddedComponent.tsx +47 -10
  214. package/src/functions.ts +48 -0
  215. package/src/hooks/useCheckout.tsx +0 -14
  216. package/src/hooks/useLinkController.tsx +54 -0
  217. package/src/index.tsx +1 -0
  218. package/src/specs/NativeAddToWalletButton.ts +1 -0
  219. package/src/specs/NativeCurrencySelectorElement.ts +5 -0
  220. package/src/specs/NativeEmbeddedPaymentElement.ts +1 -10
  221. package/src/specs/NativeStripeSdkModule.ts +11 -10
  222. package/src/types/Checkout.ts +1 -19
  223. package/src/types/EmbeddedPaymentElement.tsx +4 -27
  224. package/src/types/Errors.ts +9 -0
  225. package/src/types/LinkController.ts +75 -0
  226. package/src/types/Onramp.ts +0 -14
  227. package/src/types/PaymentMethod.ts +2 -0
  228. package/src/types/PushProvisioning.ts +2 -0
  229. package/src/types/index.ts +2 -0
  230. package/stripe-react-native.podspec +1 -1
@@ -27,6 +27,7 @@ import com.facebook.react.modules.systeminfo.ReactNativeVersion
27
27
  import com.reactnativestripesdk.addresssheet.AddressLauncherManager
28
28
  import com.reactnativestripesdk.customersheet.CustomerSheetManager
29
29
  import com.reactnativestripesdk.pushprovisioning.PushProvisioningProxy
30
+ import com.reactnativestripesdk.pushprovisioning.TapAndPayProxy
30
31
  import com.reactnativestripesdk.utils.ConfirmPaymentErrorType
31
32
  import com.reactnativestripesdk.utils.CreateTokenErrorType
32
33
  import com.reactnativestripesdk.utils.DefaultActivityLifecycleCallbacks
@@ -126,6 +127,7 @@ class StripeSdkModule(
126
127
  private val checkoutStateObservers = mutableMapOf<String, Job>()
127
128
 
128
129
  private var customerSheetManager: CustomerSheetManager? = null
130
+ private var linkControllerManager: LinkControllerManager? = null
129
131
 
130
132
  internal var embeddedIntentCreationCallback = CompletableDeferred<ReadableMap>()
131
133
  internal var embeddedConfirmationTokenCreationCallback = CompletableDeferred<ReadableMap>()
@@ -179,6 +181,8 @@ class StripeSdkModule(
179
181
  checkoutStateObservers.values.forEach { it.cancel() }
180
182
  checkoutStateObservers.clear()
181
183
  checkoutInstances.clear()
184
+ linkControllerManager?.destroy()
185
+ linkControllerManager = null
182
186
  }
183
187
 
184
188
  private fun registerStripeUIManager(uiManager: StripeUIManager) {
@@ -955,6 +959,12 @@ class StripeSdkModule(
955
959
  return
956
960
  }
957
961
 
962
+ val cardBrand =
963
+ getValOr(params, "cardBrand", null) ?: run {
964
+ promise.resolve(createError("Failed", "You must provide cardBrand"))
965
+ return
966
+ }
967
+
958
968
  if (params.getBooleanOr("supportsTapToPay", true) &&
959
969
  !PushProvisioningProxy.isNFCEnabled(
960
970
  reactApplicationContext,
@@ -964,14 +974,14 @@ class StripeSdkModule(
964
974
  return
965
975
  }
966
976
 
967
- getCurrentActivityOrResolveWithError(promise)?.let {
968
- PushProvisioningProxy.isCardInWallet(it, last4) { isCardInWallet, token, error ->
977
+ getCurrentActivityOrResolveWithError(promise)?.let { activity ->
978
+ TapAndPayProxy.checkEligibility(activity, last4, cardBrand) { canAdd, token, error ->
969
979
  val result =
970
980
  error?.let {
971
- createCanAddCardResult(false, "MISSING_CONFIGURATION", null)
981
+ createCanAddCardResult(false, "MISSING_CONFIGURATION")
972
982
  } ?: run {
973
- val status = if (isCardInWallet) "CARD_ALREADY_EXISTS" else null
974
- createCanAddCardResult(!isCardInWallet, status, token)
983
+ val status = if (!canAdd) "CARD_ALREADY_EXISTS" else null
984
+ createCanAddCardResult(canAdd, status, token)
975
985
  }
976
986
  promise.resolve(result)
977
987
  }
@@ -1443,15 +1453,6 @@ class StripeSdkModule(
1443
1453
  // TODO:
1444
1454
  }
1445
1455
 
1446
- @ReactMethod
1447
- override fun updateEmbeddedPaymentElementWithCheckout(
1448
- sessionKey: String,
1449
- promise: Promise,
1450
- ) {
1451
- // No-op on Android. JS dispatches Checkout updates through the view command instead.
1452
- promise.resolve(null)
1453
- }
1454
-
1455
1456
  @ReactMethod
1456
1457
  override fun clearEmbeddedPaymentOption(
1457
1458
  viewTag: Double,
@@ -1800,30 +1801,6 @@ class StripeSdkModule(
1800
1801
  }
1801
1802
  }
1802
1803
 
1803
- override fun checkoutUpdateBillingAddress(
1804
- sessionKey: String,
1805
- address: ReadableMap,
1806
- name: String?,
1807
- phone: String?,
1808
- promise: Promise,
1809
- ) {
1810
- val addressUpdate = buildCheckoutAddressUpdate(name, phone, address) ?: run {
1811
- promise.reject(ErrorType.Failed.toString(), "A billing address country is required.")
1812
- return
1813
- }
1814
-
1815
- performCheckoutMutation(
1816
- sessionKey = sessionKey,
1817
- promise = promise,
1818
- ) { checkout ->
1819
- checkout.updateBillingAddress(
1820
- name = addressUpdate.name,
1821
- phoneNumber = addressUpdate.phone,
1822
- address = addressUpdate.toCheckoutAddress(),
1823
- )
1824
- }
1825
- }
1826
-
1827
1804
  override fun checkoutApplyPromotionCode(
1828
1805
  sessionKey: String,
1829
1806
  code: String,
@@ -2026,6 +2003,34 @@ class StripeSdkModule(
2026
2003
  }
2027
2004
  }
2028
2005
 
2006
+ // LinkController - Private Preview
2007
+
2008
+ @ReactMethod
2009
+ override fun initLinkController(
2010
+ params: ReadableMap,
2011
+ promise: Promise,
2012
+ ) {
2013
+ linkControllerManager?.destroy()
2014
+ linkControllerManager = LinkControllerManager(
2015
+ context = reactApplicationContext,
2016
+ publishableKey = publishableKey,
2017
+ stripeAccountId = stripeAccountId,
2018
+ )
2019
+ linkControllerManager?.configure(params, promise)
2020
+ }
2021
+
2022
+ @ReactMethod
2023
+ override fun presentLinkController(promise: Promise) {
2024
+ val manager = linkControllerManager
2025
+ if (manager == null) {
2026
+ promise.resolve(createError(ErrorType.Failed.toString(), LINK_CONTROLLER_NOT_INITIALIZED_ERROR))
2027
+ return
2028
+ }
2029
+ UiThreadUtil.runOnUiThread {
2030
+ manager.present(promise)
2031
+ }
2032
+ }
2033
+
2029
2034
  /**
2030
2035
  * React native apps do not properly handle activity re-creation so make
2031
2036
  * sure to dismiss any stripe ui when that happens to make sure apps stay
@@ -83,6 +83,14 @@ class AddToWalletButtonManager :
83
83
  // noop, iOS only.
84
84
  }
85
85
 
86
+ @ReactProp(name = "isBounceProvisioned")
87
+ override fun setIsBounceProvisioned(
88
+ view: AddToWalletButtonView,
89
+ value: Boolean,
90
+ ) {
91
+ view.setIsBounceProvisioned(value)
92
+ }
93
+
86
94
  @ReactProp(name = "testEnv")
87
95
  override fun setTestEnv(
88
96
  view: AddToWalletButtonView,
@@ -33,6 +33,7 @@ class AddToWalletButtonView(
33
33
  private var ephemeralKey: String? = null
34
34
  private var sourceMap: ReadableMap? = null
35
35
  private var token: ReadableMap? = null
36
+ private var isBounceProvisioned: Boolean = false
36
37
 
37
38
  private var loadedSource: String? = null
38
39
  private var currentDataSource: DataSource<CloseableReference<CloseableImage>>? = null
@@ -54,6 +55,7 @@ class AddToWalletButtonView(
54
55
  cardDescription,
55
56
  ephemeralKey,
56
57
  token,
58
+ isBounceProvisioned,
57
59
  )
58
60
  }
59
61
  ?: run {
@@ -189,6 +191,10 @@ class AddToWalletButtonView(
189
191
  token = map
190
192
  }
191
193
 
194
+ fun setIsBounceProvisioned(value: Boolean) {
195
+ isBounceProvisioned = value
196
+ }
197
+
192
198
  fun dispatchEvent(error: WritableMap?) {
193
199
  UIManagerHelper
194
200
  .getEventDispatcherForReactTag(context, id)
@@ -42,6 +42,7 @@ object PushProvisioningProxy {
42
42
  cardDescription: String,
43
43
  ephemeralKey: String,
44
44
  token: ReadableMap?,
45
+ isBounceProvisioned: Boolean,
45
46
  ) {
46
47
  try {
47
48
  Class.forName("com.stripe.android.pushProvisioning.PushProvisioningActivityStarter")
@@ -50,7 +51,7 @@ object PushProvisioningProxy {
50
51
  createActivityEventListener(context, view)
51
52
  context.currentActivity?.let {
52
53
  DefaultPushProvisioningProxy()
53
- .beginPushProvisioning(it, description, EphemeralKeyProvider(ephemeralKey))
54
+ .beginPushProvisioning(it, description, EphemeralKeyProvider(ephemeralKey), isBounceProvisioned)
54
55
  }
55
56
  ?: run {
56
57
  view.dispatchEvent(
@@ -136,10 +137,10 @@ class DefaultPushProvisioningProxy {
136
137
  activity: Activity,
137
138
  description: String,
138
139
  provider: EphemeralKeyProvider,
140
+ isBounceProvisioned: Boolean,
139
141
  ) {
140
- PushProvisioningActivityStarter(
141
- activity,
142
- PushProvisioningActivityStarter.Args(description, provider, false),
143
- ).startForResult()
142
+ val args = PushProvisioningActivityStarter.Args(description, provider, true)
143
+ args.setIsBounceProvisioned(isBounceProvisioned)
144
+ PushProvisioningActivityStarter(activity, args).startForResult()
144
145
  }
145
146
  }
@@ -12,10 +12,14 @@ import com.reactnativestripesdk.utils.getIntOr
12
12
  typealias TokenCheckHandler =
13
13
  (isCardInWallet: Boolean, token: WritableMap?, error: WritableMap?) -> Unit
14
14
 
15
+ typealias EligibilityCheckHandler = (canAdd: Boolean, token: WritableMap?, error: WritableMap?) -> Unit
16
+
15
17
  object TapAndPayProxy {
16
18
  private const val TAG = "StripeTapAndPay"
17
19
  private var tapAndPayClient: Any? = null
18
20
  const val REQUEST_CODE_TOKENIZE = 90909
21
+ private const val FALLBACK_MASTERCARD_CONSTANT = 3
22
+ private const val FALLBACK_VISA_CONSTANT = 4
19
23
 
20
24
  private fun getTapandPayTokens(activity: Activity): Task<List<Any>>? =
21
25
  try {
@@ -75,6 +79,93 @@ object TapAndPayProxy {
75
79
  }
76
80
  }
77
81
 
82
+ fun checkEligibility(
83
+ activity: Activity,
84
+ cardLastFour: String,
85
+ cardBrand: String,
86
+ callback: EligibilityCheckHandler,
87
+ ) {
88
+ try {
89
+ val tapAndPayClass = Class.forName("com.google.android.gms.tapandpay.TapAndPay")
90
+ val getClientMethod = tapAndPayClass.getMethod("getClient", Activity::class.java)
91
+ val client = getClientMethod.invoke(null, activity)
92
+
93
+ val (network, tokenServiceProvider) = mapBrandToConstants(cardBrand)
94
+ val builderClass =
95
+ Class.forName(
96
+ "com.google.android.gms.tapandpay.issuer.HasEligibleTokenizationTargetRequest\$Builder"
97
+ )
98
+ val builder = builderClass.getDeclaredConstructor().newInstance()
99
+ builderClass.getMethod("setIdentifier", String::class.java).invoke(builder, cardLastFour)
100
+ builderClass.getMethod("setNetwork", Int::class.java).invoke(builder, network)
101
+ builderClass.getMethod("setTokenServiceProvider", Int::class.java).invoke(builder, tokenServiceProvider)
102
+ builderClass.getMethod("setIssuerName", String::class.java).invoke(builder, "Stripe")
103
+ val request = builderClass.getMethod("build").invoke(builder)
104
+
105
+ val requestClass = Class.forName("com.google.android.gms.tapandpay.issuer.HasEligibleTokenizationTargetRequest")
106
+ val tapAndPayClientClass = Class.forName("com.google.android.gms.tapandpay.TapAndPayClient")
107
+ val method = tapAndPayClientClass.getMethod("hasEligibleTokenizationTarget", requestClass)
108
+
109
+ @Suppress("UNCHECKED_CAST")
110
+ val task = method.invoke(client, request) as Task<Boolean>
111
+ task.addOnCompleteListener { completedTask ->
112
+ if (completedTask.isSuccessful) {
113
+ val hasTarget = completedTask.result
114
+ findExistingToken(activity, cardLastFour) { _, token, _ ->
115
+ callback(hasTarget, token, null)
116
+ }
117
+ } else {
118
+ Log.w(
119
+ TAG,
120
+ "hasEligibleTokenizationTarget failed, falling back to listTokens: " + completedTask.exception,
121
+ )
122
+ fallbackToListTokens(activity, cardLastFour, callback)
123
+ }
124
+ }
125
+ } catch (e: Exception) {
126
+ Log.e(TAG, "There was a problem calling hasEligibleTokenizationTarget with Google TapAndPay: " + e.message)
127
+ fallbackToListTokens(activity, cardLastFour, callback)
128
+ }
129
+ }
130
+
131
+ private fun fallbackToListTokens(
132
+ activity: Activity,
133
+ cardLastFour: String,
134
+ callback: EligibilityCheckHandler,
135
+ ) {
136
+ findExistingToken(activity, cardLastFour) { isInWallet, token, error ->
137
+ if (error != null) {
138
+ callback(false, null, error)
139
+ } else {
140
+ callback(!isInWallet, token, null)
141
+ }
142
+ }
143
+ }
144
+
145
+ private fun mapBrandToConstants(cardBrand: String): Pair<Int, Int> {
146
+ try {
147
+ val tapAndPayClass = Class.forName("com.google.android.gms.tapandpay.TapAndPay")
148
+ return if (cardBrand.lowercase() == "mastercard") {
149
+ Pair(
150
+ tapAndPayClass.getField("CARD_NETWORK_MASTERCARD").getInt(null),
151
+ tapAndPayClass.getField("TOKEN_PROVIDER_MASTERCARD").getInt(null),
152
+ )
153
+ } else {
154
+ Pair(
155
+ tapAndPayClass.getField("CARD_NETWORK_VISA").getInt(null),
156
+ tapAndPayClass.getField("TOKEN_PROVIDER_VISA").getInt(null),
157
+ )
158
+ }
159
+ } catch (e: Exception) {
160
+ Log.e(TAG, "There was a problem getting TapAndPay constants: " + e.message)
161
+ return if (cardBrand.lowercase() == "mastercard") {
162
+ Pair(FALLBACK_MASTERCARD_CONSTANT, FALLBACK_MASTERCARD_CONSTANT)
163
+ } else {
164
+ Pair(FALLBACK_VISA_CONSTANT, FALLBACK_VISA_CONSTANT)
165
+ }
166
+ }
167
+ }
168
+
78
169
  fun tokenize(
79
170
  activity: Activity,
80
171
  tokenReferenceId: String,
@@ -33,6 +33,9 @@ public class AddToWalletButtonManagerDelegate<T extends View, U extends BaseView
33
33
  case "testEnv":
34
34
  mViewManager.setTestEnv(view, value == null ? false : (boolean) value);
35
35
  break;
36
+ case "isBounceProvisioned":
37
+ mViewManager.setIsBounceProvisioned(view, value == null ? false : (boolean) value);
38
+ break;
36
39
  case "cardDetails":
37
40
  mViewManager.setCardDetails(view, new DynamicFromObject(value));
38
41
  break;
@@ -18,6 +18,7 @@ public interface AddToWalletButtonManagerInterface<T extends View> {
18
18
  void setIOSButtonStyle(T view, @Nullable String value);
19
19
  void setAndroidAssetSource(T view, @Nullable ReadableMap value);
20
20
  void setTestEnv(T view, boolean value);
21
+ void setIsBounceProvisioned(T view, boolean value);
21
22
  void setCardDetails(T view, Dynamic value);
22
23
  void setToken(T view, Dynamic value);
23
24
  void setEphemeralKey(T view, Dynamic value);
@@ -50,9 +50,6 @@ public class EmbeddedPaymentElementViewManagerDelegate<T extends View, U extends
50
50
  case "update":
51
51
  mViewManager.update(view, args != null ? args.getString(0) : null);
52
52
  break;
53
- case "updateWithCheckout":
54
- mViewManager.updateWithCheckout(view, args != null ? args.getString(0) : null);
55
- break;
56
53
  }
57
54
  }
58
55
  }
@@ -20,5 +20,4 @@ public interface EmbeddedPaymentElementViewManagerInterface<T extends View> {
20
20
  void confirm(T view);
21
21
  void clearPaymentOption(T view);
22
22
  void update(T view, @Nullable String intentConfigurationJson);
23
- void updateWithCheckout(T view, @Nullable String sessionKey);
24
23
  }
@@ -11,6 +11,7 @@ package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
13
  import androidx.annotation.Nullable;
14
+ import com.facebook.react.bridge.DynamicFromObject;
14
15
  import com.facebook.react.uimanager.BaseViewManager;
15
16
  import com.facebook.react.uimanager.BaseViewManagerDelegate;
16
17
  import com.facebook.react.uimanager.LayoutShadowNode;
@@ -28,6 +29,9 @@ public class StripeCurrencySelectorElementManagerDelegate<T extends View, U exte
28
29
  case "disabled":
29
30
  mViewManager.setDisabled(view, value == null ? false : (boolean) value);
30
31
  break;
32
+ case "appearance":
33
+ mViewManager.setAppearance(view, new DynamicFromObject(value));
34
+ break;
31
35
  default:
32
36
  super.setProperty(view, propName, value);
33
37
  }
@@ -11,8 +11,10 @@ package com.facebook.react.viewmanagers;
11
11
 
12
12
  import android.view.View;
13
13
  import androidx.annotation.Nullable;
14
+ import com.facebook.react.bridge.Dynamic;
14
15
 
15
16
  public interface StripeCurrencySelectorElementManagerInterface<T extends View> {
16
17
  void setSessionKey(T view, @Nullable String value);
17
18
  void setDisabled(T view, boolean value);
19
+ void setAppearance(T view, Dynamic value);
18
20
  }
@@ -265,10 +265,6 @@ public abstract class NativeStripeSdkModuleSpec extends ReactContextBaseJavaModu
265
265
  @DoNotStrip
266
266
  public abstract void updateEmbeddedPaymentElement(ReadableMap intentConfig, Promise promise);
267
267
 
268
- @ReactMethod
269
- @DoNotStrip
270
- public abstract void updateEmbeddedPaymentElementWithCheckout(String sessionKey, Promise promise);
271
-
272
268
  @ReactMethod
273
269
  @DoNotStrip
274
270
  public abstract void clearEmbeddedPaymentOption(double viewTag, Promise promise);
@@ -309,10 +305,6 @@ public abstract class NativeStripeSdkModuleSpec extends ReactContextBaseJavaModu
309
305
  @DoNotStrip
310
306
  public abstract void checkoutUpdateShippingAddress(String sessionKey, ReadableMap address, @Nullable String name, @Nullable String phone, Promise promise);
311
307
 
312
- @ReactMethod
313
- @DoNotStrip
314
- public abstract void checkoutUpdateBillingAddress(String sessionKey, ReadableMap address, @Nullable String name, @Nullable String phone, Promise promise);
315
-
316
308
  @ReactMethod
317
309
  @DoNotStrip
318
310
  public abstract void checkoutApplyPromotionCode(String sessionKey, String code, Promise promise);
@@ -337,6 +329,14 @@ public abstract class NativeStripeSdkModuleSpec extends ReactContextBaseJavaModu
337
329
  @DoNotStrip
338
330
  public abstract void checkoutRunServerUpdateComplete(String sessionKey, @Nullable String error, Promise promise);
339
331
 
332
+ @ReactMethod
333
+ @DoNotStrip
334
+ public abstract void initLinkController(ReadableMap params, Promise promise);
335
+
336
+ @ReactMethod
337
+ @DoNotStrip
338
+ public abstract void presentLinkController(Promise promise);
339
+
340
340
  @ReactMethod
341
341
  @DoNotStrip
342
342
  public abstract void addListener(String eventType);
@@ -3,14 +3,12 @@
3
3
  package com.reactnativestripesdk
4
4
 
5
5
  import com.facebook.react.bridge.Arguments
6
- import com.facebook.react.bridge.WritableArray
7
6
  import com.facebook.react.bridge.WritableMap
8
7
  import com.reactnativestripesdk.utils.ErrorType
9
8
  import com.stripe.android.core.exception.StripeException
10
9
  import com.stripe.android.crypto.onramp.ExperimentalCryptoOnramp
11
10
  import com.stripe.android.crypto.onramp.exception.AppAttestationException
12
11
  import com.stripe.android.crypto.onramp.exception.CryptoOnrampApiException
13
- import com.stripe.android.crypto.onramp.exception.SDKVersion
14
12
  import com.stripe.android.crypto.onramp.exception.StripeCryptoOnrampError
15
13
 
16
14
  internal fun createOnrampFailedError(error: Throwable): WritableMap =
@@ -32,29 +30,26 @@ private fun createOnrampError(
32
30
 
33
31
  val stripeError = apiException.stripeError
34
32
  val onrampErrorType = apiException.toOnrampErrorType()
33
+ val apiErrorContext = apiException.apiErrorContext
35
34
 
36
35
  return createOnrampErrorMap(
37
36
  code = code,
38
37
  message = apiException.userMessage,
39
38
  localizedMessage = apiException.localizedMessage,
40
39
  declineCode = stripeError?.declineCode,
41
- type = apiException.context.apiErrorType ?: stripeError?.type,
40
+ type = apiErrorContext.apiErrorType ?: stripeError?.type,
42
41
  stripeErrorCode = apiException.code,
43
42
  ) {
44
43
  putString("onrampErrorType", onrampErrorType)
45
44
  putString("developerMessage", apiException.developerMessage)
46
45
  putString("userMessage", apiException.userMessage)
47
- putString("reason", apiException.context.reason)
48
- putString("operation", apiException.context.operation)
49
- putString("appPackageName", apiException.context.appPackageName)
50
- putString("mode", apiException.context.mode)
51
- putArray("sdkVersions", mapFromSdkVersions(apiException.sdkVersions))
52
- putString("requestId", apiException.context.requestId)
53
- putString("apiErrorCode", apiException.context.apiErrorCode)
54
- putString("apiErrorType", apiException.context.apiErrorType)
55
- putString("apiErrorMessage", apiException.context.apiErrorMessage)
56
- putString("apiUserMessage", apiException.context.apiUserMessage)
57
- putString("docUrl", apiException.context.docUrl)
46
+ putString("reason", apiErrorContext.reason)
47
+ putString("requestId", apiErrorContext.requestId)
48
+ putString("apiErrorCode", apiErrorContext.apiErrorCode)
49
+ putString("apiErrorType", apiErrorContext.apiErrorType)
50
+ putString("apiErrorMessage", apiErrorContext.apiErrorMessage)
51
+ putString("apiUserMessage", apiErrorContext.apiUserMessage)
52
+ putString("docUrl", apiErrorContext.docUrl)
58
53
  }
59
54
  }
60
55
 
@@ -129,17 +124,3 @@ private fun createOnrampErrorMap(
129
124
  map.putMap("error", details)
130
125
  return map
131
126
  }
132
-
133
- private fun mapFromSdkVersions(
134
- sdkVersions: List<SDKVersion>,
135
- ): WritableArray =
136
- Arguments.createArray().apply {
137
- sdkVersions.forEach { sdkVersion ->
138
- pushMap(
139
- Arguments.createMap().apply {
140
- putString("name", sdkVersion.name)
141
- putString("version", sdkVersion.version)
142
- },
143
- )
144
- }
145
- }
@@ -1,4 +1,4 @@
1
- @file:OptIn(ExperimentalCryptoOnramp::class)
1
+ @file:OptIn(ExperimentalCryptoOnramp::class, LinkControllerPreview::class)
2
2
 
3
3
  package com.reactnativestripesdk
4
4
 
@@ -39,7 +39,7 @@ import com.stripe.android.crypto.onramp.model.OnrampCheckoutResult
39
39
  import com.stripe.android.crypto.onramp.model.OnrampCollectPaymentMethodResult
40
40
  import com.stripe.android.crypto.onramp.model.OnrampConfigurationResult
41
41
  import com.stripe.android.crypto.onramp.model.OnrampCreateCryptoPaymentTokenResult
42
- import com.stripe.android.crypto.onramp.model.OnrampCrsCarfDeclarationResult
42
+ import com.stripe.android.crypto.onramp.model.OnrampUserAttestationResult
43
43
  import com.stripe.android.crypto.onramp.model.OnrampHasLinkAccountResult
44
44
  import com.stripe.android.crypto.onramp.model.OnrampLogOutResult
45
45
  import com.stripe.android.crypto.onramp.model.OnrampRegisterLinkUserResult
@@ -52,6 +52,7 @@ import com.stripe.android.crypto.onramp.model.OnrampVerifyIdentityResult
52
52
  import com.stripe.android.crypto.onramp.model.OnrampVerifyKycInfoResult
53
53
  import com.stripe.android.crypto.onramp.model.PaymentMethodSelection
54
54
  import com.stripe.android.link.LinkController.PaymentMethodPreview
55
+ import com.stripe.android.link.LinkControllerPreview
55
56
  import com.stripe.android.link.PaymentMethodPreviewDetails
56
57
  import com.stripe.android.model.CardBrand
57
58
  import com.stripe.android.model.DateOfBirth
@@ -65,7 +66,7 @@ import kotlinx.coroutines.withContext
65
66
  import kotlinx.coroutines.withTimeout
66
67
 
67
68
  @SuppressLint("RestrictedApi")
68
- @OptIn(ExperimentalCryptoOnramp::class)
69
+ @OptIn(ExperimentalCryptoOnramp::class, LinkControllerPreview::class)
69
70
  @ReactModule(name = NativeOnrampSdkModuleSpec.NAME)
70
71
  class OnrampSdkModule(
71
72
  reactContext: ReactApplicationContext,
@@ -152,7 +153,7 @@ class OnrampSdkModule(
152
153
  handleOnrampCheckoutResult(result, checkoutPromise!!)
153
154
  }.verifyKycCallback { result ->
154
155
  handleOnrampKycVerificationResult(result, verifyKycPromise!!)
155
- }.crsCarfDeclarationCallback { result ->
156
+ }.userAttestationCallback { result ->
156
157
  userAttestationPromise?.let {
157
158
  handleUserAttestationResult(result, it)
158
159
  }
@@ -426,7 +427,7 @@ class OnrampSdkModule(
426
427
  }
427
428
 
428
429
  userAttestationPromise = promise
429
- presenter.presentCrsCarfDeclaration()
430
+ presenter.presentUserAttestation()
430
431
  }
431
432
 
432
433
  @ReactMethod
@@ -783,19 +784,19 @@ class OnrampSdkModule(
783
784
  }
784
785
 
785
786
  private fun handleUserAttestationResult(
786
- result: OnrampCrsCarfDeclarationResult,
787
+ result: OnrampUserAttestationResult,
787
788
  promise: Promise,
788
789
  ) {
789
790
  when (result) {
790
- is OnrampCrsCarfDeclarationResult.Confirmed -> {
791
+ is OnrampUserAttestationResult.Confirmed -> {
791
792
  promise.resolve(
792
793
  WritableNativeMap().apply { putString("status", "Confirmed") },
793
794
  )
794
795
  }
795
- is OnrampCrsCarfDeclarationResult.Cancelled -> {
796
+ is OnrampUserAttestationResult.Cancelled -> {
796
797
  promise.resolve(createCanceledError("User attestation was canceled"))
797
798
  }
798
- is OnrampCrsCarfDeclarationResult.Failed -> {
799
+ is OnrampUserAttestationResult.Failed -> {
799
800
  promise.resolve(createOnrampFailedError(result.error))
800
801
  }
801
802
  }