@stripe/stripe-react-native 0.44.0 → 0.46.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 (334) hide show
  1. package/.clang-format +90 -0
  2. package/.editorconfig +3 -0
  3. package/CHANGELOG.md +13 -1
  4. package/README.md +0 -3
  5. package/android/.gradle/8.11.1/checksums/checksums.lock +0 -0
  6. package/android/.gradle/8.11.1/checksums/md5-checksums.bin +0 -0
  7. package/android/.gradle/8.11.1/checksums/sha1-checksums.bin +0 -0
  8. package/android/.gradle/8.11.1/executionHistory/executionHistory.bin +0 -0
  9. package/android/.gradle/8.11.1/executionHistory/executionHistory.lock +0 -0
  10. package/android/.gradle/8.11.1/fileHashes/fileHashes.bin +0 -0
  11. package/android/.gradle/8.11.1/fileHashes/fileHashes.lock +0 -0
  12. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  13. package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
  14. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  15. package/android/.gradle/config.properties +2 -0
  16. package/android/.gradle/file-system.probe +0 -0
  17. package/android/.idea/caches/deviceStreaming.xml +619 -0
  18. package/android/.idea/compiler.xml +6 -0
  19. package/android/.idea/gradle.xml +19 -0
  20. package/android/.idea/migrations.xml +10 -0
  21. package/android/.idea/misc.xml +10 -0
  22. package/android/.idea/runConfigurations.xml +17 -0
  23. package/android/.idea/vcs.xml +6 -0
  24. package/android/build.gradle +90 -18
  25. package/android/gradle.properties +1 -1
  26. package/android/local.properties +8 -0
  27. package/android/src/main/java/com/reactnativestripesdk/AuBECSDebitFormViewManager.kt +15 -6
  28. package/android/src/main/java/com/reactnativestripesdk/CardChangeEvent.kt +56 -0
  29. package/android/src/main/java/com/reactnativestripesdk/CardFieldView.kt +4 -4
  30. package/android/src/main/java/com/reactnativestripesdk/CardFieldViewManager.kt +55 -45
  31. package/android/src/main/java/com/reactnativestripesdk/{CardFocusEvent.kt → CardFocusChangeEvent.kt} +2 -2
  32. package/android/src/main/java/com/reactnativestripesdk/CardFormCompleteEvent.kt +17 -16
  33. package/android/src/main/java/com/reactnativestripesdk/CardFormView.kt +5 -5
  34. package/android/src/main/java/com/reactnativestripesdk/CardFormViewManager.kt +39 -33
  35. package/android/src/main/java/com/reactnativestripesdk/CollectBankAccountLauncherFragment.kt +35 -36
  36. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementView.kt +224 -0
  37. package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +238 -0
  38. package/android/src/main/java/com/reactnativestripesdk/FinancialConnectionsSheetFragment.kt +11 -26
  39. package/android/src/main/java/com/reactnativestripesdk/GooglePayButtonManager.kt +14 -6
  40. package/android/src/main/java/com/reactnativestripesdk/GooglePayLauncherFragment.kt +3 -17
  41. package/android/src/main/java/com/reactnativestripesdk/GooglePayPaymentMethodLauncherFragment.kt +20 -6
  42. package/android/src/main/java/com/reactnativestripesdk/PaymentLauncherFragment.kt +63 -44
  43. package/android/src/main/java/com/reactnativestripesdk/PaymentMethodCreateParamsFactory.kt +3 -1
  44. package/android/src/main/java/com/reactnativestripesdk/PaymentOptionDisplayDataMapper.kt +17 -0
  45. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +266 -0
  46. package/android/src/main/java/com/reactnativestripesdk/PaymentSheetFragment.kt +25 -33
  47. package/android/src/main/java/com/reactnativestripesdk/StripeAbstractComposeView.kt +113 -0
  48. package/android/src/main/java/com/reactnativestripesdk/StripeContainerManager.kt +11 -3
  49. package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +180 -65
  50. package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +34 -4
  51. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressLauncherFragment.kt +3 -17
  52. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetView.kt +33 -27
  53. package/android/src/main/java/com/reactnativestripesdk/addresssheet/AddressSheetViewManager.kt +49 -24
  54. package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetFragment.kt +19 -24
  55. package/android/src/main/java/com/reactnativestripesdk/customersheet/ReactNativeCustomerAdapter.kt +11 -29
  56. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonManager.kt +36 -12
  57. package/android/src/main/java/com/reactnativestripesdk/pushprovisioning/AddToWalletButtonView.kt +5 -3
  58. package/android/src/main/java/com/reactnativestripesdk/utils/Extensions.kt +4 -0
  59. package/android/src/main/java/com/reactnativestripesdk/utils/KeepJsAwakeTask.kt +2 -2
  60. package/android/src/main/java/com/reactnativestripesdk/utils/Mappers.kt +21 -0
  61. package/android/src/main/java/com/reactnativestripesdk/utils/StripeFragment.kt +52 -0
  62. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddToWalletButtonManagerDelegate.java +49 -0
  63. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddToWalletButtonManagerInterface.java +25 -0
  64. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddressSheetViewManagerDelegate.java +64 -0
  65. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AddressSheetViewManagerInterface.java +30 -0
  66. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerDelegate.java +41 -0
  67. package/android/src/oldarch/java/com/facebook/react/viewmanagers/ApplePayButtonManagerInterface.java +20 -0
  68. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AuBECSDebitFormManagerDelegate.java +36 -0
  69. package/android/src/oldarch/java/com/facebook/react/viewmanagers/AuBECSDebitFormManagerInterface.java +20 -0
  70. package/android/src/oldarch/java/com/facebook/react/viewmanagers/CardFieldManagerDelegate.java +73 -0
  71. package/android/src/oldarch/java/com/facebook/react/viewmanagers/CardFieldManagerInterface.java +31 -0
  72. package/android/src/oldarch/java/com/facebook/react/viewmanagers/CardFormManagerDelegate.java +67 -0
  73. package/android/src/oldarch/java/com/facebook/react/viewmanagers/CardFormManagerInterface.java +29 -0
  74. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerDelegate.java +49 -0
  75. package/android/src/oldarch/java/com/facebook/react/viewmanagers/EmbeddedPaymentElementViewManagerInterface.java +21 -0
  76. package/android/src/oldarch/java/com/facebook/react/viewmanagers/GooglePayButtonManagerDelegate.java +38 -0
  77. package/android/src/oldarch/java/com/facebook/react/viewmanagers/GooglePayButtonManagerInterface.java +19 -0
  78. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeContainerManagerDelegate.java +32 -0
  79. package/android/src/oldarch/java/com/facebook/react/viewmanagers/StripeContainerManagerInterface.java +17 -0
  80. package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +310 -0
  81. package/ios/AddressSheet/AddressSheetUtils.swift +21 -19
  82. package/ios/AddressSheet/AddressSheetView.swift +23 -17
  83. package/ios/ApplePayButtonManager.m +0 -1
  84. package/ios/ApplePayButtonManager.swift +1 -3
  85. package/ios/ApplePayButtonView.swift +25 -20
  86. package/ios/ApplePayViewController.swift +22 -22
  87. package/ios/AuBECSDebitFormView.swift +14 -8
  88. package/ios/CardFieldManager.swift +1 -4
  89. package/ios/CardFieldView.swift +28 -25
  90. package/ios/CardFormManager.swift +1 -4
  91. package/ios/CardFormView.swift +25 -16
  92. package/ios/CustomerSheet/CustomerSheetUtils.swift +12 -16
  93. package/ios/CustomerSheet/ReactNativeCustomerAdapter.swift +8 -8
  94. package/ios/EmbeddedPaymentElementManager.m +6 -0
  95. package/ios/EmbeddedPaymentElementView.swift +49 -0
  96. package/ios/NewArch/AddToWalletButtonComponentView.h +10 -0
  97. package/ios/NewArch/AddToWalletButtonComponentView.mm +93 -0
  98. package/ios/NewArch/AddressSheetViewComponentView.h +10 -0
  99. package/ios/NewArch/AddressSheetViewComponentView.mm +109 -0
  100. package/ios/NewArch/ApplePayButtonComponentView.h +10 -0
  101. package/ios/NewArch/ApplePayButtonComponentView.mm +124 -0
  102. package/ios/NewArch/AuBECSDebitFormComponentView.h +10 -0
  103. package/ios/NewArch/AuBECSDebitFormComponentView.mm +95 -0
  104. package/ios/NewArch/CardFieldComponentView.h +10 -0
  105. package/ios/NewArch/CardFieldComponentView.mm +125 -0
  106. package/ios/NewArch/CardFormComponentView.h +10 -0
  107. package/ios/NewArch/CardFormComponentView.mm +108 -0
  108. package/ios/NewArch/EmbeddedPaymentElementViewComponentView.h +10 -0
  109. package/ios/NewArch/EmbeddedPaymentElementViewComponentView.mm +81 -0
  110. package/ios/NewArch/StripeContainerComponentView.h +10 -0
  111. package/ios/NewArch/StripeContainerComponentView.mm +74 -0
  112. package/ios/NewArch/StripeNewArchConversions.h +20 -0
  113. package/ios/NewArch/StripeNewArchConversions.mm +47 -0
  114. package/ios/OldArch/StripeSdkEventEmitterCompat.h +27 -0
  115. package/ios/OldArch/StripeSdkEventEmitterCompat.m +105 -0
  116. package/ios/PaymentOptionDisplayData+ReactNative.swift +55 -0
  117. package/ios/PaymentSheetAppearance.swift +194 -1
  118. package/ios/PushProvisioning/AddToWalletButtonView.swift +19 -13
  119. package/ios/StripeContainerView.swift +5 -3
  120. package/ios/StripeSdk.h +21 -0
  121. package/ios/StripeSdk.mm +415 -0
  122. package/ios/StripeSdkEmitter.swift +19 -0
  123. package/ios/{StripeSdk+CustomerSheet.swift → StripeSdkImpl+CustomerSheet.swift} +24 -25
  124. package/ios/StripeSdkImpl+Embedded.swift +327 -0
  125. package/ios/{StripeSdk+PaymentSheet.swift → StripeSdkImpl+PaymentSheet.swift} +18 -29
  126. package/ios/{StripeSdk.swift → StripeSdkImpl.swift} +50 -72
  127. package/ios/StripeSwiftInterop.h +25 -0
  128. package/ios/stripe_react_native.h +2 -0
  129. package/lib/commonjs/components/AddToWalletButton.js +1 -1
  130. package/lib/commonjs/components/AddToWalletButton.js.map +1 -1
  131. package/lib/commonjs/components/AddressSheet.js +1 -1
  132. package/lib/commonjs/components/AddressSheet.js.map +1 -1
  133. package/lib/commonjs/components/AuBECSDebitForm.js +1 -1
  134. package/lib/commonjs/components/AuBECSDebitForm.js.map +1 -1
  135. package/lib/commonjs/components/CardField.js +1 -1
  136. package/lib/commonjs/components/CardField.js.map +1 -1
  137. package/lib/commonjs/components/CardForm.js +1 -1
  138. package/lib/commonjs/components/CardForm.js.map +1 -1
  139. package/lib/commonjs/components/CustomerSheet.js +1 -1
  140. package/lib/commonjs/components/CustomerSheet.js.map +1 -1
  141. package/lib/commonjs/components/PlatformPayButton.js +1 -1
  142. package/lib/commonjs/components/PlatformPayButton.js.map +1 -1
  143. package/lib/commonjs/components/StripeContainer.js +1 -1
  144. package/lib/commonjs/components/StripeContainer.js.map +1 -1
  145. package/lib/commonjs/components/StripeProvider.js +1 -1
  146. package/lib/commonjs/components/StripeProvider.js.map +1 -1
  147. package/lib/commonjs/events.js +2 -0
  148. package/lib/commonjs/events.js.map +1 -0
  149. package/lib/commonjs/functions.js +1 -1
  150. package/lib/commonjs/functions.js.map +1 -1
  151. package/lib/commonjs/index.js +1 -1
  152. package/lib/commonjs/index.js.map +1 -1
  153. package/lib/commonjs/specs/NativeAddToWalletButton.js +2 -0
  154. package/lib/commonjs/specs/NativeAddToWalletButton.js.map +1 -0
  155. package/lib/commonjs/specs/NativeAddressSheet.js +2 -0
  156. package/lib/commonjs/specs/NativeAddressSheet.js.map +1 -0
  157. package/lib/commonjs/specs/NativeApplePayButton.js +2 -0
  158. package/lib/commonjs/specs/NativeApplePayButton.js.map +1 -0
  159. package/lib/commonjs/specs/NativeAuBECSDebitForm.js +2 -0
  160. package/lib/commonjs/specs/NativeAuBECSDebitForm.js.map +1 -0
  161. package/lib/commonjs/specs/NativeCardField.js +2 -0
  162. package/lib/commonjs/specs/NativeCardField.js.map +1 -0
  163. package/lib/commonjs/specs/NativeCardForm.js +2 -0
  164. package/lib/commonjs/specs/NativeCardForm.js.map +1 -0
  165. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js +2 -0
  166. package/lib/commonjs/specs/NativeEmbeddedPaymentElement.js.map +1 -0
  167. package/lib/commonjs/specs/NativeGooglePayButton.js +2 -0
  168. package/lib/commonjs/specs/NativeGooglePayButton.js.map +1 -0
  169. package/lib/commonjs/specs/NativeStripeContainer.js +2 -0
  170. package/lib/commonjs/specs/NativeStripeContainer.js.map +1 -0
  171. package/lib/commonjs/specs/NativeStripeSdkModule.js +2 -0
  172. package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -0
  173. package/lib/commonjs/specs/utils.js +2 -0
  174. package/lib/commonjs/specs/utils.js.map +1 -0
  175. package/lib/commonjs/types/EmbeddedPaymentElement.js +2 -0
  176. package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -0
  177. package/lib/commonjs/types/PaymentSheet.js +1 -1
  178. package/lib/commonjs/types/PaymentSheet.js.map +1 -1
  179. package/lib/module/components/AddToWalletButton.js +1 -1
  180. package/lib/module/components/AddToWalletButton.js.map +1 -1
  181. package/lib/module/components/AddressSheet.js +1 -1
  182. package/lib/module/components/AddressSheet.js.map +1 -1
  183. package/lib/module/components/AuBECSDebitForm.js +1 -1
  184. package/lib/module/components/AuBECSDebitForm.js.map +1 -1
  185. package/lib/module/components/CardField.js +1 -1
  186. package/lib/module/components/CardField.js.map +1 -1
  187. package/lib/module/components/CardForm.js +1 -1
  188. package/lib/module/components/CardForm.js.map +1 -1
  189. package/lib/module/components/CustomerSheet.js +1 -1
  190. package/lib/module/components/CustomerSheet.js.map +1 -1
  191. package/lib/module/components/PlatformPayButton.js +1 -1
  192. package/lib/module/components/PlatformPayButton.js.map +1 -1
  193. package/lib/module/components/StripeContainer.js +1 -1
  194. package/lib/module/components/StripeContainer.js.map +1 -1
  195. package/lib/module/components/StripeProvider.js +1 -1
  196. package/lib/module/components/StripeProvider.js.map +1 -1
  197. package/lib/module/events.js +2 -0
  198. package/lib/module/events.js.map +1 -0
  199. package/lib/module/functions.js +1 -1
  200. package/lib/module/functions.js.map +1 -1
  201. package/lib/module/index.js +1 -1
  202. package/lib/module/index.js.map +1 -1
  203. package/lib/module/specs/NativeAddToWalletButton.js +2 -0
  204. package/lib/module/specs/NativeAddToWalletButton.js.map +1 -0
  205. package/lib/module/specs/NativeAddressSheet.js +2 -0
  206. package/lib/module/specs/NativeAddressSheet.js.map +1 -0
  207. package/lib/module/specs/NativeApplePayButton.js +2 -0
  208. package/lib/module/specs/NativeApplePayButton.js.map +1 -0
  209. package/lib/module/specs/NativeAuBECSDebitForm.js +2 -0
  210. package/lib/module/specs/NativeAuBECSDebitForm.js.map +1 -0
  211. package/lib/module/specs/NativeCardField.js +2 -0
  212. package/lib/module/specs/NativeCardField.js.map +1 -0
  213. package/lib/module/specs/NativeCardForm.js +2 -0
  214. package/lib/module/specs/NativeCardForm.js.map +1 -0
  215. package/lib/module/specs/NativeEmbeddedPaymentElement.js +2 -0
  216. package/lib/module/specs/NativeEmbeddedPaymentElement.js.map +1 -0
  217. package/lib/module/specs/NativeGooglePayButton.js +2 -0
  218. package/lib/module/specs/NativeGooglePayButton.js.map +1 -0
  219. package/lib/module/specs/NativeStripeContainer.js +2 -0
  220. package/lib/module/specs/NativeStripeContainer.js.map +1 -0
  221. package/lib/module/specs/NativeStripeSdkModule.js +2 -0
  222. package/lib/module/specs/NativeStripeSdkModule.js.map +1 -0
  223. package/lib/module/specs/utils.js +2 -0
  224. package/lib/module/specs/utils.js.map +1 -0
  225. package/lib/module/types/EmbeddedPaymentElement.js +2 -0
  226. package/lib/module/types/EmbeddedPaymentElement.js.map +1 -0
  227. package/lib/module/types/PaymentSheet.js +1 -1
  228. package/lib/module/types/PaymentSheet.js.map +1 -1
  229. package/lib/typescript/src/components/AddToWalletButton.d.ts.map +1 -1
  230. package/lib/typescript/src/components/AddressSheet.d.ts.map +1 -1
  231. package/lib/typescript/src/components/AuBECSDebitForm.d.ts.map +1 -1
  232. package/lib/typescript/src/components/CardField.d.ts +1 -1
  233. package/lib/typescript/src/components/CardField.d.ts.map +1 -1
  234. package/lib/typescript/src/components/CardForm.d.ts +1 -1
  235. package/lib/typescript/src/components/CardForm.d.ts.map +1 -1
  236. package/lib/typescript/src/components/CustomerSheet.d.ts +1 -1
  237. package/lib/typescript/src/components/CustomerSheet.d.ts.map +1 -1
  238. package/lib/typescript/src/components/StripeContainer.d.ts.map +1 -1
  239. package/lib/typescript/src/events.d.ts +13 -0
  240. package/lib/typescript/src/events.d.ts.map +1 -0
  241. package/lib/typescript/src/functions.d.ts.map +1 -1
  242. package/lib/typescript/src/hooks/useFinancialConnectionsSheet.d.ts +4 -4
  243. package/lib/typescript/src/hooks/useFinancialConnectionsSheet.d.ts.map +1 -1
  244. package/lib/typescript/src/hooks/useStripe.d.ts +2 -2
  245. package/lib/typescript/src/hooks/useStripe.d.ts.map +1 -1
  246. package/lib/typescript/src/index.d.ts +2 -0
  247. package/lib/typescript/src/index.d.ts.map +1 -1
  248. package/lib/typescript/src/specs/NativeAddToWalletButton.d.ts +27 -0
  249. package/lib/typescript/src/specs/NativeAddToWalletButton.d.ts.map +1 -0
  250. package/lib/typescript/src/specs/NativeAddressSheet.d.ts +34 -0
  251. package/lib/typescript/src/specs/NativeAddressSheet.d.ts.map +1 -0
  252. package/lib/typescript/src/specs/NativeApplePayButton.d.ts +28 -0
  253. package/lib/typescript/src/specs/NativeApplePayButton.d.ts.map +1 -0
  254. package/lib/typescript/src/specs/NativeAuBECSDebitForm.d.ts +19 -0
  255. package/lib/typescript/src/specs/NativeAuBECSDebitForm.d.ts.map +1 -0
  256. package/lib/typescript/src/specs/NativeCardField.d.ts +33 -0
  257. package/lib/typescript/src/specs/NativeCardField.d.ts.map +1 -0
  258. package/lib/typescript/src/specs/NativeCardForm.d.ts +31 -0
  259. package/lib/typescript/src/specs/NativeCardForm.d.ts.map +1 -0
  260. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts +17 -0
  261. package/lib/typescript/src/specs/NativeEmbeddedPaymentElement.d.ts.map +1 -0
  262. package/lib/typescript/src/specs/NativeGooglePayButton.d.ts +11 -0
  263. package/lib/typescript/src/specs/NativeGooglePayButton.d.ts.map +1 -0
  264. package/lib/typescript/src/specs/NativeStripeContainer.d.ts +8 -0
  265. package/lib/typescript/src/specs/NativeStripeContainer.d.ts.map +1 -0
  266. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +93 -0
  267. package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -0
  268. package/lib/typescript/src/specs/utils.d.ts +20 -0
  269. package/lib/typescript/src/specs/utils.d.ts.map +1 -0
  270. package/lib/typescript/src/types/CustomerSheet.d.ts +1 -5
  271. package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
  272. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +161 -0
  273. package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -0
  274. package/lib/typescript/src/types/PaymentSheet.d.ts +97 -4
  275. package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
  276. package/lib/typescript/src/types/components/CardFieldInput.d.ts +3 -2
  277. package/lib/typescript/src/types/components/CardFieldInput.d.ts.map +1 -1
  278. package/lib/typescript/src/types/components/CardFormView.d.ts +3 -1
  279. package/lib/typescript/src/types/components/CardFormView.d.ts.map +1 -1
  280. package/package.json +22 -2
  281. package/src/components/AddToWalletButton.tsx +2 -5
  282. package/src/components/AddressSheet.tsx +5 -16
  283. package/src/components/AuBECSDebitForm.tsx +3 -12
  284. package/src/components/CardField.tsx +20 -30
  285. package/src/components/CardForm.tsx +14 -29
  286. package/src/components/CustomerSheet.tsx +23 -25
  287. package/src/components/PlatformPayButton.tsx +6 -6
  288. package/src/components/StripeContainer.tsx +5 -12
  289. package/src/components/StripeProvider.tsx +1 -1
  290. package/src/events.ts +49 -0
  291. package/src/functions.ts +13 -24
  292. package/src/hooks/useFinancialConnectionsSheet.tsx +2 -2
  293. package/src/hooks/useStripe.tsx +2 -2
  294. package/src/index.tsx +3 -0
  295. package/src/specs/NativeAddToWalletButton.ts +40 -0
  296. package/src/specs/NativeAddressSheet.ts +50 -0
  297. package/src/specs/NativeApplePayButton.ts +40 -0
  298. package/src/specs/NativeAuBECSDebitForm.ts +24 -0
  299. package/src/specs/NativeCardField.ts +51 -0
  300. package/src/specs/NativeCardForm.ts +43 -0
  301. package/src/specs/NativeEmbeddedPaymentElement.ts +28 -0
  302. package/src/specs/NativeGooglePayButton.ts +20 -0
  303. package/src/specs/NativeStripeContainer.ts +12 -0
  304. package/src/specs/NativeStripeSdkModule.ts +219 -0
  305. package/src/specs/utils.ts +22 -0
  306. package/src/types/CustomerSheet.ts +1 -5
  307. package/src/types/EmbeddedPaymentElement.tsx +467 -0
  308. package/src/types/PaymentSheet.ts +114 -4
  309. package/src/types/components/CardFieldInput.ts +1 -2
  310. package/src/types/components/CardFormView.ts +1 -1
  311. package/stripe-react-native.podspec +27 -2
  312. package/android/src/main/java/com/reactnativestripesdk/CardChangedEvent.kt +0 -54
  313. package/ios/StripeSdk.m +0 -244
  314. package/lib/commonjs/NativeStripeSdk.js +0 -2
  315. package/lib/commonjs/NativeStripeSdk.js.map +0 -1
  316. package/lib/commonjs/components/ApplePayButtonNative.js +0 -2
  317. package/lib/commonjs/components/ApplePayButtonNative.js.map +0 -1
  318. package/lib/commonjs/components/GooglePayButtonNative.js +0 -2
  319. package/lib/commonjs/components/GooglePayButtonNative.js.map +0 -1
  320. package/lib/module/NativeStripeSdk.js +0 -2
  321. package/lib/module/NativeStripeSdk.js.map +0 -1
  322. package/lib/module/components/ApplePayButtonNative.js +0 -2
  323. package/lib/module/components/ApplePayButtonNative.js.map +0 -1
  324. package/lib/module/components/GooglePayButtonNative.js +0 -2
  325. package/lib/module/components/GooglePayButtonNative.js.map +0 -1
  326. package/lib/typescript/src/NativeStripeSdk.d.ts +0 -58
  327. package/lib/typescript/src/NativeStripeSdk.d.ts.map +0 -1
  328. package/lib/typescript/src/components/ApplePayButtonNative.d.ts +0 -4
  329. package/lib/typescript/src/components/ApplePayButtonNative.d.ts.map +0 -1
  330. package/lib/typescript/src/components/GooglePayButtonNative.d.ts +0 -4
  331. package/lib/typescript/src/components/GooglePayButtonNative.d.ts.map +0 -1
  332. package/src/NativeStripeSdk.tsx +0 -159
  333. package/src/components/ApplePayButtonNative.tsx +0 -5
  334. package/src/components/GooglePayButtonNative.tsx +0 -7
@@ -0,0 +1,17 @@
1
+ import com.facebook.react.bridge.Arguments
2
+ import com.facebook.react.bridge.WritableMap
3
+ import com.reactnativestripesdk.utils.mapFromPaymentSheetBillingDetails
4
+ import com.stripe.android.paymentelement.EmbeddedPaymentElement
5
+ import com.stripe.android.paymentelement.ExperimentalEmbeddedPaymentElementApi
6
+
7
+ /**
8
+ * Serialize Stripe's PaymentOptionDisplayData into a WritableMap
9
+ * that can be sent over the RN bridge.
10
+ */
11
+ @OptIn(ExperimentalEmbeddedPaymentElementApi::class)
12
+ fun EmbeddedPaymentElement.PaymentOptionDisplayData.toWritableMap(): WritableMap =
13
+ Arguments.createMap().apply {
14
+ putString("label", label)
15
+ putString("paymentMethodType", paymentMethodType)
16
+ putMap("billingDetails", mapFromPaymentSheetBillingDetails(billingDetails))
17
+ }
@@ -1,11 +1,15 @@
1
1
  package com.reactnativestripesdk
2
2
 
3
+ import android.annotation.SuppressLint
3
4
  import android.content.Context
5
+ import android.content.res.Configuration
4
6
  import android.graphics.Color
5
7
  import android.os.Bundle
6
8
  import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
9
+ import com.stripe.android.paymentelement.ExperimentalEmbeddedPaymentElementApi
7
10
  import com.stripe.android.paymentsheet.PaymentSheet
8
11
 
12
+ @SuppressLint("RestrictedApi")
9
13
  fun buildPaymentSheetAppearance(
10
14
  userParams: Bundle?,
11
15
  context: Context,
@@ -14,6 +18,28 @@ fun buildPaymentSheetAppearance(
14
18
  val lightColorParams = colorParams?.getBundle(PaymentSheetAppearanceKeys.LIGHT) ?: colorParams
15
19
  val darkColorParams = colorParams?.getBundle(PaymentSheetAppearanceKeys.DARK) ?: colorParams
16
20
 
21
+ val embeddedAppearance =
22
+ buildEmbeddedAppearance(
23
+ userParams?.getBundle(PaymentSheetAppearanceKeys.EMBEDDED_PAYMENT_ELEMENT),
24
+ lightColorParams,
25
+ context,
26
+ )
27
+
28
+ embeddedAppearance?.let {
29
+ return PaymentSheet.Appearance(
30
+ typography = buildTypography(userParams?.getBundle(PaymentSheetAppearanceKeys.FONT), context),
31
+ colorsLight = buildColors(lightColorParams, PaymentSheet.Colors.defaultLight),
32
+ colorsDark = buildColors(darkColorParams, PaymentSheet.Colors.defaultDark),
33
+ shapes = buildShapes(userParams?.getBundle(PaymentSheetAppearanceKeys.SHAPES)),
34
+ primaryButton =
35
+ buildPrimaryButton(
36
+ userParams?.getBundle(PaymentSheetAppearanceKeys.PRIMARY_BUTTON),
37
+ context,
38
+ ),
39
+ embeddedAppearance = embeddedAppearance,
40
+ )
41
+ }
42
+
17
43
  return PaymentSheet.Appearance(
18
44
  typography = buildTypography(userParams?.getBundle(PaymentSheetAppearanceKeys.FONT), context),
19
45
  colorsLight = buildColors(lightColorParams, PaymentSheet.Colors.defaultLight),
@@ -213,6 +239,205 @@ private fun buildPrimaryButtonColors(
213
239
  ),
214
240
  )
215
241
 
242
+ @OptIn(ExperimentalEmbeddedPaymentElementApi::class)
243
+ @SuppressLint("RestrictedApi")
244
+ @Throws(PaymentSheetAppearanceException::class)
245
+ private fun buildEmbeddedAppearance(
246
+ embeddedParams: Bundle?,
247
+ defaultColorsBundle: Bundle?,
248
+ context: Context,
249
+ ): PaymentSheet.Appearance.Embedded? {
250
+ if (embeddedParams == null) {
251
+ return null
252
+ }
253
+
254
+ val rowParams =
255
+ getBundleOrNull(embeddedParams, PaymentSheetAppearanceKeys.ROW)
256
+ ?: return null
257
+
258
+ val defaultColors = buildColors(defaultColorsBundle, PaymentSheet.Colors.defaultLight)
259
+
260
+ // Default style
261
+ val styleString = rowParams.getString(PaymentSheetAppearanceKeys.STYLE, "flatWithRadio")
262
+
263
+ val defaultAdditionalInsetsDp = 6.0f
264
+ val defaultSeparatorThicknessDp = 1.0f
265
+ val defaultSpacingDp = 12.0f
266
+ val defaultCheckmarkInsetDp = 0f
267
+
268
+ val additionalInsets = getFloatOr(rowParams, PaymentSheetAppearanceKeys.ADDITIONAL_INSETS, defaultAdditionalInsetsDp)
269
+
270
+ val rowStyle: PaymentSheet.Appearance.Embedded.RowStyle =
271
+ when (styleString) {
272
+ "flatWithRadio" -> {
273
+ val flatParams = getBundleOrNull(rowParams, PaymentSheetAppearanceKeys.FLAT)
274
+ val radioParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.RADIO)
275
+ val separatorInsetsParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
276
+
277
+ // Default separator insets specific to FlatWithRadio
278
+ val defaultSeparatorStartInsetDp = 30.0f
279
+ val defaultSeparatorEndInsetDp = 0.0f
280
+
281
+ // Parse dimensions as Floats
282
+ val separatorThickness = getFloatOr(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS, defaultSeparatorThicknessDp)
283
+ val startSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.LEFT, defaultSeparatorStartInsetDp)
284
+ val endSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.RIGHT, defaultSeparatorEndInsetDp)
285
+
286
+ // Parse booleans
287
+ val topEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED, true)
288
+ val bottomEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED, true)
289
+
290
+ // Parse individual colors using default colors
291
+ val parsedSeparatorColor =
292
+ dynamicColorFromParams(
293
+ context,
294
+ flatParams,
295
+ PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
296
+ defaultColors.componentBorder,
297
+ )
298
+
299
+ val parsedSelectedColor =
300
+ dynamicColorFromParams(
301
+ context,
302
+ radioParams,
303
+ PaymentSheetAppearanceKeys.SELECTED_COLOR,
304
+ defaultColors.primary,
305
+ )
306
+
307
+ val parsedUnselectedColor =
308
+ dynamicColorFromParams(
309
+ context,
310
+ radioParams,
311
+ PaymentSheetAppearanceKeys.UNSELECTED_COLOR,
312
+ defaultColors.componentBorder,
313
+ )
314
+
315
+ val flatRadioColors =
316
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithRadio.Colors(
317
+ separatorColor = parsedSeparatorColor,
318
+ unselectedColor = parsedUnselectedColor,
319
+ selectedColor = parsedSelectedColor,
320
+ )
321
+
322
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithRadio(
323
+ separatorThicknessDp = separatorThickness,
324
+ startSeparatorInsetDp = startSeparatorInset,
325
+ endSeparatorInsetDp = endSeparatorInset,
326
+ topSeparatorEnabled = topEnabled,
327
+ bottomSeparatorEnabled = bottomEnabled,
328
+ additionalVerticalInsetsDp = additionalInsets,
329
+ horizontalInsetsDp = 0.0F, // We do not have an iOS equal for this API so it's not configurable in React Native
330
+ colorsLight = flatRadioColors,
331
+ colorsDark = flatRadioColors,
332
+ )
333
+ }
334
+ "flatWithCheckmark" -> {
335
+ val flatParams = getBundleOrNull(rowParams, PaymentSheetAppearanceKeys.FLAT)
336
+ val checkmarkParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.CHECKMARK)
337
+ val separatorInsetsParams = getBundleOrNull(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_INSETS)
338
+
339
+ // Default separator insets specific to FlatWithCheckmark
340
+ val defaultSeparatorStartInsetDp = 0.0f
341
+ val defaultSeparatorEndInsetDp = 0.0f
342
+
343
+ // Parse dimensions as Floats
344
+ val separatorThickness = getFloatOr(flatParams, PaymentSheetAppearanceKeys.SEPARATOR_THICKNESS, defaultSeparatorThicknessDp)
345
+ val startSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.LEFT, defaultSeparatorStartInsetDp)
346
+ val endSeparatorInset = getFloatOr(separatorInsetsParams, PaymentSheetAppearanceKeys.RIGHT, defaultSeparatorEndInsetDp)
347
+ val checkmarkInset = getFloatOr(checkmarkParams, PaymentSheetAppearanceKeys.CHECKMARK_INSET, defaultCheckmarkInsetDp)
348
+
349
+ // Parse booleans
350
+ val topEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.TOP_SEPARATOR_ENABLED, true)
351
+ val bottomEnabled = getBooleanOr(flatParams, PaymentSheetAppearanceKeys.BOTTOM_SEPARATOR_ENABLED, true)
352
+
353
+ // Parse individual colors using root defaults
354
+ val parsedSeparatorColor =
355
+ dynamicColorFromParams(
356
+ context,
357
+ flatParams,
358
+ PaymentSheetAppearanceKeys.SEPARATOR_COLOR,
359
+ defaultColors.componentBorder,
360
+ )
361
+
362
+ val parsedCheckmarkColor =
363
+ dynamicColorFromParams(
364
+ context,
365
+ checkmarkParams,
366
+ PaymentSheetAppearanceKeys.COLOR,
367
+ defaultColors.primary,
368
+ )
369
+
370
+ // Create the required Colors object
371
+ val flatCheckmarkColors =
372
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithCheckmark.Colors(
373
+ separatorColor = parsedSeparatorColor,
374
+ checkmarkColor = parsedCheckmarkColor,
375
+ )
376
+
377
+ PaymentSheet.Appearance.Embedded.RowStyle.FlatWithCheckmark(
378
+ separatorThicknessDp = separatorThickness,
379
+ startSeparatorInsetDp = startSeparatorInset,
380
+ endSeparatorInsetDp = endSeparatorInset,
381
+ topSeparatorEnabled = topEnabled,
382
+ bottomSeparatorEnabled = bottomEnabled,
383
+ checkmarkInsetDp = checkmarkInset,
384
+ additionalVerticalInsetsDp = additionalInsets,
385
+ horizontalInsetsDp = 0.0F, // We do not have an iOS equal for this API so it's not configurable in React Native
386
+ colorsLight = flatCheckmarkColors,
387
+ colorsDark = flatCheckmarkColors,
388
+ )
389
+ }
390
+ "floatingButton" -> {
391
+ val floatingParams = getBundleOrNull(rowParams, PaymentSheetAppearanceKeys.FLOATING)
392
+ PaymentSheet.Appearance.Embedded.RowStyle.FloatingButton(
393
+ additionalInsetsDp = additionalInsets,
394
+ spacingDp = getFloatOr(floatingParams, PaymentSheetAppearanceKeys.SPACING, defaultSpacingDp),
395
+ )
396
+ }
397
+ else -> {
398
+ System.err.println("WARN: Unsupported embedded payment element row style received: $styleString. Falling back to default.")
399
+ return null
400
+ }
401
+ }
402
+
403
+ return PaymentSheet.Appearance.Embedded(style = rowStyle)
404
+ }
405
+
406
+ /**
407
+ * Pulls a light/dark hex‑string map out of [params],
408
+ * chooses the right one based on the current UI mode,
409
+ * and parses it (falling back to [defaultColor]).
410
+ */
411
+ private fun dynamicColorFromParams(
412
+ context: Context,
413
+ params: Bundle?,
414
+ key: String,
415
+ defaultColor: Int,
416
+ ): Int {
417
+ // Expect a nested Bundle { "light": "#RRGGBB", "dark": "#RRGGBB" }
418
+ val colorBundle = params?.getBundle(key)
419
+ if (colorBundle != null) {
420
+ val isDark =
421
+ (
422
+ context.resources.configuration.uiMode
423
+ and Configuration.UI_MODE_NIGHT_MASK
424
+ ) == Configuration.UI_MODE_NIGHT_YES
425
+
426
+ // Pick the hex for current mode, or null
427
+ val hex =
428
+ if (isDark) {
429
+ colorBundle.getString(PaymentSheetAppearanceKeys.DARK)
430
+ } else {
431
+ colorBundle.getString(PaymentSheetAppearanceKeys.LIGHT)
432
+ }
433
+
434
+ return colorFromHexOrDefault(hex, defaultColor)
435
+ }
436
+
437
+ // no override bundle → just use default
438
+ return defaultColor
439
+ }
440
+
216
441
  private fun getDoubleOrNull(
217
442
  bundle: Bundle?,
218
443
  key: String,
@@ -250,6 +475,22 @@ private fun getFloatOr(
250
475
  return defaultValue
251
476
  }
252
477
 
478
+ private fun getBundleOrNull(
479
+ bundle: Bundle?,
480
+ key: String,
481
+ ): Bundle? = bundle?.getBundle(key)
482
+
483
+ private fun getBooleanOr(
484
+ bundle: Bundle?,
485
+ key: String,
486
+ defaultValue: Boolean,
487
+ ): Boolean =
488
+ if (bundle?.containsKey(key) == true) {
489
+ bundle.getBoolean(key)
490
+ } else {
491
+ defaultValue
492
+ }
493
+
253
494
  private fun getFloatOrNull(
254
495
  bundle: Bundle?,
255
496
  key: String,
@@ -327,5 +568,30 @@ private class PaymentSheetAppearanceKeys {
327
568
  const val PRIMARY_BUTTON = "primaryButton"
328
569
  const val TEXT = "text"
329
570
  const val BORDER = "border"
571
+
572
+ const val EMBEDDED_PAYMENT_ELEMENT = "embeddedPaymentElement"
573
+ const val ROW = "row"
574
+ const val STYLE = "style"
575
+ const val ADDITIONAL_INSETS = "additionalInsets"
576
+
577
+ const val FLAT = "flat"
578
+ const val SEPARATOR_THICKNESS = "separatorThickness"
579
+ const val SEPARATOR_COLOR = "separatorColor"
580
+ const val SEPARATOR_INSETS = "separatorInsets"
581
+ const val TOP_SEPARATOR_ENABLED = "topSeparatorEnabled"
582
+ const val BOTTOM_SEPARATOR_ENABLED = "bottomSeparatorEnabled"
583
+ const val RADIO = "radio"
584
+ const val SELECTED_COLOR = "selectedColor"
585
+ const val UNSELECTED_COLOR = "unselectedColor"
586
+ const val CHECKMARK = "checkmark"
587
+ const val COLOR = "color"
588
+ const val CHECKMARK_INSET = "inset"
589
+
590
+ const val FLOATING = "floating"
591
+ const val SPACING = "spacing"
592
+
593
+ // Keys for EdgeInsetsConfig
594
+ const val LEFT = "left"
595
+ const val RIGHT = "right"
330
596
  }
331
597
  }
@@ -11,13 +11,8 @@ import android.os.Bundle
11
11
  import android.os.Handler
12
12
  import android.os.Looper
13
13
  import android.util.Base64
14
- import android.view.LayoutInflater
15
- import android.view.View
16
- import android.view.ViewGroup
17
- import android.widget.FrameLayout
18
14
  import androidx.appcompat.content.res.AppCompatResources
19
15
  import androidx.core.graphics.drawable.DrawableCompat
20
- import androidx.fragment.app.Fragment
21
16
  import com.facebook.react.bridge.Arguments
22
17
  import com.facebook.react.bridge.Promise
23
18
  import com.facebook.react.bridge.ReactApplicationContext
@@ -30,6 +25,7 @@ import com.reactnativestripesdk.utils.KeepJsAwakeTask
30
25
  import com.reactnativestripesdk.utils.PaymentSheetAppearanceException
31
26
  import com.reactnativestripesdk.utils.PaymentSheetErrorType
32
27
  import com.reactnativestripesdk.utils.PaymentSheetException
28
+ import com.reactnativestripesdk.utils.StripeFragment
33
29
  import com.reactnativestripesdk.utils.createError
34
30
  import com.reactnativestripesdk.utils.createResult
35
31
  import com.reactnativestripesdk.utils.mapFromPaymentMethod
@@ -48,10 +44,9 @@ import java.io.ByteArrayOutputStream
48
44
  import kotlin.Exception
49
45
 
50
46
  @OptIn(ExperimentalAllowsRemovalOfLastSavedPaymentMethodApi::class)
51
- class PaymentSheetFragment(
52
- private val context: ReactApplicationContext,
53
- private val initPromise: Promise,
54
- ) : Fragment() {
47
+ class PaymentSheetFragment : StripeFragment() {
48
+ private lateinit var context: ReactApplicationContext
49
+ private lateinit var initPromise: Promise
55
50
  private var paymentSheet: PaymentSheet? = null
56
51
  private var flowController: PaymentSheet.FlowController? = null
57
52
  private var paymentIntentClientSecret: String? = null
@@ -64,17 +59,7 @@ class PaymentSheetFragment(
64
59
  internal var paymentSheetIntentCreationCallback = CompletableDeferred<ReadableMap>()
65
60
  private var keepJsAwake: KeepJsAwakeTask? = null
66
61
 
67
- override fun onCreateView(
68
- inflater: LayoutInflater,
69
- container: ViewGroup?,
70
- savedInstanceState: Bundle?,
71
- ): View = FrameLayout(requireActivity()).also { it.visibility = View.GONE }
72
-
73
- override fun onViewCreated(
74
- view: View,
75
- savedInstanceState: Bundle?,
76
- ) {
77
- super.onViewCreated(view, savedInstanceState)
62
+ override fun prepare() {
78
63
  val merchantDisplayName = arguments?.getString("merchantDisplayName").orEmpty()
79
64
  if (merchantDisplayName.isEmpty()) {
80
65
  initPromise.resolve(
@@ -163,11 +148,13 @@ class PaymentSheetFragment(
163
148
  ),
164
149
  )
165
150
  }
151
+
166
152
  is PaymentSheetResult.Failed -> {
167
153
  resolvePaymentResult(
168
154
  createError(PaymentSheetErrorType.Failed.toString(), paymentResult.error),
169
155
  )
170
156
  }
157
+
171
158
  is PaymentSheetResult.Completed -> {
172
159
  resolvePaymentResult(WritableNativeMap())
173
160
  // Remove the fragment now, we can be sure it won't be needed again if an intent is
@@ -183,22 +170,13 @@ class PaymentSheetFragment(
183
170
  val createIntentCallback =
184
171
  CreateIntentCallback { paymentMethod, shouldSavePaymentMethod ->
185
172
  val stripeSdkModule: StripeSdkModule? = context.getNativeModule(StripeSdkModule::class.java)
186
- if (stripeSdkModule == null || stripeSdkModule.eventListenerCount == 0) {
187
- return@CreateIntentCallback CreateIntentResult.Failure(
188
- cause =
189
- Exception(
190
- "Tried to call confirmHandler, but no callback was found. Please file an issue: https://github.com/stripe/stripe-react-native/issues",
191
- ),
192
- displayMessage = "An unexpected error occurred",
193
- )
194
- }
195
173
  val params =
196
174
  Arguments.createMap().apply {
197
175
  putMap("paymentMethod", mapFromPaymentMethod(paymentMethod))
198
176
  putBoolean("shouldSavePaymentMethod", shouldSavePaymentMethod)
199
177
  }
200
178
 
201
- stripeSdkModule.sendEvent(context, "onConfirmHandlerCallback", params)
179
+ stripeSdkModule?.emitOnConfirmHandlerCallback(params)
202
180
 
203
181
  val resultFromJavascript = paymentSheetIntentCreationCallback.await()
204
182
  // reset the completable
@@ -352,7 +330,8 @@ class PaymentSheetFragment(
352
330
  override fun onActivitySaveInstanceState(
353
331
  activity: Activity,
354
332
  outState: Bundle,
355
- ) {}
333
+ ) {
334
+ }
356
335
 
357
336
  override fun onActivityDestroyed(activity: Activity) {
358
337
  paymentSheetActivity = null
@@ -442,6 +421,18 @@ class PaymentSheetFragment(
442
421
  companion object {
443
422
  internal const val TAG = "payment_sheet_launch_fragment"
444
423
 
424
+ internal fun create(
425
+ context: ReactApplicationContext,
426
+ arguments: Bundle,
427
+ initPromise: Promise,
428
+ ): PaymentSheetFragment {
429
+ val instance = PaymentSheetFragment()
430
+ instance.context = context
431
+ instance.initPromise = initPromise
432
+ instance.arguments = arguments
433
+ return instance
434
+ }
435
+
445
436
  private val mapIntToButtonType =
446
437
  mapOf(
447
438
  1 to PaymentSheet.GooglePayConfiguration.ButtonType.Buy,
@@ -509,7 +500,7 @@ class PaymentSheetFragment(
509
500
  }
510
501
 
511
502
  @Throws(PaymentSheetException::class)
512
- private fun buildIntentConfiguration(intentConfigurationParams: Bundle?): PaymentSheet.IntentConfiguration? {
503
+ internal fun buildIntentConfiguration(intentConfigurationParams: Bundle?): PaymentSheet.IntentConfiguration? {
513
504
  if (intentConfigurationParams == null) {
514
505
  return null
515
506
  }
@@ -556,7 +547,7 @@ class PaymentSheetFragment(
556
547
 
557
548
  @OptIn(ExperimentalCustomerSessionApi::class)
558
549
  @Throws(PaymentSheetException::class)
559
- private fun buildCustomerConfiguration(bundle: Bundle?): PaymentSheet.CustomerConfiguration? {
550
+ internal fun buildCustomerConfiguration(bundle: Bundle?): PaymentSheet.CustomerConfiguration? {
560
551
  val customerId = bundle?.getString("customerId").orEmpty()
561
552
  val customerEphemeralKeySecret = bundle?.getString("customerEphemeralKeySecret").orEmpty()
562
553
  val customerSessionClientSecret = bundle?.getString("customerSessionClientSecret").orEmpty()
@@ -638,6 +629,7 @@ fun mapToAddressCollectionMode(str: String?): PaymentSheet.BillingDetailsCollect
638
629
  when (str) {
639
630
  "automatic" ->
640
631
  PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Automatic
632
+
641
633
  "never" -> PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Never
642
634
  "full" -> PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Full
643
635
  else -> PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Automatic
@@ -0,0 +1,113 @@
1
+ package com.reactnativestripesdk
2
+
3
+ import android.content.Context
4
+ import androidx.compose.runtime.Composable
5
+ import androidx.compose.ui.platform.AbstractComposeView
6
+ import androidx.compose.ui.platform.ViewCompositionStrategy
7
+ import androidx.compose.ui.platform.findViewTreeCompositionContext
8
+ import androidx.lifecycle.Lifecycle
9
+ import androidx.lifecycle.LifecycleEventObserver
10
+ import androidx.lifecycle.LifecycleOwner
11
+ import androidx.lifecycle.LifecycleRegistry
12
+ import androidx.lifecycle.findViewTreeViewModelStoreOwner
13
+ import androidx.lifecycle.setViewTreeLifecycleOwner
14
+ import androidx.lifecycle.setViewTreeViewModelStoreOwner
15
+ import androidx.savedstate.findViewTreeSavedStateRegistryOwner
16
+ import androidx.savedstate.setViewTreeSavedStateRegistryOwner
17
+ import com.facebook.react.bridge.ReactContext
18
+
19
+ /**
20
+ * Compose disposes views by default when using Fragments, which is not compatible with how
21
+ * react-native-screens work. To avoid this we change the composition strategy to use the
22
+ * activity lifecycle instead of the fragment. Note that `setViewTreeLifecycleOwner` also
23
+ * needs to be set otherwise a different code path will dispose of the view.
24
+ *
25
+ * **IMPORTANT** Views using this will need to call `handleOnDropViewInstance` manually to avoid leaking.
26
+ * This can be done using the using the following code in the view manager:
27
+ *
28
+ * ```
29
+ * override fun onDropViewInstance(view: SomeStripeAbstractComposeView) {
30
+ * super.onDropViewInstance(view)
31
+ *
32
+ * view.handleOnDropViewInstance()
33
+ * }
34
+ * ```
35
+ */
36
+ abstract class StripeAbstractComposeView(
37
+ context: Context,
38
+ ) : AbstractComposeView(context) {
39
+ /**
40
+ * Dummy compose view that will be added at the root of the app, this is needed so that the context
41
+ * that compose needs is already initialized and we can set it directly on our compose views.
42
+ * If we do not do this there are cases where react-native initializes compose views in ways that
43
+ * are not supported and causes crashes. An example is when using a compose view inside react-native
44
+ * Modal component.
45
+ */
46
+ class CompatView(
47
+ context: Context,
48
+ ) : AbstractComposeView(context) {
49
+ init {
50
+ visibility = GONE
51
+ }
52
+
53
+ @Composable
54
+ override fun Content() {
55
+ }
56
+ }
57
+
58
+ private var isLifecycleSetup = false
59
+
60
+ // Create a lifecycle this is tied to the activity, but that we can manually
61
+ // update to DESTROYED state when the view is dropped.
62
+ private val lifecycleOwner: LifecycleOwner =
63
+ object : LifecycleOwner {
64
+ override val lifecycle: Lifecycle get() {
65
+ return lifecycleRegistry
66
+ }
67
+ }
68
+ private var lifecycleRegistry = LifecycleRegistry(lifecycleOwner)
69
+
70
+ init {
71
+ // Setup lifecycles
72
+ setViewCompositionStrategy(
73
+ ViewCompositionStrategy.DisposeOnLifecycleDestroyed(lifecycleOwner = lifecycleOwner),
74
+ )
75
+ setViewTreeLifecycleOwner(lifecycleOwner = lifecycleOwner)
76
+
77
+ // Setup context from dummy compose view.
78
+ (context as ReactContext).getNativeModule(StripeSdkModule::class.java)?.composeCompatView?.let {
79
+ setParentCompositionContext(it.findViewTreeCompositionContext())
80
+ setViewTreeSavedStateRegistryOwner(it.findViewTreeSavedStateRegistryOwner())
81
+ setViewTreeViewModelStoreOwner(it.findViewTreeViewModelStoreOwner())
82
+ }
83
+ }
84
+
85
+ override fun onAttachedToWindow() {
86
+ super.onAttachedToWindow()
87
+
88
+ if (isLifecycleSetup) {
89
+ return
90
+ }
91
+
92
+ ((context as? ReactContext)?.currentActivity as? LifecycleOwner?)?.let {
93
+ isLifecycleSetup = true
94
+
95
+ // Setup the lifecycle to match the activity.
96
+ it.lifecycle.addObserver(
97
+ object : LifecycleEventObserver {
98
+ override fun onStateChanged(
99
+ source: LifecycleOwner,
100
+ event: Lifecycle.Event,
101
+ ) {
102
+ lifecycleRegistry.handleLifecycleEvent(event)
103
+ }
104
+ },
105
+ )
106
+ }
107
+ }
108
+
109
+ fun handleOnDropViewInstance() {
110
+ // Update the lifecycle state to DESTROYED to cause the composition to be destroyed.
111
+ lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
112
+ }
113
+ }
@@ -4,20 +4,28 @@ import com.facebook.react.module.annotations.ReactModule
4
4
  import com.facebook.react.uimanager.ThemedReactContext
5
5
  import com.facebook.react.uimanager.ViewGroupManager
6
6
  import com.facebook.react.uimanager.annotations.ReactProp
7
+ import com.facebook.react.viewmanagers.StripeContainerManagerDelegate
8
+ import com.facebook.react.viewmanagers.StripeContainerManagerInterface
7
9
 
8
10
  @ReactModule(name = StripeContainerManager.REACT_CLASS)
9
- class StripeContainerManager : ViewGroupManager<StripeContainerView>() {
11
+ class StripeContainerManager :
12
+ ViewGroupManager<StripeContainerView>(),
13
+ StripeContainerManagerInterface<StripeContainerView> {
14
+ private val delegate = StripeContainerManagerDelegate(this)
15
+
10
16
  override fun getName() = REACT_CLASS
11
17
 
18
+ override fun getDelegate() = delegate
19
+
12
20
  @ReactProp(name = "keyboardShouldPersistTaps")
13
- fun setKeyboardShouldPersistTaps(
21
+ override fun setKeyboardShouldPersistTaps(
14
22
  view: StripeContainerView,
15
23
  keyboardShouldPersistTaps: Boolean,
16
24
  ) {
17
25
  view.setKeyboardShouldPersistTaps(keyboardShouldPersistTaps)
18
26
  }
19
27
 
20
- override fun createViewInstance(reactContext: ThemedReactContext): StripeContainerView = StripeContainerView(reactContext)
28
+ override fun createViewInstance(reactContext: ThemedReactContext) = StripeContainerView(reactContext)
21
29
 
22
30
  companion object {
23
31
  const val REACT_CLASS = "StripeContainer"