@primer-io/react-native 0.16.0 → 2.0.1

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 (233) hide show
  1. package/README.md +114 -24
  2. package/android/build.gradle +10 -2
  3. package/android/gradle.properties +3 -3
  4. package/android/src/main/java/com/primerioreactnative/PrimerRN.kt +124 -150
  5. package/android/src/main/java/com/primerioreactnative/PrimerRNEventListener.kt +212 -128
  6. package/android/src/main/java/com/primerioreactnative/ReactNativePackage.kt +3 -14
  7. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerCheckoutDataRN.kt +12 -0
  8. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerClientSessionRN.kt +54 -0
  9. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerErrorRN.kt +3 -9
  10. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerEvents.kt +13 -0
  11. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerPaymentInstrumentTokenRN.kt +4 -4
  12. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerPaymentMethodDataRN.kt +8 -0
  13. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerSettingsRN.kt +43 -125
  14. package/android/src/main/java/com/primerioreactnative/extensions/Payment.kt +6 -0
  15. package/android/src/main/java/com/primerioreactnative/extensions/PrimerAddress.kt +15 -0
  16. package/android/src/main/java/com/primerioreactnative/extensions/PrimerCheckoutData.kt +7 -0
  17. package/android/src/main/java/com/primerioreactnative/extensions/PrimerClientSession.kt +15 -0
  18. package/android/src/main/java/com/primerioreactnative/extensions/PrimerCustomer.kt +13 -0
  19. package/android/src/main/java/com/primerioreactnative/extensions/PrimerLineItem.kt +8 -0
  20. package/android/src/main/java/com/primerioreactnative/extensions/PrimerOrder.kt +6 -0
  21. package/android/src/main/java/com/primerioreactnative/extensions/PrimerPaymentMethodData.kt +7 -0
  22. package/android/src/main/java/com/primerioreactnative/utils/ErrorHelper.kt +1 -3
  23. package/android/src/main/java/com/primerioreactnative/utils/JsonConverter.kt +45 -0
  24. package/android/src/main/java/com/primerioreactnative/utils/PrimerImplementedRNCallbacks.kt +16 -6
  25. package/ios/DataModels/ImplementedRNCallbacks.swift +31 -0
  26. package/ios/DataModels/PrimerErrorRN.swift +0 -17
  27. package/ios/DataModels/PrimerSettingsRN.swift +70 -147
  28. package/ios/DataModels/PrimerThemeRN.swift +1 -10
  29. package/ios/RNTPrimer.m +26 -12
  30. package/ios/RNTPrimer.swift +295 -249
  31. package/ios/{Core/ReactNative-Bridging-Header.h → ReactNative-Bridging-Header.h} +0 -1
  32. package/ios/ReactNative.xcodeproj/project.pbxproj +14 -14
  33. package/lib/commonjs/Primer.js +201 -150
  34. package/lib/commonjs/Primer.js.map +1 -1
  35. package/lib/commonjs/RNPrimer.js +102 -41
  36. package/lib/commonjs/RNPrimer.js.map +1 -1
  37. package/lib/commonjs/index.js +110 -24
  38. package/lib/commonjs/index.js.map +1 -1
  39. package/lib/commonjs/models/{primer.js → Primer.js} +1 -1
  40. package/lib/commonjs/{headless_checkout/types.js.map → models/Primer.js.map} +0 -0
  41. package/lib/commonjs/models/PrimerCheckoutData.js +9 -0
  42. package/lib/commonjs/models/PrimerCheckoutData.js.map +1 -0
  43. package/lib/commonjs/models/PrimerCheckoutPaymentMethodData.js +2 -0
  44. package/lib/commonjs/models/{action-request.js.map → PrimerCheckoutPaymentMethodData.js.map} +0 -0
  45. package/lib/commonjs/models/PrimerClientSession.js +2 -0
  46. package/lib/commonjs/models/{client-session-actions-request.js.map → PrimerClientSession.js.map} +0 -0
  47. package/lib/commonjs/models/{utils/countryCode.js → PrimerCountryCode.js} +1 -1
  48. package/lib/commonjs/models/PrimerCountryCode.js.map +1 -0
  49. package/lib/commonjs/models/{utils/currencyCode.js → PrimerCurrencyCode.js} +1 -1
  50. package/lib/commonjs/models/PrimerCurrencyCode.js.map +1 -0
  51. package/lib/commonjs/models/PrimerError.js +28 -0
  52. package/lib/commonjs/models/PrimerError.js.map +1 -0
  53. package/lib/commonjs/models/PrimerPaymentMethodTokenData.js +14 -0
  54. package/lib/commonjs/models/PrimerPaymentMethodTokenData.js.map +1 -0
  55. package/lib/commonjs/models/PrimerSessionIntent.js +14 -0
  56. package/lib/commonjs/models/PrimerSessionIntent.js.map +1 -0
  57. package/lib/commonjs/models/{primer-config.js → PrimerSettings.js} +1 -1
  58. package/lib/commonjs/models/{primer-callbacks.js.map → PrimerSettings.js.map} +0 -0
  59. package/lib/commonjs/models/PrimerTheme.js +2 -0
  60. package/lib/commonjs/models/{primer-config.js.map → PrimerTheme.js.map} +0 -0
  61. package/lib/commonjs/utils/index.js.map +1 -1
  62. package/lib/module/Primer.js +201 -137
  63. package/lib/module/Primer.js.map +1 -1
  64. package/lib/module/RNPrimer.js +102 -41
  65. package/lib/module/RNPrimer.js.map +1 -1
  66. package/lib/module/index.js +9 -5
  67. package/lib/module/index.js.map +1 -1
  68. package/lib/module/models/Primer.js +2 -0
  69. package/lib/{commonjs/models/primer-request.js.map → module/models/Primer.js.map} +0 -0
  70. package/lib/module/models/PrimerCheckoutData.js +7 -0
  71. package/lib/module/models/PrimerCheckoutData.js.map +1 -0
  72. package/lib/module/models/PrimerCheckoutPaymentMethodData.js +2 -0
  73. package/lib/{commonjs/models/primer-settings.js.map → module/models/PrimerCheckoutPaymentMethodData.js.map} +0 -0
  74. package/lib/module/models/PrimerClientSession.js +2 -0
  75. package/lib/{commonjs/models/primer-theme.js.map → module/models/PrimerClientSession.js.map} +0 -0
  76. package/lib/module/models/{utils/countryCode.js → PrimerCountryCode.js} +1 -1
  77. package/lib/module/models/PrimerCountryCode.js.map +1 -0
  78. package/lib/module/models/{utils/currencyCode.js → PrimerCurrencyCode.js} +1 -1
  79. package/lib/module/models/PrimerCurrencyCode.js.map +1 -0
  80. package/lib/module/models/PrimerError.js +19 -0
  81. package/lib/module/models/PrimerError.js.map +1 -0
  82. package/lib/module/models/PrimerPaymentMethodTokenData.js +7 -0
  83. package/lib/module/models/PrimerPaymentMethodTokenData.js.map +1 -0
  84. package/lib/module/models/PrimerSessionIntent.js +7 -0
  85. package/lib/module/models/PrimerSessionIntent.js.map +1 -0
  86. package/lib/module/models/PrimerSettings.js +2 -0
  87. package/lib/{commonjs/models/primer.js.map → module/models/PrimerSettings.js.map} +0 -0
  88. package/lib/module/models/PrimerTheme.js +2 -0
  89. package/lib/module/{headless_checkout/types.js.map → models/PrimerTheme.js.map} +0 -0
  90. package/lib/module/utils/index.js.map +1 -1
  91. package/lib/typescript/Primer.d.ts +2 -15
  92. package/lib/typescript/RNPrimer.d.ts +16 -9
  93. package/lib/typescript/index.d.ts +9 -5
  94. package/lib/typescript/models/Primer.d.ts +26 -0
  95. package/lib/typescript/models/PrimerCheckoutData.d.ts +15 -0
  96. package/lib/typescript/models/PrimerCheckoutPaymentMethodData.d.ts +5 -0
  97. package/lib/typescript/models/PrimerClientSession.d.ts +45 -0
  98. package/lib/typescript/models/{utils/countryCode.d.ts → PrimerCountryCode.d.ts} +1 -1
  99. package/lib/typescript/models/{utils/currencyCode.d.ts → PrimerCurrencyCode.d.ts} +1 -1
  100. package/lib/typescript/models/PrimerError.d.ts +11 -0
  101. package/lib/typescript/models/PrimerPaymentMethodTokenData.d.ts +116 -0
  102. package/lib/typescript/models/PrimerSessionIntent.d.ts +4 -0
  103. package/lib/typescript/models/PrimerSettings.d.ts +73 -0
  104. package/lib/typescript/models/{primer-theme.d.ts → PrimerTheme.d.ts} +1 -1
  105. package/lib/typescript/utils/index.d.ts +1 -1
  106. package/package.json +1 -1
  107. package/primer-io-react-native.podspec +1 -1
  108. package/src/Primer.ts +228 -172
  109. package/src/RNPrimer.ts +135 -51
  110. package/src/index.tsx +33 -7
  111. package/src/models/Primer.ts +35 -0
  112. package/src/models/PrimerCheckoutData.ts +18 -0
  113. package/src/models/PrimerCheckoutPaymentMethodData.ts +5 -0
  114. package/src/models/PrimerClientSession.ts +53 -0
  115. package/src/models/{utils/countryCode.ts → PrimerCountryCode.ts} +1 -1
  116. package/src/models/{utils/currencyCode.ts → PrimerCurrencyCode.ts} +1 -1
  117. package/src/models/PrimerError.ts +20 -0
  118. package/src/models/PrimerPaymentMethodTokenData.ts +130 -0
  119. package/src/models/PrimerSessionIntent.ts +4 -0
  120. package/src/models/PrimerSettings.ts +93 -0
  121. package/src/models/{primer-theme.ts → PrimerTheme.ts} +1 -1
  122. package/src/utils/index.ts +1 -1
  123. package/android/src/main/java/com/primerioreactnative/PrimerCardNumberEditTextManager.kt +0 -83
  124. package/android/src/main/java/com/primerioreactnative/PrimerHeadlessUniversalCheckout.kt +0 -198
  125. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerEventsRN.kt +0 -11
  126. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerIntentRN.kt +0 -80
  127. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerOnClientSessionActionsRequestRN.kt +0 -65
  128. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerRequestRN.kt +0 -9
  129. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerThemeRN.kt +0 -51
  130. package/android/src/main/java/com/primerioreactnative/huc/assets/AssetsManager.kt +0 -56
  131. package/android/src/main/java/com/primerioreactnative/huc/events/PrimerHeadlessUniversalCheckoutEvent.kt +0 -11
  132. package/android/src/main/java/com/primerioreactnative/huc/extensions/Map.kt +0 -10
  133. package/android/src/main/java/com/primerioreactnative/utils/Keys.kt +0 -7
  134. package/android/src/main/java/com/primerioreactnative/utils/PrimerEventQueueRN.kt +0 -30
  135. package/ios/DataModels/PrimerIntentRN.swift +0 -10
  136. package/ios/DataModels/PrimerRequestRN.swift +0 -14
  137. package/ios/Headless Universal Checkout/RNTPrimerCardNumberInputElementManager.m +0 -23
  138. package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckout.m +0 -30
  139. package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckout.swift +0 -241
  140. package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.m +0 -14
  141. package/ios/Headless Universal Checkout/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.swift +0 -113
  142. package/lib/commonjs/PrimerInput.js +0 -80
  143. package/lib/commonjs/PrimerInput.js.map +0 -1
  144. package/lib/commonjs/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js +0 -14
  145. package/lib/commonjs/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js.map +0 -1
  146. package/lib/commonjs/headless_checkout/NativePrimerHeadlessUniversalCheckout.js +0 -110
  147. package/lib/commonjs/headless_checkout/NativePrimerHeadlessUniversalCheckout.js.map +0 -1
  148. package/lib/commonjs/headless_checkout/PrimerHeadlessUniversalCheckout.js +0 -117
  149. package/lib/commonjs/headless_checkout/PrimerHeadlessUniversalCheckout.js.map +0 -1
  150. package/lib/commonjs/headless_checkout/types.js +0 -2
  151. package/lib/commonjs/models/action-request.js +0 -2
  152. package/lib/commonjs/models/client-session-actions-request.js +0 -2
  153. package/lib/commonjs/models/payment-instrument-token.js +0 -30
  154. package/lib/commonjs/models/payment-instrument-token.js.map +0 -1
  155. package/lib/commonjs/models/primer-callbacks.js +0 -6
  156. package/lib/commonjs/models/primer-error.js +0 -4
  157. package/lib/commonjs/models/primer-error.js.map +0 -1
  158. package/lib/commonjs/models/primer-intent.js +0 -4
  159. package/lib/commonjs/models/primer-intent.js.map +0 -1
  160. package/lib/commonjs/models/primer-request.js +0 -2
  161. package/lib/commonjs/models/primer-settings.js +0 -6
  162. package/lib/commonjs/models/primer-theme.js +0 -2
  163. package/lib/commonjs/models/utils/countryCode.js.map +0 -1
  164. package/lib/commonjs/models/utils/currencyCode.js.map +0 -1
  165. package/lib/commonjs/models/utils/redirectScheme.js +0 -4
  166. package/lib/commonjs/models/utils/redirectScheme.js.map +0 -1
  167. package/lib/module/PrimerInput.js +0 -46
  168. package/lib/module/PrimerInput.js.map +0 -1
  169. package/lib/module/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js +0 -5
  170. package/lib/module/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.js.map +0 -1
  171. package/lib/module/headless_checkout/NativePrimerHeadlessUniversalCheckout.js +0 -98
  172. package/lib/module/headless_checkout/NativePrimerHeadlessUniversalCheckout.js.map +0 -1
  173. package/lib/module/headless_checkout/PrimerHeadlessUniversalCheckout.js +0 -100
  174. package/lib/module/headless_checkout/PrimerHeadlessUniversalCheckout.js.map +0 -1
  175. package/lib/module/headless_checkout/types.js +0 -2
  176. package/lib/module/models/action-request.js +0 -2
  177. package/lib/module/models/action-request.js.map +0 -1
  178. package/lib/module/models/client-session-actions-request.js +0 -2
  179. package/lib/module/models/client-session-actions-request.js.map +0 -1
  180. package/lib/module/models/payment-instrument-token.js +0 -28
  181. package/lib/module/models/payment-instrument-token.js.map +0 -1
  182. package/lib/module/models/primer-callbacks.js +0 -2
  183. package/lib/module/models/primer-callbacks.js.map +0 -1
  184. package/lib/module/models/primer-config.js +0 -2
  185. package/lib/module/models/primer-config.js.map +0 -1
  186. package/lib/module/models/primer-error.js +0 -2
  187. package/lib/module/models/primer-error.js.map +0 -1
  188. package/lib/module/models/primer-intent.js +0 -2
  189. package/lib/module/models/primer-intent.js.map +0 -1
  190. package/lib/module/models/primer-request.js +0 -2
  191. package/lib/module/models/primer-request.js.map +0 -1
  192. package/lib/module/models/primer-settings.js +0 -2
  193. package/lib/module/models/primer-settings.js.map +0 -1
  194. package/lib/module/models/primer-theme.js +0 -2
  195. package/lib/module/models/primer-theme.js.map +0 -1
  196. package/lib/module/models/primer.js +0 -2
  197. package/lib/module/models/primer.js.map +0 -1
  198. package/lib/module/models/utils/countryCode.js.map +0 -1
  199. package/lib/module/models/utils/currencyCode.js.map +0 -1
  200. package/lib/module/models/utils/redirectScheme.js +0 -2
  201. package/lib/module/models/utils/redirectScheme.js.map +0 -1
  202. package/lib/typescript/PrimerInput.d.ts +0 -15
  203. package/lib/typescript/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.d.ts +0 -1
  204. package/lib/typescript/headless_checkout/NativePrimerHeadlessUniversalCheckout.d.ts +0 -13
  205. package/lib/typescript/headless_checkout/PrimerHeadlessUniversalCheckout.d.ts +0 -13
  206. package/lib/typescript/headless_checkout/types.d.ts +0 -16
  207. package/lib/typescript/models/action-request.d.ts +0 -10
  208. package/lib/typescript/models/client-session-actions-request.d.ts +0 -15
  209. package/lib/typescript/models/payment-instrument-token.d.ts +0 -76
  210. package/lib/typescript/models/primer-callbacks.d.ts +0 -10
  211. package/lib/typescript/models/primer-config.d.ts +0 -44
  212. package/lib/typescript/models/primer-error.d.ts +0 -8
  213. package/lib/typescript/models/primer-intent.d.ts +0 -13
  214. package/lib/typescript/models/primer-request.d.ts +0 -7
  215. package/lib/typescript/models/primer-settings.d.ts +0 -65
  216. package/lib/typescript/models/primer.d.ts +0 -33
  217. package/lib/typescript/models/utils/redirectScheme.d.ts +0 -3
  218. package/src/PrimerInput.tsx +0 -73
  219. package/src/RNTPrimerHeadlessUniversalCheckoutCardFormUIManager.tsx +0 -2
  220. package/src/headless_checkout/NativePrimerHeadlessUniversalCheckout.ts +0 -132
  221. package/src/headless_checkout/PrimerHeadlessUniversalCheckout.ts +0 -140
  222. package/src/headless_checkout/types.ts +0 -18
  223. package/src/models/action-request.ts +0 -12
  224. package/src/models/client-session-actions-request.ts +0 -21
  225. package/src/models/payment-instrument-token.ts +0 -109
  226. package/src/models/primer-callbacks.ts +0 -14
  227. package/src/models/primer-config.ts +0 -55
  228. package/src/models/primer-error.ts +0 -19
  229. package/src/models/primer-intent.ts +0 -49
  230. package/src/models/primer-request.ts +0 -7
  231. package/src/models/primer-settings.ts +0 -73
  232. package/src/models/primer.ts +0 -41
  233. package/src/models/utils/redirectScheme.ts +0 -5
package/README.md CHANGED
@@ -10,49 +10,139 @@ Official React Native SDK plugin for [Primer](https://primer.io)
10
10
  <img src="https://img.shields.io/npm/v/@primer-io/react-native" />
11
11
  </p>
12
12
 
13
- ---
13
+ **Note:** This quick start guide addresses the platform-specific integration points only. As everything prior to that (e.g. creating a client token) is the same for all the guidelines.
14
14
 
15
- The simplest payments integration, ever. Integrate payments once with just a few lines of code, and empower ops teams to automate complex business logic with Primer.
15
+ # Set up the Universal Checkout
16
16
 
17
- ### Features of the React Native SDK
17
+ ## Step 1. Install the SDK
18
18
 
19
- - 💳 Create great payment experiences with our Universal Checkout
19
+ Add the SDK package.
20
20
 
21
- - 🧩 Connect and configure new payment methods with only a few lines of code
21
+ ```sh
22
+ \# With yarn
23
+ yarn add @primer-io/react-native
24
+
25
+ \# With npm
26
+ npm i @primer-io/react-native --save
27
+ ```
28
+
29
+ Once you are done, navigate to the \/ios folder and run pod install.
22
30
 
23
- - Dynamically handle 3DS 2.0 across processors and be SCA ready
31
+ ## Step 2. Initialize the SDK
24
32
 
25
- - ♻️ Store payment methods for one-click checkout, recurring and repeat payments
33
+ Import the Primer SDK, construct your settings and call the SDK’s configure function.
26
34
 
27
- - 🔒 Always PCI compliant without redirecting customers
35
+ ```js
36
+ import * as React from 'react';
37
+ import {
38
+ Primer,
39
+ PrimerSettings,
40
+ PrimerCheckoutData
41
+ } from '@primer-io/react-native';
42
+
43
+ const CheckoutScreen = (props: any) => {
44
+
45
+ const onCheckoutComplete = (checkoutData: PrimerCheckoutData) => {
46
+ // Perform an action based on the payment creation response
47
+ // ex. show success screen, redirect to order confirmation view, etc.
48
+ };
49
+
50
+ React.useEffect(() => {
51
+ const settings: PrimerSettings = {
52
+ onCheckoutComplete: onCheckoutComplete
53
+ };
54
+
55
+ Primer.configure(settings)
56
+ .then(() => {
57
+ // SDK is initialized sucessfully
58
+ })
59
+ .catch (err => {
60
+ // SDK failed to initialize
61
+ })
62
+ }, []);
63
+ }
64
+ ```
28
65
 
29
- ---
66
+ ## Step 3. Generate a client token
30
67
 
31
- ## 💾 Installation
68
+ **Note:** Check our guide on how to set up the client session [here](https://primer.io/docs/accept-payments/manage-client-sessions).
32
69
 
33
- ```sh
34
- npm i @primer-io/react-native
70
+ Make an API call to your backend to fetch a Client Token. Here is a simple example of how it can be done from your component. Once successful store your Client Token for future use.
71
+
72
+ ```js
73
+ const CheckoutScreen = (props: any) => {
74
+
75
+ // ...
76
+
77
+ const onUniversalCheckoutButtonTapped = async () => {
78
+ try {
79
+ // Make an API request to your backend to create a client session
80
+ // and fetch a client token.
81
+ const clientToken = await createClientSession(clientSessionRequestParams);
82
+ } catch (err) {
83
+ // ...
84
+ }
85
+ };
86
+ }
35
87
  ```
36
88
 
37
- ## 🔧 Usage
89
+ ## Step 4. Show Universal Checkout
90
+
91
+ At this step, you should have a Client Token available. Call the `showUniversalCheckout(clientToken)` function, with the Client Token (as shown below) to present Universal Checkout.
38
92
 
39
93
  ```js
40
- import { Primer } from '@primer-io/react-native';
94
+ const CheckoutScreen = (props: any) => {
41
95
 
42
- // fetch Primer client token from backend.
43
- const token: string = await fetchClientToken();
96
+ // ...
44
97
 
45
- // configure listeners and settings.
46
- const onTokenizeSuccess = async (t, handler) => {
47
- const payment = await createPayment(t);
48
- handler.handleSuccess(); // resume the checkout flow with success message.
49
- };
98
+ const onUniversalCheckoutButtonTapped = async () => {
99
+ try {
100
+ // ...
50
101
 
51
- // show Universal Checkout with client token and config.
52
- Primer.showUniversalCheckout(token, { onTokenizeSuccess });
102
+ // Present Universal Checkout
103
+ await Primer.showUniversalCheckout(clientToken);
104
+ } catch (err) {
105
+ // ...
106
+ }
107
+ };
108
+ }
53
109
  ```
54
110
 
55
- For more info & help troubleshooting, check out our 🔥 [docs](https://www.notion.so/primerio/Quick-Start-6c5eb61e5bbe426ca66244259e06048e)
111
+ ## Full Code Snippet
112
+
113
+ ```js
114
+ import * as React from 'react';
115
+ import {
116
+ Primer,
117
+ PrimerSettings,
118
+ PrimerCheckoutData
119
+ } from '@primer-io/react-native';
120
+
121
+ const CheckoutScreen = async (props: any) => {
122
+ const onCheckoutComplete = (checkoutData: PrimerCheckoutData) => {
123
+ // Show a success screen
124
+ };
125
+
126
+ const onUniversalCheckoutButtonTapped = async () => {
127
+ const settings: PrimerSettings = {
128
+ onCheckoutComplete: onCheckoutComplete
129
+ };
130
+
131
+ // Configure the SDK
132
+ await Primer.configure(settings);
133
+
134
+ // Ask your backend to create a client session
135
+ const clientToken = await createClientSession(clientSessionRequestParams);
136
+
137
+ // Present Universal Checkout
138
+ await Primer.showUniversalCheckout(clientToken);
139
+ };
140
+ }
141
+ ```
142
+
143
+ You should now be able to see Universal Checkout! The user can now interact with Universal Checkout, and the SDK will create the payment. The payment’s data will be returned in the onCheckoutComplete callback configured in Step 2.
144
+
145
+ **Note:** For more info & help troubleshooting, check out our [docs](http://primer.io/docs).
56
146
 
57
147
  ## 📚 License
58
148
 
@@ -4,6 +4,7 @@ buildscript {
4
4
 
5
5
  repositories {
6
6
  google()
7
+ mavenLocal()
7
8
  jcenter()
8
9
  }
9
10
 
@@ -37,6 +38,9 @@ android {
37
38
  }
38
39
 
39
40
  buildTypes {
41
+ debug {
42
+ consumerProguardFiles 'consumer-rules.pro'
43
+ }
40
44
  release {
41
45
  consumerProguardFiles 'consumer-rules.pro'
42
46
  minifyEnabled false
@@ -49,9 +53,13 @@ android {
49
53
  sourceCompatibility JavaVersion.VERSION_1_8
50
54
  targetCompatibility JavaVersion.VERSION_1_8
51
55
  }
56
+ kotlinOptions {
57
+ freeCompilerArgs += '-Xjvm-default=all'
58
+ }
52
59
  }
53
60
 
54
61
  repositories {
62
+ mavenLocal()
55
63
  mavenCentral()
56
64
  jcenter()
57
65
  google()
@@ -128,6 +136,6 @@ dependencies {
128
136
  // noinspection GradleDynamicVersion
129
137
  api 'com.facebook.react:react-native:+'
130
138
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
131
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1"
132
- implementation 'io.primer:android:1.15.0'
139
+ implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3"
140
+ implementation 'io.primer:android:2.0.1'
133
141
  }
@@ -1,4 +1,4 @@
1
- ReactNative_kotlinVersion=1.5.0
2
- ReactNative_compileSdkVersion=29
1
+ ReactNative_kotlinVersion=1.6.21
2
+ ReactNative_compileSdkVersion=31
3
3
  ReactNative_buildToolsVersion=29.0.2
4
- ReactNative_targetSdkVersion=29
4
+ ReactNative_targetSdkVersion=31
@@ -4,80 +4,49 @@ import android.util.Log
4
4
  import com.facebook.react.bridge.*
5
5
  import com.facebook.react.modules.core.DeviceEventManagerModule
6
6
  import com.primerioreactnative.datamodels.*
7
- import com.primerioreactnative.utils.Keys
8
7
  import com.primerioreactnative.utils.PrimerImplementedRNCallbacks
8
+ import com.primerioreactnative.utils.convertJsonToMap
9
9
  import com.primerioreactnative.utils.errorTo
10
- import io.primer.android.PaymentMethodIntent
11
10
  import io.primer.android.Primer
12
- import io.primer.android.model.dto.PrimerConfig
13
- import io.primer.android.model.dto.PrimerPaymentMethod
14
- import io.primer.android.model.dto.PrimerPaymentMethodType
11
+ import io.primer.android.PrimerSessionIntent
12
+ import io.primer.android.data.configuration.models.PrimerPaymentMethodType
13
+ import io.primer.android.data.settings.PrimerSettings
15
14
  import kotlinx.serialization.decodeFromString
16
15
  import kotlinx.serialization.encodeToString
17
16
  import kotlinx.serialization.json.Json
18
17
  import org.json.JSONObject
19
18
 
20
- class PrimerRN(reactContext: ReactApplicationContext) :
21
- ReactContextBaseJavaModule(reactContext) {
22
-
23
- private var settings: PrimerSettingsRN = PrimerSettingsRN()
24
- private var theme: PrimerThemeRN = PrimerThemeRN()
25
- private var intent: PaymentMethodIntent? = null
26
- private var paymentMethod: PrimerPaymentMethod? = null
27
-
19
+ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
28
20
  private var mListener = PrimerRNEventListener()
29
-
30
- private var sdkWasInitialised = false
31
-
32
21
  private val json = Json { ignoreUnknownKeys = true }
33
22
 
34
23
  init {
35
24
  mListener.sendEvent = { eventName, paramsJson -> sendEvent(eventName, paramsJson) }
36
- mListener.sendError = { paramsJson -> checkoutFailed(paramsJson) }
25
+ mListener.sendError = { paramsJson -> onError(paramsJson) }
26
+ mListener.sendErrorWithCheckoutData =
27
+ { paramsJson, checkoutData -> onError(paramsJson, checkoutData) }
37
28
  }
38
29
 
39
30
  override fun getName(): String = "NativePrimer"
40
31
 
41
32
  @ReactMethod
42
- fun configureWithSettings(settingsStr: String, promise: Promise) {
33
+ fun configure(settingsStr: String, promise: Promise) {
43
34
  try {
44
35
  Log.d("PrimerRN", "settings: $settingsStr")
45
- val settings = json.decodeFromString<PrimerSettingsRN>(settingsStr)
46
- this.settings = settings
47
- startSdk()
36
+ val settings =
37
+ if (settingsStr.isBlank()) PrimerSettingsRN() else json.decodeFromString(
38
+ settingsStr
39
+ )
40
+ startSdk(settings.toPrimerSettings())
48
41
  promise.resolve(null)
49
42
  } catch (e: Exception) {
50
43
  Log.e("PrimerRN", "configure settings error: $e")
51
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "failed to parse settings."
52
- checkoutFailed(exception)
53
- promise.reject(exception.errorId, exception.errorDescription, e)
44
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo "failed to parse settings."
45
+ onError(exception)
46
+ promise.reject(exception.errorId, exception.description, e)
54
47
  }
55
48
  }
56
49
 
57
- @ReactMethod
58
- fun configureWithTheme(themeStr: String, promise: Promise) {
59
- try {
60
- Log.d("PrimerRN", "theme: $themeStr")
61
- val theme = json.decodeFromString<PrimerThemeRN>(themeStr)
62
- this.theme = theme
63
- startSdk()
64
- promise.resolve(null)
65
- } catch (e: Exception) {
66
- Log.e("PrimerRN", "configure theme error: $e")
67
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "failed to parse theme."
68
- checkoutFailed(exception)
69
- promise.reject(exception.errorId, exception.errorDescription, e)
70
- }
71
- }
72
-
73
- @ReactMethod
74
- fun showUniversalCheckout(promise: Promise) {
75
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
76
- "This method is deprecated. Use the new showUniversalCheckoutWithClientToken method"
77
- checkoutFailed(exception)
78
- promise.reject(exception.errorId, exception.errorDescription)
79
- }
80
-
81
50
  @ReactMethod
82
51
  fun showUniversalCheckoutWithClientToken(
83
52
  clientToken: String,
@@ -87,62 +56,54 @@ class PrimerRN(reactContext: ReactApplicationContext) :
87
56
  Primer.instance.showUniversalCheckout(reactApplicationContext.applicationContext, clientToken)
88
57
  promise.resolve(null)
89
58
  } catch (e: Exception) {
90
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
59
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo
91
60
  "Primer SDK failed: ${e.message}"
92
- checkoutFailed(exception)
93
- promise.reject(exception.errorId, exception.errorDescription, e)
61
+ onError(exception)
62
+ promise.reject(exception.errorId, exception.description, e)
94
63
  }
95
64
  }
96
65
 
97
66
  @ReactMethod
98
- fun showVaultManager(promise: Promise) {
99
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
100
- "This method is deprecated. Use the new showUniversalCheckoutWithClientToken method"
101
- checkoutFailed(exception)
102
- promise.reject(exception.errorId, exception.errorDescription)
103
- }
104
-
105
- @ReactMethod
106
- fun showVaultManager(clientToken: String, promise: Promise) {
67
+ fun showVaultManagerWithClientToken(clientToken: String, promise: Promise) {
107
68
  try {
108
69
  Primer.instance.showVaultManager(reactApplicationContext.applicationContext, clientToken)
109
70
  promise.resolve(null)
110
71
  } catch (e: Exception) {
111
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
72
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo
112
73
  "Primer SDK failed: ${e.message}"
113
- checkoutFailed(exception)
114
- promise.reject(exception.errorId, exception.errorDescription, e)
74
+ onError(exception)
75
+ promise.reject(exception.errorId, exception.description, e)
115
76
  }
116
77
  }
117
78
 
118
79
  @ReactMethod
119
80
  fun showPaymentMethod(
120
- clientToken: String,
121
81
  paymentMethodTypeStr: String,
122
82
  intentStr: String,
83
+ clientToken: String,
123
84
  promise: Promise
124
85
  ) {
86
+ val intent: PrimerSessionIntent
125
87
  try {
126
- this.intent = PaymentMethodIntent.valueOf(intentStr.uppercase())
88
+ intent = PrimerSessionIntent.valueOf(intentStr.uppercase())
127
89
  } catch (e: Exception) {
128
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "failed to parse intent."
129
- checkoutFailed(exception)
130
- promise.reject(exception.errorId, exception.errorDescription, e)
90
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo "Intent $intentStr is not valid."
91
+ onError(exception)
92
+ promise.reject(exception.errorId, exception.description, e)
131
93
  return
132
94
  }
95
+ val paymentMethod: PrimerPaymentMethodType
133
96
  try {
134
- val paymentMethod = getPrimerPaymentMethod(paymentMethodTypeStr)
135
- this.paymentMethod = paymentMethod
97
+ paymentMethod = getPrimerPaymentMethod(paymentMethodTypeStr)
136
98
  } catch (e: Exception) {
137
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo "failed to parse payment method type."
138
- checkoutFailed(exception)
139
- promise.reject(exception.errorId, exception.errorDescription, e)
99
+ val exception =
100
+ ErrorTypeRN.NativeBridgeFailed errorTo "Payment method type $paymentMethodTypeStr is not valid."
101
+ onError(exception)
102
+ promise.reject(exception.errorId, exception.description, e)
140
103
  return
141
104
  }
142
105
 
143
106
  try {
144
- val paymentMethod = this.paymentMethod ?: return
145
- val intent = this.intent ?: return
146
107
  Primer.instance.showPaymentMethod(
147
108
  reactApplicationContext.applicationContext,
148
109
  clientToken,
@@ -151,59 +112,80 @@ class PrimerRN(reactContext: ReactApplicationContext) :
151
112
  )
152
113
  promise.resolve(null)
153
114
  } catch (e: Exception) {
154
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
115
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo
155
116
  "Primer SDK failed: ${e.message}"
156
- checkoutFailed(exception)
157
- promise.reject(exception.errorId, exception.errorDescription, e)
117
+ onError(exception)
118
+ promise.reject(exception.errorId, exception.description, e)
158
119
  }
159
120
  }
160
121
 
161
122
  @ReactMethod
162
- fun handleNewClientToken(clientToken: String, promise: Promise) {
163
- mListener.onClientTokenCallback(clientToken, null)
164
- mListener.onClientSessionActions(clientToken, null)
165
- mListener.onTokenizeSuccess(clientToken, null)
166
- mListener.onResumeSuccess(clientToken, null)
167
- removeCallbacksAndHandlers()
123
+ fun dismiss(promise: Promise) {
124
+ Primer.instance.dismiss()
168
125
  promise.resolve(null)
169
126
  }
170
127
 
128
+ // region tokenization handlers
171
129
  @ReactMethod
172
- fun handleError(errorStr: String, promise: Promise) {
173
- try {
174
- val err = json.decodeFromString<PrimerErrorRN>(errorStr)
175
- mListener.onClientTokenCallback(null, err)
176
- mListener.onClientSessionActions(null, err)
177
- mListener.onTokenizeSuccess(null, err)
178
- mListener.onResumeSuccess(null, err)
179
- removeCallbacksAndHandlers()
180
- promise.resolve(null)
181
- } catch (e: Exception) {
182
- val exception = PrimerErrorRN(
183
- ErrorTypeRN.CheckoutFlowFailed.name,
184
- "Primer SDK failed: ${e.message}"
185
- )
186
- checkoutFailed(exception)
187
- promise.reject(exception.errorId, exception.errorDescription, e)
188
- }
130
+ fun handleTokenizationNewClientToken(newClientToken: String, promise: Promise) {
131
+ mListener.handleTokenizationNewClientToken(newClientToken)
132
+ promise.resolve(null)
189
133
  }
190
134
 
191
135
  @ReactMethod
192
- fun handleSuccess(promise: Promise) {
193
- try {
194
- mListener.onClientTokenCallback(null, null)
195
- mListener.onClientSessionActions(null, null)
196
- mListener.onTokenizeSuccess(null, null)
197
- mListener.onResumeSuccess(null, null)
198
- removeCallbacksAndHandlers()
199
- promise.resolve(null)
200
- } catch (e: Exception) {
201
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
202
- "Primer SDK failed: ${e.message}"
203
- checkoutFailed(exception)
204
- promise.reject(exception.errorId, exception.errorDescription, e)
205
- }
136
+ fun handleTokenizationSuccess(promise: Promise) {
137
+ mListener.handleTokenizationSuccess()
138
+ promise.resolve(null)
139
+ }
140
+
141
+ @ReactMethod
142
+ fun handleTokenizationFailure(errorMessage: String?, promise: Promise) {
143
+ mListener.handleTokenizationFailure(errorMessage.orEmpty())
144
+ promise.resolve(null)
145
+ }
146
+ // endregion
147
+
148
+ // region resume handlers
149
+ @ReactMethod
150
+ fun handleResumeNewClientToken(newClientToken: String, promise: Promise) {
151
+ mListener.handleResumeNewClientToken(newClientToken)
152
+ promise.resolve(null)
153
+ }
154
+
155
+ @ReactMethod
156
+ fun handleResumeSuccess(promise: Promise) {
157
+ mListener.handleResumeSuccess()
158
+ promise.resolve(null)
159
+ }
160
+
161
+ @ReactMethod
162
+ fun handleResumeFailure(errorMessage: String?, promise: Promise) {
163
+ mListener.handleResumeFailure(errorMessage.orEmpty())
164
+ promise.resolve(null)
165
+ }
166
+ // endregion
167
+
168
+ // region payment handlers
169
+ @ReactMethod
170
+ fun handlePaymentCreationContinue(promise: Promise) {
171
+ mListener.handlePaymentCreationContinue()
172
+ promise.resolve(null)
173
+ }
174
+
175
+ @ReactMethod
176
+ fun handlePaymentCreationAbort(errorMessage: String?, promise: Promise) {
177
+ mListener.handlePaymentCreationAbort(errorMessage.orEmpty())
178
+ promise.resolve(null)
179
+ }
180
+ // endregion
181
+
182
+ // region error handlers
183
+ @ReactMethod
184
+ fun showErrorMessage(errorMessage: String?, promise: Promise) {
185
+ mListener.handleErrorMessage(errorMessage.orEmpty())
186
+ promise.resolve(null)
206
187
  }
188
+ // endregion
207
189
 
208
190
  @ReactMethod
209
191
  fun setImplementedRNCallbacks(implementedRNCallbacksStr: String, promise: Promise) {
@@ -214,32 +196,28 @@ class PrimerRN(reactContext: ReactApplicationContext) :
214
196
  this.mListener.setImplementedCallbacks(implementedRNCallbacks)
215
197
  promise.resolve(null)
216
198
  } catch (e: Exception) {
217
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "Failed to parse implemented callbacks"
218
- checkoutFailed(exception)
219
- promise.reject(exception.errorId, exception.errorDescription, e)
199
+ val exception =
200
+ ErrorTypeRN.NativeBridgeFailed errorTo "Implemented callbacks $implementedRNCallbacksStr is not valid."
201
+ onError(exception)
202
+ promise.reject(exception.errorId, exception.description, e)
220
203
  }
221
204
  }
222
205
 
223
- private fun removeCallbacksAndHandlers() {
224
- mListener.removeCallbacksAndHandlers()
206
+ private fun startSdk(settings: PrimerSettings) {
207
+ Primer.instance.configure(settings, mListener)
225
208
  }
226
209
 
227
- private fun startSdk() {
228
- val theme = theme.format()
229
- val settings = settings.format()
230
- val config = PrimerConfig(theme, settings)
231
-
232
- Primer.instance.configure(config, mListener)
233
- sdkWasInitialised = true
234
- }
235
-
236
- private fun checkoutFailed(exception: PrimerErrorRN) {
210
+ private fun onError(exception: PrimerErrorRN, checkoutDataRN: PrimerCheckoutDataRN? = null) {
237
211
  val params = Arguments.createMap()
238
212
  val errorJson = JSONObject(Json.encodeToString(exception))
239
- val data = Arguments.createMap()
240
- prepareData(data, errorJson)
241
- params.putMap(Keys.ERROR, data)
242
- sendEvent(PrimerEventsRN.OnError.string, params)
213
+ val errorData = prepareData(errorJson)
214
+ params.putMap(Keys.ERROR, errorData)
215
+ checkoutDataRN?.let {
216
+ val checkoutDataJson = JSONObject(Json.encodeToString(it))
217
+ val checkoutData = prepareData(checkoutDataJson)
218
+ params.putMap(Keys.CHECKOUT_DATA, checkoutData)
219
+ }
220
+ sendEvent(PrimerEvents.ON_ERROR.eventName, params)
243
221
  }
244
222
 
245
223
  private fun sendEvent(name: String, params: WritableMap) {
@@ -249,31 +227,27 @@ class PrimerRN(reactContext: ReactApplicationContext) :
249
227
  }
250
228
 
251
229
  private fun sendEvent(name: String, data: JSONObject?) {
252
- val params = Arguments.createMap()
253
- prepareData(params, data)
230
+ val params = prepareData(data)
254
231
  reactApplicationContext.getJSModule(
255
232
  DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
256
233
  ).emit(name, params)
257
234
  }
258
235
 
259
- private fun prepareData(params: WritableMap, data: JSONObject?) {
260
- data?.keys()?.forEach { key ->
261
- when (val dataValue = data.opt(key)) {
262
- is String -> params.putString(key, dataValue)
263
- is Boolean -> params.putBoolean(key, dataValue)
264
- is Double -> params.putDouble(key, dataValue)
265
- is Int -> params.putInt(key, dataValue)
266
- is JSONObject -> prepareData(params, dataValue)
267
- else -> params.putNull(key)
268
- }
269
- }
236
+ private fun prepareData(data: JSONObject?): WritableMap {
237
+ return data?.let { convertJsonToMap(data) } ?: Arguments.createMap()
270
238
  }
271
239
 
272
- private fun getPrimerPaymentMethod(paymentMethodTypeStr: String): PrimerPaymentMethod {
240
+ private fun getPrimerPaymentMethod(paymentMethodTypeStr: String): PrimerPaymentMethodType {
273
241
  if (PrimerPaymentMethodType.PAYMENT_CARD.name == paymentMethodTypeStr) {
274
- return PrimerPaymentMethod.CARD
242
+ return PrimerPaymentMethodType.PAYMENT_CARD
275
243
  }
276
244
 
277
- return PrimerPaymentMethod.valueOf(paymentMethodTypeStr)
245
+ return PrimerPaymentMethodType.valueOf(paymentMethodTypeStr)
278
246
  }
279
247
  }
248
+
249
+ internal object Keys {
250
+ const val ERROR = "error"
251
+ const val RESUME_TOKEN = "resumeToken"
252
+ const val CHECKOUT_DATA = "checkoutData"
253
+ }