@primer-io/react-native 0.15.8 → 2.0.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 (203) hide show
  1. package/README.md +114 -24
  2. package/android/build.gradle +7 -2
  3. package/android/gradle.properties +3 -3
  4. package/android/src/main/java/com/primerioreactnative/PrimerRN.kt +118 -148
  5. package/android/src/main/java/com/primerioreactnative/PrimerRNEventListener.kt +212 -127
  6. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerCheckoutDataRN.kt +12 -0
  7. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerClientSessionRN.kt +54 -0
  8. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerErrorRN.kt +3 -7
  9. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerEvents.kt +13 -0
  10. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerPaymentInstrumentTokenRN.kt +4 -4
  11. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerPaymentMethodDataRN.kt +8 -0
  12. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerSettingsRN.kt +43 -125
  13. package/android/src/main/java/com/primerioreactnative/extensions/Payment.kt +6 -0
  14. package/android/src/main/java/com/primerioreactnative/extensions/PrimerAddress.kt +15 -0
  15. package/android/src/main/java/com/primerioreactnative/extensions/PrimerCheckoutData.kt +7 -0
  16. package/android/src/main/java/com/primerioreactnative/extensions/PrimerClientSession.kt +15 -0
  17. package/android/src/main/java/com/primerioreactnative/extensions/PrimerCustomer.kt +13 -0
  18. package/android/src/main/java/com/primerioreactnative/extensions/PrimerLineItem.kt +8 -0
  19. package/android/src/main/java/com/primerioreactnative/extensions/PrimerOrder.kt +6 -0
  20. package/android/src/main/java/com/primerioreactnative/extensions/PrimerPaymentMethodData.kt +7 -0
  21. package/android/src/main/java/com/primerioreactnative/utils/ErrorHelper.kt +1 -3
  22. package/android/src/main/java/com/primerioreactnative/utils/JsonConverter.kt +45 -0
  23. package/android/src/main/java/com/primerioreactnative/utils/PrimerImplementedRNCallbacks.kt +16 -6
  24. package/ios/DataModels/ImplementedRNCallbacks.swift +31 -0
  25. package/ios/DataModels/PrimerErrorRN.swift +0 -17
  26. package/ios/DataModels/PrimerSettingsRN.swift +70 -147
  27. package/ios/DataModels/PrimerThemeRN.swift +1 -10
  28. package/ios/{Pods/Manifest.lock → Podfile.lock} +1 -1
  29. package/ios/RNTPrimer.m +26 -12
  30. package/ios/RNTPrimer.swift +295 -249
  31. package/ios/ReactNative.xcodeproj/project.pbxproj +14 -14
  32. package/lib/commonjs/Primer.js +201 -150
  33. package/lib/commonjs/Primer.js.map +1 -1
  34. package/lib/commonjs/RNPrimer.js +102 -41
  35. package/lib/commonjs/RNPrimer.js.map +1 -1
  36. package/lib/commonjs/index.js +117 -4
  37. package/lib/commonjs/index.js.map +1 -1
  38. package/lib/commonjs/models/Primer.js +6 -0
  39. package/lib/commonjs/models/{action-request.js.map → Primer.js.map} +0 -0
  40. package/lib/commonjs/models/PrimerCheckoutData.js +9 -0
  41. package/lib/commonjs/models/PrimerCheckoutData.js.map +1 -0
  42. package/lib/commonjs/models/PrimerCheckoutPaymentMethodData.js +2 -0
  43. package/lib/commonjs/models/{client-session-actions-request.js.map → PrimerCheckoutPaymentMethodData.js.map} +0 -0
  44. package/lib/commonjs/models/PrimerClientSession.js +2 -0
  45. package/lib/commonjs/models/{primer-callbacks.js.map → PrimerClientSession.js.map} +0 -0
  46. package/lib/commonjs/models/{utils/countryCode.js → PrimerCountryCode.js} +1 -1
  47. package/lib/commonjs/models/PrimerCountryCode.js.map +1 -0
  48. package/lib/commonjs/models/{utils/currencyCode.js → PrimerCurrencyCode.js} +1 -1
  49. package/lib/commonjs/models/PrimerCurrencyCode.js.map +1 -0
  50. package/lib/commonjs/models/PrimerError.js +28 -0
  51. package/lib/commonjs/models/PrimerError.js.map +1 -0
  52. package/lib/commonjs/models/PrimerPaymentMethodTokenData.js +14 -0
  53. package/lib/commonjs/models/PrimerPaymentMethodTokenData.js.map +1 -0
  54. package/lib/commonjs/models/PrimerSessionIntent.js +14 -0
  55. package/lib/commonjs/models/PrimerSessionIntent.js.map +1 -0
  56. package/lib/commonjs/models/PrimerSettings.js +6 -0
  57. package/lib/commonjs/models/{primer-config.js.map → PrimerSettings.js.map} +0 -0
  58. package/lib/commonjs/models/PrimerTheme.js +2 -0
  59. package/lib/commonjs/models/{primer-request.js.map → PrimerTheme.js.map} +0 -0
  60. package/lib/commonjs/utils/index.js +1 -1
  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 -4
  67. package/lib/module/index.js.map +1 -1
  68. package/lib/module/models/Primer.js +2 -0
  69. package/lib/{commonjs/models/primer-settings.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-theme.js.map → module/models/PrimerCheckoutPaymentMethodData.js.map} +0 -0
  74. package/lib/module/models/PrimerClientSession.js +2 -0
  75. package/lib/{commonjs/models/primer.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/module/models/{action-request.js.map → PrimerSettings.js.map} +0 -0
  88. package/lib/module/models/PrimerTheme.js +2 -0
  89. package/lib/module/models/{client-session-actions-request.js.map → 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 -3
  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 -6
  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/datamodels/PrimerEventsRN.kt +0 -11
  124. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerIntentRN.kt +0 -80
  125. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerOnClientSessionActionsRequestRN.kt +0 -65
  126. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerRequestRN.kt +0 -9
  127. package/android/src/main/java/com/primerioreactnative/datamodels/PrimerThemeRN.kt +0 -51
  128. package/android/src/main/java/com/primerioreactnative/utils/PrimerEventQueueRN.kt +0 -30
  129. package/ios/DataModels/PrimerIntentRN.swift +0 -10
  130. package/ios/DataModels/PrimerRequestRN.swift +0 -14
  131. package/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -344
  132. package/ios/Pods/Pods.xcodeproj/xcuserdata/aladintaleb.xcuserdatad/xcschemes/Pods-ReactNative.xcscheme +0 -60
  133. package/ios/Pods/Pods.xcodeproj/xcuserdata/aladintaleb.xcuserdatad/xcschemes/xcschememanagement.plist +0 -16
  134. package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative-acknowledgements.markdown +0 -3
  135. package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative-acknowledgements.plist +0 -29
  136. package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative-dummy.m +0 -5
  137. package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative.debug.xcconfig +0 -8
  138. package/ios/Pods/Target Support Files/Pods-ReactNative/Pods-ReactNative.release.xcconfig +0 -8
  139. package/ios/ReactNative.xcworkspace/xcuserdata/aladintaleb.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  140. package/lib/commonjs/models/action-request.js +0 -2
  141. package/lib/commonjs/models/client-session-actions-request.js +0 -2
  142. package/lib/commonjs/models/payment-instrument-token.js +0 -30
  143. package/lib/commonjs/models/payment-instrument-token.js.map +0 -1
  144. package/lib/commonjs/models/primer-callbacks.js +0 -2
  145. package/lib/commonjs/models/primer-config.js +0 -2
  146. package/lib/commonjs/models/primer-error.js +0 -4
  147. package/lib/commonjs/models/primer-error.js.map +0 -1
  148. package/lib/commonjs/models/primer-intent.js +0 -4
  149. package/lib/commonjs/models/primer-intent.js.map +0 -1
  150. package/lib/commonjs/models/primer-request.js +0 -2
  151. package/lib/commonjs/models/primer-settings.js +0 -2
  152. package/lib/commonjs/models/primer-theme.js +0 -2
  153. package/lib/commonjs/models/primer.js +0 -2
  154. package/lib/commonjs/models/utils/countryCode.js.map +0 -1
  155. package/lib/commonjs/models/utils/currencyCode.js.map +0 -1
  156. package/lib/commonjs/models/utils/redirectScheme.js +0 -4
  157. package/lib/commonjs/models/utils/redirectScheme.js.map +0 -1
  158. package/lib/module/models/action-request.js +0 -2
  159. package/lib/module/models/client-session-actions-request.js +0 -2
  160. package/lib/module/models/payment-instrument-token.js +0 -28
  161. package/lib/module/models/payment-instrument-token.js.map +0 -1
  162. package/lib/module/models/primer-callbacks.js +0 -2
  163. package/lib/module/models/primer-callbacks.js.map +0 -1
  164. package/lib/module/models/primer-config.js +0 -2
  165. package/lib/module/models/primer-config.js.map +0 -1
  166. package/lib/module/models/primer-error.js +0 -2
  167. package/lib/module/models/primer-error.js.map +0 -1
  168. package/lib/module/models/primer-intent.js +0 -2
  169. package/lib/module/models/primer-intent.js.map +0 -1
  170. package/lib/module/models/primer-request.js +0 -2
  171. package/lib/module/models/primer-request.js.map +0 -1
  172. package/lib/module/models/primer-settings.js +0 -2
  173. package/lib/module/models/primer-settings.js.map +0 -1
  174. package/lib/module/models/primer-theme.js +0 -2
  175. package/lib/module/models/primer-theme.js.map +0 -1
  176. package/lib/module/models/primer.js +0 -2
  177. package/lib/module/models/primer.js.map +0 -1
  178. package/lib/module/models/utils/countryCode.js.map +0 -1
  179. package/lib/module/models/utils/currencyCode.js.map +0 -1
  180. package/lib/module/models/utils/redirectScheme.js +0 -2
  181. package/lib/module/models/utils/redirectScheme.js.map +0 -1
  182. package/lib/typescript/models/action-request.d.ts +0 -10
  183. package/lib/typescript/models/client-session-actions-request.d.ts +0 -15
  184. package/lib/typescript/models/payment-instrument-token.d.ts +0 -76
  185. package/lib/typescript/models/primer-callbacks.d.ts +0 -10
  186. package/lib/typescript/models/primer-config.d.ts +0 -44
  187. package/lib/typescript/models/primer-error.d.ts +0 -8
  188. package/lib/typescript/models/primer-intent.d.ts +0 -13
  189. package/lib/typescript/models/primer-request.d.ts +0 -7
  190. package/lib/typescript/models/primer-settings.d.ts +0 -65
  191. package/lib/typescript/models/primer.d.ts +0 -33
  192. package/lib/typescript/models/utils/redirectScheme.d.ts +0 -3
  193. package/src/models/action-request.ts +0 -12
  194. package/src/models/client-session-actions-request.ts +0 -21
  195. package/src/models/payment-instrument-token.ts +0 -109
  196. package/src/models/primer-callbacks.ts +0 -14
  197. package/src/models/primer-config.ts +0 -55
  198. package/src/models/primer-error.ts +0 -19
  199. package/src/models/primer-intent.ts +0 -49
  200. package/src/models/primer-request.ts +0 -7
  201. package/src/models/primer-settings.ts +0 -73
  202. package/src/models/primer.ts +0 -41
  203. 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
 
@@ -52,9 +53,13 @@ android {
52
53
  sourceCompatibility JavaVersion.VERSION_1_8
53
54
  targetCompatibility JavaVersion.VERSION_1_8
54
55
  }
56
+ kotlinOptions {
57
+ freeCompilerArgs += '-Xjvm-default=all'
58
+ }
55
59
  }
56
60
 
57
61
  repositories {
62
+ mavenLocal()
58
63
  mavenCentral()
59
64
  jcenter()
60
65
  google()
@@ -131,6 +136,6 @@ dependencies {
131
136
  // noinspection GradleDynamicVersion
132
137
  api 'com.facebook.react:react-native:+'
133
138
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
134
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1"
135
- 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.0'
136
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
@@ -5,78 +5,48 @@ import com.facebook.react.bridge.*
5
5
  import com.facebook.react.modules.core.DeviceEventManagerModule
6
6
  import com.primerioreactnative.datamodels.*
7
7
  import com.primerioreactnative.utils.PrimerImplementedRNCallbacks
8
+ import com.primerioreactnative.utils.convertJsonToMap
8
9
  import com.primerioreactnative.utils.errorTo
9
- import io.primer.android.PaymentMethodIntent
10
10
  import io.primer.android.Primer
11
- import io.primer.android.model.dto.PrimerConfig
12
- import io.primer.android.model.dto.PrimerPaymentMethod
13
- 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
14
14
  import kotlinx.serialization.decodeFromString
15
15
  import kotlinx.serialization.encodeToString
16
16
  import kotlinx.serialization.json.Json
17
17
  import org.json.JSONObject
18
18
 
19
-
20
19
  class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
21
-
22
- private var settings: PrimerSettingsRN = PrimerSettingsRN()
23
- private var theme: PrimerThemeRN = PrimerThemeRN()
24
- private var intent: PaymentMethodIntent? = null
25
- private var paymentMethod: PrimerPaymentMethod? = null
26
-
27
20
  private var mListener = PrimerRNEventListener()
28
-
29
- private var sdkWasInitialised = false
30
-
31
21
  private val json = Json { ignoreUnknownKeys = true }
32
22
 
33
23
  init {
34
24
  mListener.sendEvent = { eventName, paramsJson -> sendEvent(eventName, paramsJson) }
35
- mListener.sendError = { paramsJson -> checkoutFailed(paramsJson) }
25
+ mListener.sendError = { paramsJson -> onError(paramsJson) }
26
+ mListener.sendErrorWithCheckoutData =
27
+ { paramsJson, checkoutData -> onError(paramsJson, checkoutData) }
36
28
  }
37
29
 
38
30
  override fun getName(): String = "NativePrimer"
39
31
 
40
32
  @ReactMethod
41
- fun configureWithSettings(settingsStr: String, promise: Promise) {
33
+ fun configure(settingsStr: String, promise: Promise) {
42
34
  try {
43
35
  Log.d("PrimerRN", "settings: $settingsStr")
44
- val settings = json.decodeFromString<PrimerSettingsRN>(settingsStr)
45
- this.settings = settings
46
- startSdk()
36
+ val settings =
37
+ if (settingsStr.isBlank()) PrimerSettingsRN() else json.decodeFromString(
38
+ settingsStr
39
+ )
40
+ startSdk(settings.toPrimerSettings())
47
41
  promise.resolve(null)
48
42
  } catch (e: Exception) {
49
43
  Log.e("PrimerRN", "configure settings error: $e")
50
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "failed to parse settings."
51
- checkoutFailed(exception)
52
- 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)
53
47
  }
54
48
  }
55
49
 
56
- @ReactMethod
57
- fun configureWithTheme(themeStr: String, promise: Promise) {
58
- try {
59
- Log.d("PrimerRN", "theme: $themeStr")
60
- val theme = json.decodeFromString<PrimerThemeRN>(themeStr)
61
- this.theme = theme
62
- startSdk()
63
- promise.resolve(null)
64
- } catch (e: Exception) {
65
- Log.e("PrimerRN", "configure theme error: $e")
66
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "failed to parse theme."
67
- checkoutFailed(exception)
68
- promise.reject(exception.errorId, exception.errorDescription, e)
69
- }
70
- }
71
-
72
- @ReactMethod
73
- fun showUniversalCheckout(promise: Promise) {
74
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
75
- "This method is deprecated. Use the new showUniversalCheckoutWithClientToken method"
76
- checkoutFailed(exception)
77
- promise.reject(exception.errorId, exception.errorDescription)
78
- }
79
-
80
50
  @ReactMethod
81
51
  fun showUniversalCheckoutWithClientToken(
82
52
  clientToken: String,
@@ -86,62 +56,54 @@ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModu
86
56
  Primer.instance.showUniversalCheckout(reactApplicationContext.applicationContext, clientToken)
87
57
  promise.resolve(null)
88
58
  } catch (e: Exception) {
89
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
59
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo
90
60
  "Primer SDK failed: ${e.message}"
91
- checkoutFailed(exception)
92
- promise.reject(exception.errorId, exception.errorDescription, e)
61
+ onError(exception)
62
+ promise.reject(exception.errorId, exception.description, e)
93
63
  }
94
64
  }
95
65
 
96
66
  @ReactMethod
97
- fun showVaultManager(promise: Promise) {
98
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
99
- "This method is deprecated. Use the new showUniversalCheckoutWithClientToken method"
100
- checkoutFailed(exception)
101
- promise.reject(exception.errorId, exception.errorDescription)
102
- }
103
-
104
- @ReactMethod
105
- fun showVaultManager(clientToken: String, promise: Promise) {
67
+ fun showVaultManagerWithClientToken(clientToken: String, promise: Promise) {
106
68
  try {
107
69
  Primer.instance.showVaultManager(reactApplicationContext.applicationContext, clientToken)
108
70
  promise.resolve(null)
109
71
  } catch (e: Exception) {
110
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
72
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo
111
73
  "Primer SDK failed: ${e.message}"
112
- checkoutFailed(exception)
113
- promise.reject(exception.errorId, exception.errorDescription, e)
74
+ onError(exception)
75
+ promise.reject(exception.errorId, exception.description, e)
114
76
  }
115
77
  }
116
78
 
117
79
  @ReactMethod
118
80
  fun showPaymentMethod(
119
- clientToken: String,
120
81
  paymentMethodTypeStr: String,
121
82
  intentStr: String,
83
+ clientToken: String,
122
84
  promise: Promise
123
85
  ) {
86
+ val intent: PrimerSessionIntent
124
87
  try {
125
- this.intent = PaymentMethodIntent.valueOf(intentStr.uppercase())
88
+ intent = PrimerSessionIntent.valueOf(intentStr.uppercase())
126
89
  } catch (e: Exception) {
127
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "failed to parse intent."
128
- checkoutFailed(exception)
129
- 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)
130
93
  return
131
94
  }
95
+ val paymentMethod: PrimerPaymentMethodType
132
96
  try {
133
- val paymentMethod = getPrimerPaymentMethod(paymentMethodTypeStr)
134
- this.paymentMethod = paymentMethod
97
+ paymentMethod = getPrimerPaymentMethod(paymentMethodTypeStr)
135
98
  } catch (e: Exception) {
136
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo "failed to parse payment method type."
137
- checkoutFailed(exception)
138
- 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)
139
103
  return
140
104
  }
141
105
 
142
106
  try {
143
- val paymentMethod = this.paymentMethod ?: return
144
- val intent = this.intent ?: return
145
107
  Primer.instance.showPaymentMethod(
146
108
  reactApplicationContext.applicationContext,
147
109
  clientToken,
@@ -150,60 +112,81 @@ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModu
150
112
  )
151
113
  promise.resolve(null)
152
114
  } catch (e: Exception) {
153
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
115
+ val exception = ErrorTypeRN.NativeBridgeFailed errorTo
154
116
  "Primer SDK failed: ${e.message}"
155
- checkoutFailed(exception)
156
- promise.reject(exception.errorId, exception.errorDescription, e)
117
+ onError(exception)
118
+ promise.reject(exception.errorId, exception.description, e)
157
119
  }
158
120
  }
159
121
 
160
122
  @ReactMethod
161
- fun handleNewClientToken(clientToken: String, promise: Promise) {
162
- mListener.onClientTokenCallback(clientToken, null)
163
- mListener.onClientSessionActions(clientToken, null)
164
- mListener.onTokenizeSuccess(clientToken, null)
165
- mListener.onResumeSuccess(clientToken, null)
166
- removeCallbacksAndHandlers()
123
+ fun dismiss(promise: Promise) {
124
+ Primer.instance.dismiss()
167
125
  promise.resolve(null)
168
126
  }
169
127
 
128
+ // region tokenization handlers
170
129
  @ReactMethod
171
- fun handleError(errorStr: String, promise: Promise) {
172
- try {
173
- val err = json.decodeFromString<PrimerErrorRN>(errorStr)
174
- mListener.onClientTokenCallback(null, err)
175
- mListener.onClientSessionActions(null, err)
176
- mListener.onTokenizeSuccess(null, err)
177
- mListener.onResumeSuccess(null, err)
178
- removeCallbacksAndHandlers()
179
- promise.resolve(null)
180
- } catch (e: Exception) {
181
- val exception = PrimerErrorRN(
182
- ErrorTypeRN.CheckoutFlowFailed.name,
183
- "Primer SDK failed: ${e.message}"
184
- )
185
- checkoutFailed(exception)
186
- promise.reject(exception.errorId, exception.errorDescription, e)
187
- }
130
+ fun handleTokenizationNewClientToken(newClientToken: String, promise: Promise) {
131
+ mListener.handleTokenizationNewClientToken(newClientToken)
132
+ promise.resolve(null)
188
133
  }
189
134
 
190
135
  @ReactMethod
191
- fun handleSuccess(promise: Promise) {
192
- try {
193
- mListener.onClientTokenCallback(null, null)
194
- mListener.onClientSessionActions(null, null)
195
- mListener.onTokenizeSuccess(null, null)
196
- mListener.onResumeSuccess(null, null)
197
- removeCallbacksAndHandlers()
198
- promise.resolve(null)
199
- } catch (e: Exception) {
200
- val exception = ErrorTypeRN.CheckoutFlowFailed errorTo
201
- "Primer SDK failed: ${e.message}"
202
- checkoutFailed(exception)
203
- promise.reject(exception.errorId, exception.errorDescription, e)
204
- }
136
+ fun handleTokenizationSuccess(promise: Promise) {
137
+ mListener.handleTokenizationSuccess()
138
+ promise.resolve(null)
205
139
  }
206
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)
187
+ }
188
+ // endregion
189
+
207
190
  @ReactMethod
208
191
  fun setImplementedRNCallbacks(implementedRNCallbacksStr: String, promise: Promise) {
209
192
  try {
@@ -213,32 +196,28 @@ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModu
213
196
  this.mListener.setImplementedCallbacks(implementedRNCallbacks)
214
197
  promise.resolve(null)
215
198
  } catch (e: Exception) {
216
- val exception = ErrorTypeRN.ParseJsonFailed errorTo "Failed to parse implemented callbacks"
217
- checkoutFailed(exception)
218
- 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)
219
203
  }
220
204
  }
221
205
 
222
- private fun removeCallbacksAndHandlers() {
223
- mListener.removeCallbacksAndHandlers()
224
- }
225
-
226
- private fun startSdk() {
227
- val theme = theme.format()
228
- val settings = settings.format()
229
- val config = PrimerConfig(theme, settings)
230
-
231
- Primer.instance.configure(config, mListener)
232
- sdkWasInitialised = true
206
+ private fun startSdk(settings: PrimerSettings) {
207
+ Primer.instance.configure(settings, mListener)
233
208
  }
234
209
 
235
- private fun checkoutFailed(exception: PrimerErrorRN) {
210
+ private fun onError(exception: PrimerErrorRN, checkoutDataRN: PrimerCheckoutDataRN? = null) {
236
211
  val params = Arguments.createMap()
237
212
  val errorJson = JSONObject(Json.encodeToString(exception))
238
- val data = Arguments.createMap()
239
- prepareData(data, errorJson)
240
- params.putMap(Keys.ERROR, data)
241
- 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)
242
221
  }
243
222
 
244
223
  private fun sendEvent(name: String, params: WritableMap) {
@@ -248,36 +227,27 @@ class PrimerRN(reactContext: ReactApplicationContext) : ReactContextBaseJavaModu
248
227
  }
249
228
 
250
229
  private fun sendEvent(name: String, data: JSONObject?) {
251
- val params = Arguments.createMap()
252
- prepareData(params, data)
230
+ val params = prepareData(data)
253
231
  reactApplicationContext.getJSModule(
254
232
  DeviceEventManagerModule.RCTDeviceEventEmitter::class.java
255
233
  ).emit(name, params)
256
234
  }
257
235
 
258
- private fun prepareData(params: WritableMap, data: JSONObject?) {
259
- data?.keys()?.forEach { key ->
260
- when (val dataValue = data.opt(key)) {
261
- is String -> params.putString(key, dataValue)
262
- is Boolean -> params.putBoolean(key, dataValue)
263
- is Double -> params.putDouble(key, dataValue)
264
- is Int -> params.putInt(key, dataValue)
265
- is JSONObject -> prepareData(params, dataValue)
266
- else -> params.putNull(key)
267
- }
268
- }
236
+ private fun prepareData(data: JSONObject?): WritableMap {
237
+ return data?.let { convertJsonToMap(data) } ?: Arguments.createMap()
269
238
  }
270
239
 
271
- private fun getPrimerPaymentMethod(paymentMethodTypeStr: String): PrimerPaymentMethod {
240
+ private fun getPrimerPaymentMethod(paymentMethodTypeStr: String): PrimerPaymentMethodType {
272
241
  if (PrimerPaymentMethodType.PAYMENT_CARD.name == paymentMethodTypeStr) {
273
- return PrimerPaymentMethod.CARD
242
+ return PrimerPaymentMethodType.PAYMENT_CARD
274
243
  }
275
244
 
276
- return PrimerPaymentMethod.valueOf(paymentMethodTypeStr)
245
+ return PrimerPaymentMethodType.valueOf(paymentMethodTypeStr)
277
246
  }
278
247
  }
279
248
 
280
249
  internal object Keys {
281
250
  const val ERROR = "error"
282
251
  const val RESUME_TOKEN = "resumeToken"
252
+ const val CHECKOUT_DATA = "checkoutData"
283
253
  }