@jimrising/easymerchantsdk-react-native 2.2.8 → 2.3.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 (102) hide show
  1. package/.idea/caches/deviceStreaming.xml +11 -0
  2. package/README.md +305 -167
  3. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  4. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$3.dex +0 -0
  5. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  6. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  7. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  8. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule$3.dex +0 -0
  9. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  10. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/desugar_graph.bin +0 -0
  11. package/android/build/.transforms/58b147bdc43284da2468dab19bc4a64d/transformed/classes/classes_dex/classes.dex +0 -0
  12. package/android/build/.transforms/e9a664a11ce12edf79cd87b1e07aa243/transformed/classes/classes_dex/classes.dex +0 -0
  13. package/android/build/intermediates/aar_main_jar/release/syncReleaseLibJars/classes.jar +0 -0
  14. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  15. package/android/build/intermediates/compile_library_classes_jar/release/bundleLibCompileToJarRelease/classes.jar +0 -0
  16. package/android/build/intermediates/full_jar/release/createFullJarRelease/full.jar +0 -0
  17. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  18. package/android/build/intermediates/incremental/lintVitalAnalyzeRelease/release-artifact-dependencies.xml +4 -4
  19. package/android/build/intermediates/incremental/lintVitalAnalyzeRelease/release-artifact-libraries.xml +4 -4
  20. package/android/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +916 -916
  21. package/android/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +3 -3
  22. package/android/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties +1 -1
  23. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  24. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  25. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  26. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  27. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  28. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  29. package/android/build/intermediates/lint-cache/lintVitalAnalyzeRelease/maven.google/com/android/tools/build/group-index.xml +22 -0
  30. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-dependencies.xml +4 -4
  31. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-libraries.xml +4 -4
  32. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-dependencies.xml +4 -4
  33. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-libraries.xml +4 -4
  34. package/android/build/intermediates/local_aar_for_lint/release/out.aar +0 -0
  35. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_payment_done_url.xml +2 -1
  36. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/multi-v2/values-night-v8.json +2 -2
  37. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/multi-v2/values.json +38 -38
  38. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/anim-v21.json +9 -9
  39. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/anim.json +24 -24
  40. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/animator-v21.json +1 -1
  41. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/animator.json +34 -34
  42. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color-night-v8.json +3 -3
  43. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color-v31.json +10 -10
  44. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color.json +153 -153
  45. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-anydpi-v21.json +6 -6
  46. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-hdpi-v4.json +13 -13
  47. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-ldpi-v4.json +6 -6
  48. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-mdpi-v4.json +12 -12
  49. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v21.json +4 -4
  50. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v23.json +7 -7
  51. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v29.json +1 -1
  52. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xhdpi-v4.json +12 -12
  53. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xxhdpi-v4.json +7 -7
  54. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xxxhdpi-v4.json +7 -7
  55. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable.json +395 -395
  56. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/font.json +9 -9
  57. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/interpolator-v21.json +10 -10
  58. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/interpolator.json +11 -11
  59. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-land.json +3 -3
  60. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-sw600dp-v13.json +2 -2
  61. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-v21.json +4 -4
  62. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-v26.json +1 -1
  63. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout.json +108 -108
  64. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-anydpi-v26.json +2 -2
  65. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-hdpi-v4.json +2 -2
  66. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-mdpi-v4.json +2 -2
  67. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xhdpi-v4.json +2 -2
  68. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xxhdpi-v4.json +2 -2
  69. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xxxhdpi-v4.json +2 -2
  70. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/raw.json +46 -46
  71. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/xml.json +3 -3
  72. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  73. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  74. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  75. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  76. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  77. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  78. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  79. package/android/build/intermediates/runtime_library_classes_jar/release/bundleLibRuntimeToJarRelease/classes.jar +0 -0
  80. package/android/build/intermediates/source_set_path_map/release/mapReleaseSourceSetPaths/file-map.txt +38 -38
  81. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_payment_done_url.xml.flat +0 -0
  82. package/android/build/outputs/aar/jimrising_easymerchantsdk-react-native-release.aar +0 -0
  83. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  84. package/android/build/tmp/compileReleaseJavaWithJavac/previous-compilation-data.bin +0 -0
  85. package/android/build.gradle +1 -1
  86. package/android/src/main/java/com/reactlibrary/RNEasymerchantsdkModule.java +56 -1
  87. package/ios/Classes/EasyMerchantSdk.m +124 -141
  88. package/ios/Classes/EasyMerchantSdk.swift +270 -502
  89. package/ios/Classes/EasyPayViewController.swift +18 -15
  90. package/ios/CustomComponents/TextFieldStackView.swift +16 -46
  91. package/ios/EnvironmentConfig.swift +16 -0
  92. package/ios/Example/ViewController.swift +513 -76
  93. package/ios/Models/Request.swift +365 -171
  94. package/ios/Pods/UserDefaults/UserStoreSingleton.swift +116 -12
  95. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +2 -32
  96. package/ios/Pods/ViewControllers/GrailPayVC.swift +258 -18
  97. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +1 -66
  98. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +585 -381
  99. package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +18 -9
  100. package/ios/easymerchantsdk.podspec +1 -1
  101. package/ios/easymerchantsdk.storyboard +108 -85
  102. package/package.json +1 -1
@@ -47,6 +47,17 @@
47
47
  <option name="screenX" value="1080" />
48
48
  <option name="screenY" value="2412" />
49
49
  </PersistentDeviceSelectionData>
50
+ <PersistentDeviceSelectionData>
51
+ <option name="api" value="35" />
52
+ <option name="brand" value="OnePlus" />
53
+ <option name="codename" value="OP5552L1" />
54
+ <option name="id" value="OP5552L1" />
55
+ <option name="manufacturer" value="OnePlus" />
56
+ <option name="name" value="CPH2415" />
57
+ <option name="screenDensity" value="480" />
58
+ <option name="screenX" value="1080" />
59
+ <option name="screenY" value="2412" />
60
+ </PersistentDeviceSelectionData>
50
61
  <PersistentDeviceSelectionData>
51
62
  <option name="api" value="34" />
52
63
  <option name="brand" value="OPPO" />
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # EasyMerchant SDK React Native Integration
2
2
 
3
- This guide provides instructions for integrating the EasyMerchant SDK into a React Native application for Android and iOS platforms. It focuses on creating a unified configuration object and using it to process payments with `RNEasymerchantsdk.makePayment` (Android) and `EasyMerchantSdk.makePayment` (iOS). The configuration supports card payments, ACH transfers, recurring payments, 3D Secure authentication, and customizable billing/additional fields.
3
+ This guide provides instructions for integrating the EasyMerchant SDK into a React Native application for Android and iOS platforms. It supports two payment flows: `makePayment` (direct payment with API key and secret) and `makePaymentV2` (client token-based payment). The SDK enables card payments, ACH transfers, recurring payments, 3D Secure authentication, and customizable billing/additional fields with a unified configuration object.
4
4
 
5
5
  ## Prerequisites
6
6
 
@@ -9,7 +9,7 @@ This guide provides instructions for integrating the EasyMerchant SDK into a Rea
9
9
  - **Ruby**: Version 3.2.8 or higher for iOS setup (required for CocoaPods).
10
10
  - **Xcode**: Version 14 or higher for iOS development.
11
11
  - **Android Studio**: For Android development, with Gradle configured.
12
- - **EasyMerchant SDK Credentials**: Obtain API keys and secret keys for `sandbox` or `production` environments.
12
+ - **EasyMerchant SDK Credentials**: Obtain API keys and secret keys for `sandbox` or `production` environments (for `makePayment`), and access to the payment intent API for client token generation (for `makePaymentV2`).
13
13
 
14
14
  ## Installation
15
15
 
@@ -19,7 +19,7 @@ Add the EasyMerchant SDK to your `package.json` under `dependencies`:
19
19
 
20
20
  ```json
21
21
  "dependencies": {
22
- "@jimrising/easymerchantsdk-react-native": "^2.2.8"
22
+ "@jimrising/easymerchantsdk-react-native": "^2.3.0"
23
23
  }
24
24
  ```
25
25
 
@@ -35,18 +35,18 @@ npm install @jimrising/easymerchantsdk-react-native
35
35
 
36
36
  ```gradle
37
37
  allprojects {
38
- repositories {
39
- google()
40
- mavenCentral()
41
- maven { url 'https://jitpack.io' }
42
- maven {
43
- url = uri("https://maven.pkg.github.com/jimrising/easymerchantsdk-react-native")
44
- credentials {
45
- username = properties.getProperty('GITHUB_USERNAME')
46
- password = properties.getProperty('GITHUB_PASSWORD')
47
- }
48
- }
38
+ repositories {
39
+ google()
40
+ mavenCentral()
41
+ maven { url 'https://jitpack.io' }
42
+ maven {
43
+ url = uri("https://maven.pkg.github.com/jimrising/easymerchantsdk-react-native")
44
+ credentials {
45
+ username = properties.getProperty('GITHUB_USERNAME')
46
+ password = properties.getProperty('GITHUB_PASSWORD')
47
+ }
49
48
  }
49
+ }
50
50
  }
51
51
  ```
52
52
 
@@ -72,49 +72,49 @@ import React
72
72
 
73
73
  @UIApplicationMain
74
74
  class AppDelegate: UIResponder, UIApplicationDelegate {
75
- var window: UIWindow?
76
-
77
- func application(
78
- _ application: UIApplication,
79
- didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
80
- ) -> Bool {
81
- let jsCodeLocation: URL
82
-
83
- #if DEBUG
84
- jsCodeLocation = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
85
- #else
86
- jsCodeLocation = Bundle.main.url(forResource: "main", withExtension: "jsbundle")!
87
- #endif
88
-
89
- let bridge = RCTBridge(
90
- bundleURL: jsCodeLocation,
91
- moduleProvider: nil,
92
- launchOptions: launchOptions
93
- )
94
-
95
- guard let validBridge = bridge else {
96
- fatalError("React Native bridge failed to initialize.")
97
- }
98
-
99
- let rootView = RCTRootView(
100
- bridge: validBridge,
101
- moduleName: "EasyMerchantTestApp", // Replace with your app's module name
102
- initialProperties: nil
103
- )
104
-
105
- self.window = UIWindow(frame: UIScreen.main.bounds)
106
- let rootViewController = UIViewController()
107
- rootViewController.view = rootView
108
- self.window?.rootViewController = rootViewController
109
- self.window?.makeKeyAndVisible()
110
-
111
- if let easyMerchantSdkPlugin = validBridge.module(for: EasyMerchantSdkPlugin.self) as? EasyMerchantSdkPlugin {
112
- easyMerchantSdkPlugin.setViewController(rootViewController)
113
- } else {
114
- print("Failed to retrieve EasyMerchantSdkPlugin instance from React Native bridge.")
115
- }
116
- return true
75
+ var window: UIWindow?
76
+
77
+ func application(
78
+ _ application: UIApplication,
79
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
80
+ ) -> Bool {
81
+ let jsCodeLocation: URL
82
+
83
+ #if DEBUG
84
+ jsCodeLocation = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
85
+ #else
86
+ jsCodeLocation = Bundle.main.url(forResource: "main", withExtension: "jsbundle")!
87
+ #endif
88
+
89
+ let bridge = RCTBridge(
90
+ bundleURL: jsCodeLocation,
91
+ moduleProvider: nil,
92
+ launchOptions: launchOptions
93
+ )
94
+
95
+ guard let validBridge = bridge else {
96
+ fatalError("React Native bridge failed to initialize.")
97
+ }
98
+
99
+ let rootView = RCTRootView(
100
+ bridge: validBridge,
101
+ moduleName: "EasyMerchantTestApp", // Replace with your app's module name
102
+ initialProperties: nil
103
+ )
104
+
105
+ self.window = UIWindow(frame: UIScreen.main.bounds)
106
+ let rootViewController = UIViewController()
107
+ rootViewController.view = rootView
108
+ self.window?.rootViewController = rootViewController
109
+ self.window?.makeKeyAndVisible()
110
+
111
+ if let easyMerchantSdkPlugin = validBridge.module(for: EasyMerchantSdkPlugin.self) as? EasyMerchantSdkPlugin {
112
+ easyMerchantSdkPlugin.setViewController(rootViewController)
113
+ } else {
114
+ print("Failed to retrieve EasyMerchantSdkPlugin instance from React Native bridge.")
117
115
  }
116
+ return true
117
+ }
118
118
  }
119
119
  ```
120
120
 
@@ -140,39 +140,41 @@ pod install --repo-update
140
140
 
141
141
  ## Usage
142
142
 
143
- This section explains how to configure and process payments using a unified configuration object, passed to `RNEasymerchantsdk.makePayment` (Android) or `EasyMerchantSdk.makePayment` (iOS). The configuration includes all necessary fields with default values, supporting card payments, ACH transfers, recurring payments, and 3D Secure authentication.
143
+ This section explains how to configure and process payments using `makePayment` (direct payment) and `makePaymentV2` (client token-based payment). Each flow uses a specific configuration object, with `makePaymentV2` requiring a `clientToken` instead of `apiKey` and `secretKey`.
144
144
 
145
145
  ### 1. Import Required Modules
146
146
 
147
147
  ```javascript
148
- import { NativeModules, Platform, Alert } from 'react-native';
148
+ import { NativeModules, Platform, Alert, NativeEventEmitter } from 'react-native';
149
149
  const { RNEasymerchantsdk, EasyMerchantSdk } = NativeModules;
150
150
  ```
151
151
 
152
- ### 2. Define Configuration
152
+ ### 2. Define Configurations
153
+
154
+ #### Configuration for `makePayment`
153
155
 
154
- Create a unified `config` object with default values for all required and optional fields.
156
+ The `makePayment` flow requires `apiKey` and `secretKey`. Below is a sample configuration:
155
157
 
156
158
  ```javascript
157
- const config = {
158
- environment: 'sandbox', // String, e.g., 'sandbox' or 'production'
159
- amount: '5.0', // String or number, must be a positive value
160
- currency: 'usd', // String, currency code, e.g., 'usd'
161
- tokenOnly: false, // Boolean, set to true for tokenization only, false for full payment
162
- saveCard: true, // Boolean, set to true to save card details, false otherwise
163
- saveAccount: true, // Boolean, set to true to save account details for ACH, false otherwise
164
- submitButtonText: 'Submit', // String, text for the payment button
165
- authenticatedACH: true, // Boolean, set to true to enable authenticated ACH, false otherwise
166
- secureAuthentication: true, // Boolean, set to true to enable 3D Secure, false otherwise
167
- showReceipt: true, // Boolean, set to true to show receipt after payment, false otherwise
168
- showDonate: false, // Boolean, set to true to show donation option, false otherwise
169
- showTotal: true, // Boolean, set to true to display total amount, false otherwise
170
- showSubmitButton: true, // Boolean, set to true to show submit button, false otherwise
171
- paymentMethods: ['card', 'ach'], // Array of strings, must include at least one method, e.g., ['card', 'ach']
172
- apiKey: 'replace-with-api-key', // String, environment-specific API key
173
- secretKey: 'replace-with-secret-key', // String, environment-specific secret key
159
+ const configMakePayment = {
160
+ environment: 'sandbox', // String: 'sandbox' or 'production'
161
+ amount: '5.0', // String or number, must be positive
162
+ currency: 'usd', // String: currency code, e.g., 'usd'
163
+ tokenOnly: false, // Boolean: true for tokenization, false for full payment
164
+ saveCard: true, // Boolean: save card details
165
+ saveAccount: true, // Boolean: save account details for ACH
166
+ submitButtonText: 'Submit', // String: payment button text
167
+ authenticatedACH: true, // Boolean: enable authenticated ACH
168
+ secureAuthentication: true, // Boolean: enable 3D Secure
169
+ showReceipt: true, // Boolean: show receipt after payment
170
+ showDonate: false, // Boolean: show donation option
171
+ showTotal: true, // Boolean: display total amount
172
+ showSubmitButton: true, // Boolean: show submit button
173
+ paymentMethods: ['card', 'ach'], // Array: at least one method ('card', 'ach')
174
+ apiKey: 'replace-with-api-key', // String: environment-specific API key
175
+ secretKey: 'replace-with-secret-key', // String: environment-specific secret key
174
176
  fields: {
175
- visibility: { billing: false, additional: false }, // Object, visibility for fields
177
+ visibility: { billing: false, additional: false }, // Object: field visibility
176
178
  billing: [
177
179
  { name: 'address', required: true, value: '123 Main Street, Suite 100' },
178
180
  { name: 'country', required: true, value: 'United States' },
@@ -186,63 +188,127 @@ const config = {
186
188
  ]
187
189
  },
188
190
  appearanceSettings: {
189
- theme: 'light', // String, UI theme, e.g., 'light' or 'dark'
190
- bodyBackgroundColor: '#121212', // String, hex color for body background
191
- containerBackgroundColor: '#1E1E1E', // String, hex color for container background
192
- primaryFontColor: '#FFFFFF', // String, hex color for primary font
193
- secondaryFontColor: '#B0B0B0', // String, hex color for secondary font
194
- primaryButtonBackgroundColor: '#2563EB', // String, hex color for primary button
195
- primaryButtonHoverColor: '#1D4ED8', // String, hex color for primary button hover
196
- primaryButtonFontColor: '#FFFFFF', // String, hex color for primary button font
197
- secondaryButtonBackgroundColor: '#374151', // String, hex color for secondary button
198
- secondaryButtonHoverColor: '#4B5563', // String, hex color for secondary button hover
199
- secondaryButtonFontColor: '#E5E7EB', // String, hex color for secondary button font
200
- borderRadius: '8', // String, border radius in pixels
201
- fontSize: '16', // String, font size in pixels
202
- fontWeight: 500, // Number, font weight, e.g., 400, 500, 700
203
- fontFamily: '"Inter", sans-serif' // String, font family
191
+ theme: 'light', // String: 'light' or 'dark'
192
+ bodyBackgroundColor: '#121212', // String: hex color
193
+ containerBackgroundColor: '#1E1E1E', // String: hex color
194
+ primaryFontColor: '#FFFFFF', // String: hex color
195
+ secondaryFontColor: '#B0B0B0', // String: hex color
196
+ primaryButtonBackgroundColor: '#2563EB', // String: hex color
197
+ primaryButtonHoverColor: '#1D4ED8', // String: hex color
198
+ primaryButtonFontColor: '#FFFFFF', // String: hex color
199
+ secondaryButtonBackgroundColor: '#374151', // String: hex color
200
+ secondaryButtonHoverColor: '#4B5563', // String: hex color
201
+ secondaryButtonFontColor: '#E5E7EB', // String: hex color
202
+ borderRadius: '8', // String: border radius in pixels
203
+ fontSize: '16', // String: font size in pixels
204
+ fontWeight: 500, // Number: font weight
205
+ fontFamily: '"Inter", sans-serif' // String: font family
204
206
  },
205
- email: 'john.doe@example.com', // String, customer email
206
- name: 'John Doe', // String, customer name
207
- isEmail: true, // Boolean, set to true to allow email editing, false otherwise
207
+ email: 'john.doe@example.com', // String: customer email
208
+ name: 'John Doe', // String: customer name
209
+ isEmail: true, // Boolean: allow email editing
208
210
  metadata: {
209
- metadataOne: 'metadataOne', // String, custom metadata key-value
210
- metadataTwo: 'metadataTwo' // String, custom metadata key-value
211
+ metadataOne: 'metadataOne', // String: custom metadata
212
+ metadataTwo: 'metadataTwo' // String: custom metadata
211
213
  },
212
214
  grailPayParams: {
213
- role: 'business', // String, GrailPay role
214
- timeout: 10, // Number, timeout in seconds
215
- isSandbox: true, // Boolean, set to true for GrailPay sandbox mode
216
- brandingName: 'Lyfecycle Payments', // String, branding name
217
- finderSubtitle: 'Search for your bank', // String, bank finder subtitle
218
- searchPlaceholder: 'Enter bank name' // String, search placeholder
215
+ role: 'business', // String: GrailPay role
216
+ timeout: 10, // Number: timeout in seconds
217
+ brandingName: 'Lyfecycle Payments', // String: branding name
218
+ finderSubtitle: 'Search for your bank', // String: bank finder subtitle
219
+ searchPlaceholder: 'Enter bank name' // String: search placeholder
219
220
  },
220
- is_recurring: false, // Boolean, set to true to enable recurring payments
221
- numOfCycle: 2, // Number, minimum 2 cycles for recurring payments
222
- recurringIntervals: ['daily', 'weekly', 'monthly'], // Array of strings, intervals for recurring payments
223
- recurringStartDateType: 'fixed', // String, recurring start type, e.g., 'fixed' or 'custom'
224
- recurringStartDate: '28/08/2025' // String, recurring start date in DD/MM/YYYY format
221
+ is_recurring: false, // Boolean: enable recurring payments
222
+ numOfCycle: 2, // if is_recurring == true
223
+ recurringIntervals: ['daily', 'weekly', 'monthly'], // if is_recurring == true
224
+ recurringStartDateType: 'fixed', // if is_recurring == true
225
+ recurringStartDate: '02/09/2025' // if is_recurring == true
225
226
  };
226
227
  ```
227
228
 
228
- **Notes**:
229
- - Replace `apiKey` and `secretKey` with your actual credentials.
230
- - Ensure `paymentMethods` includes at least one valid method (`'card'` or `'ach'` ).
231
- - For recurring payments, set `is_recurring: true` and ensure `recurringIntervals` has at least one interval (`'daily'`, `'weekly'`, `'monthly'`).
232
- - Set `fields.billing` and `fields.additional` to empty arrays (`[]`) if not needed.
233
- - Adjust `appearanceSettings` colors to match your app’s design.
234
- - Store sensitive data like `apiKey` and `secretKey` securely (e.g., in environment variables).
229
+ #### Configuration for `makePaymentV2`
230
+
231
+ The `makePaymentV2` flow requires a `clientToken` and omits `apiKey` and `secretKey`. Below is a sample configuration:
232
+
233
+ ```javascript
234
+ const configMakePaymentV2 = {
235
+ environment: 'sandbox', // String: 'sandbox' or 'production'
236
+ currency: 'usd', // String: currency code, e.g., 'usd'
237
+ saveCard: true, // Boolean: save card details
238
+ saveAccount: true, // Boolean: save account details for ACH
239
+ submitButtonText: 'Submit', // String: payment button text
240
+ authenticatedACH: true, // Boolean: enable authenticated ACH
241
+ secureAuthentication: true, // Boolean: enable 3D Secure
242
+ showReceipt: true, // Boolean: show receipt after payment
243
+ showDonate: false, // Boolean: show donation option
244
+ showTotal: true, // Boolean: display total amount
245
+ showSubmitButton: true, // Boolean: show submit button
246
+ paymentMethods: ['card', 'ach'], // Array: at least one method ('card', 'ach')
247
+ clientToken: 'replace-with-client-token', // String: client token from payment intent API
248
+ fields: {
249
+ visibility: { billing: false, additional: false }, // Object: field visibility
250
+ billing: [
251
+ { name: 'address', required: true, value: '123 Main Street, Suite 100' },
252
+ { name: 'country', required: true, value: 'United States' },
253
+ { name: 'state', required: true, value: 'California' },
254
+ { name: 'city', required: false, value: 'San Francisco' },
255
+ { name: 'postal_code', required: true, value: '94105' }
256
+ ],
257
+ additional: [
258
+ { name: 'phone_number', required: false, value: '+1-555-123-4567' },
259
+ { name: 'description', required: true, value: 'Test payment for development purposes' }
260
+ ]
261
+ },
262
+ appearanceSettings: {
263
+ theme: 'light', // String: 'light' or 'dark'
264
+ bodyBackgroundColor: '#121212', // String: hex color
265
+ containerBackgroundColor: '#1E1E1E', // String: hex color
266
+ primaryFontColor: '#FFFFFF', // String: hex color
267
+ secondaryFontColor: '#B0B0B0', // String: hex color
268
+ primaryButtonBackgroundColor: '#2563EB', // String: hex color
269
+ primaryButtonHoverColor: '#1D4ED8', // String: hex color
270
+ primaryButtonFontColor: '#FFFFFF', // String: hex color
271
+ secondaryButtonBackgroundColor: '#374151', // String: hex color
272
+ secondaryButtonHoverColor: '#4B5563', // String: hex color
273
+ secondaryButtonFontColor: '#E5E7EB', // String: hex color
274
+ borderRadius: '8', // String: border radius in pixels
275
+ fontSize: '16', // String: font size in pixels
276
+ fontWeight: 500, // Number: font weight
277
+ fontFamily: '"Inter", sans-serif' // String: font family
278
+ },
279
+ email: 'john.doe@example.com', // String: customer email
280
+ name: 'John Doe', // String: customer name
281
+ isEmail: true, // Boolean: allow email editing
282
+ metadata: {
283
+ metadataOne: 'metadataOne', // String: custom metadata
284
+ metadataTwo: 'metadataTwo' // String: custom metadata
285
+ },
286
+ grailPayParams: {
287
+ role: 'business', // String: GrailPay role
288
+ timeout: 10, // Number: timeout in seconds
289
+ brandingName: 'Lyfecycle Payments', // String: branding name
290
+ finderSubtitle: 'Search for your bank', // String: bank finder subtitle
291
+ searchPlaceholder: 'Enter bank name' // String: search placeholder
292
+ },
293
+ };
294
+ ```
295
+
296
+ **Key Differences**:
297
+ - **makePayment**: Requires `apiKey` and `secretKey`, used for direct payment processing.
298
+ - **makePaymentV2**: Requires `clientToken` (obtained from the payment intent API) and omits `apiKey` and `secretKey`.
299
+ - **Environment Initialization**: Required for `makePayment` on iOS; not needed for `makePaymentV2`.
300
+
235
301
 
236
- ### 3. Initialize Environment (iOS Only)
302
+ ### 3. Initialize Environment (iOS Only, for `makePayment`)
237
303
 
238
- For iOS, configure the environment before processing payments:
304
+ For `makePayment` on iOS, configure the environment before processing payments:
239
305
 
240
306
  ```javascript
241
307
  const initializeEnvironment = async () => {
242
308
  try {
243
309
  await EasyMerchantSdk.setViewController();
244
- await EasyMerchantSdk.configureEnvironment(config.environment, config.apiKey, config.secretKey);
245
- console.log(`iOS Environment configured: ${config.environment}`);
310
+ await EasyMerchantSdk.configureEnvironment(configMakePayment.environment, configMakePayment.apiKey, configMakePayment.secretKey);
311
+ console.log(`iOS Environment configured: ${configMakePayment.environment}`);
246
312
  } catch (error) {
247
313
  console.error('iOS Initialization Error:', error);
248
314
  Alert.alert('Error', `Failed to configure iOS environment: ${error.message}`);
@@ -250,32 +316,84 @@ const initializeEnvironment = async () => {
250
316
  };
251
317
  ```
252
318
 
253
- **Note**: Call `initializeEnvironment()` before processing payments on iOS. Android does not require this step.
319
+ **Note**: This step is required only for `makePayment` on iOS. Android and `makePaymentV2` do not require environment initialization.
254
320
 
255
- ### 4. Process Payments
321
+ ### 4. Retrieve Client Token (for `makePaymentV2`)
256
322
 
257
- Use the `config` object to initiate payments. The process differs slightly by platform:
323
+ For `makePaymentV2`, obtain a client token from the EasyMerchant payment intent API:
324
+
325
+ ```javascript
326
+ const apiUrls = {
327
+ sandbox: 'sandbox-url-here',
328
+ production: 'production-url-here'
329
+ };
330
+
331
+ const handleGetClientToken = async () => {
332
+ try {
333
+ const { apiKey, secretKey } = configMakePayment; // Use credentials from makePayment config
334
+ const apiUrl = apiUrls[configMakePaymentV2.environment];
335
+ const params = {
336
+ amount: 13.53,
337
+ intervals: [ "weekly","monthly"],
338
+ is_recurring: true,
339
+ recurring_start_date: "02/09/2025",
340
+ allowed_cycles: 2,
341
+ recurring_start_date_type: "fixed"
342
+ };
343
+
344
+ const response = await fetch(apiUrl, {
345
+ method: 'POST',
346
+ headers: {
347
+ 'Content-Type': 'application/json',
348
+ 'X-Api-Key': apiKey,
349
+ 'X-Api-Secret': secretKey
350
+ },
351
+ body: JSON.stringify(params)
352
+ });
353
+
354
+ const data = await response.json();
355
+ if (data.status === true && data.client_token) {
356
+ configMakePaymentV2.clientToken = data.client_token;
357
+ console.log('Client Token:', data.client_token);
358
+ Alert.alert('Success', 'Client token retrieved successfully');
359
+ } else {
360
+ throw new Error(data.message || 'No client_token in response');
361
+ }
362
+ } catch (error) {
363
+ console.error('Get Client Token Error:', error);
364
+ Alert.alert('Error', `Failed to retrieve client token: ${error.message}`);
365
+ }
366
+ };
367
+ ```
368
+
369
+ **Notes**:
370
+ - Call `handleGetClientToken` before `makePaymentV2`.
371
+ - The API endpoint varies by environment (`sandbox` or `production`).
372
+ - Use `apiKey` and `secretKey` from `configMakePayment` to authenticate the API request.
373
+ - Include recurring payment parameters if `is_recurring` is `true`.
374
+
375
+ ### 5. Process Payments
376
+
377
+ #### Using `makePayment` (Direct Payment)
258
378
 
259
379
  ```javascript
260
380
  const handlePayment = async () => {
261
- // Validate inputs
262
- if (!config.amount || isNaN(parseFloat(config.amount)) || parseFloat(config.amount) <= 0) {
381
+ if (!configMakePayment.amount || isNaN(parseFloat(configMakePayment.amount)) || parseFloat(configMakePayment.amount) <= 0) {
263
382
  Alert.alert('Error', 'Please set a valid amount');
264
383
  return;
265
384
  }
266
- if (!config.paymentMethods || config.paymentMethods.length === 0) {
385
+ if (!configMakePayment.paymentMethods || configMakePayment.paymentMethods.length === 0) {
267
386
  Alert.alert('Error', 'Please select at least one payment method');
268
387
  return;
269
388
  }
270
- if (config.is_recurring && (!config.recurringIntervals || config.recurringIntervals.length === 0)) {
389
+ if (configMakePayment.is_recurring && (!configMakePayment.recurringIntervals || configMakePayment.recurringIntervals.length === 0)) {
271
390
  Alert.alert('Error', 'Please select at least one interval for recurring payment');
272
391
  return;
273
392
  }
274
393
 
275
394
  try {
276
395
  if (Platform.OS === 'android') {
277
- // Android: Pass config object directly
278
- const response = await RNEasymerchantsdk.makePayment(config);
396
+ const response = await RNEasymerchantsdk.makePayment(configMakePayment);
279
397
  const raw = response?.response ? JSON.parse(response.response) : {};
280
398
  const parsedResponse = {
281
399
  ...raw,
@@ -285,9 +403,8 @@ const handlePayment = async () => {
285
403
  console.log('Android Payment Response:', parsedResponse);
286
404
  Alert.alert('Success', 'Payment processed!');
287
405
  } else {
288
- // iOS: Initialize environment and pass config as JSON string
289
406
  await initializeEnvironment();
290
- const configString = JSON.stringify(config);
407
+ const configString = JSON.stringify(configMakePayment);
291
408
  const result = await EasyMerchantSdk.makePayment(configString);
292
409
  const refToken = result?.additionalInfo?.threeDSecureStatus?.data?.ref_token;
293
410
  console.log('iOS Payment Response:', result);
@@ -301,15 +418,60 @@ const handlePayment = async () => {
301
418
  };
302
419
  ```
303
420
 
421
+ #### Using `makePaymentV2` (Client Token-Based)
422
+
423
+ ```javascript
424
+ const handlePaymentV2 = async () => {
425
+ if (!configMakePaymentV2.clientToken) {
426
+ Alert.alert('Error', 'Please provide a valid client token');
427
+ return;
428
+ }
429
+ if (!configMakePaymentV2.paymentMethods || configMakePaymentV2.paymentMethods.length === 0) {
430
+ Alert.alert('Error', 'Please select at least one payment method');
431
+ return;
432
+ }
433
+ if (configMakePaymentV2.is_recurring && (!configMakePaymentV2.recurringIntervals || configMakePaymentV2.recurringIntervals.length === 0)) {
434
+ Alert.alert('Error', 'Please select at least one interval for recurring payment');
435
+ return;
436
+ }
437
+
438
+ try {
439
+ if (Platform.OS === 'android') {
440
+ const response = await RNEasymerchantsdk.makePaymentV2(configMakePaymentV2);
441
+ const raw = response?.response ? JSON.parse(response.response) : {};
442
+ const parsedResponse = {
443
+ ...raw,
444
+ billingInfo: raw.billingInfo ? JSON.parse(raw.billingInfo) : raw.billingInfo,
445
+ additional_info: raw.additional_info ? JSON.parse(raw.additional_info) : raw.additional_info
446
+ };
447
+ console.log('Android Payment V2 Response:', parsedResponse);
448
+ Alert.alert('Success', 'Payment V2 processed!');
449
+ } else {
450
+ const configString = JSON.stringify(configMakePaymentV2);
451
+ const result = await EasyMerchantSdk.makePaymentV2(configString);
452
+ const refToken = result?.additionalInfo?.threeDSecureStatus?.data?.ref_token;
453
+ console.log('iOS Payment V2 Response:', result);
454
+ if (refToken) console.log('Reference Token:', refToken);
455
+ Alert.alert('Success', 'Payment V2 processed!');
456
+ }
457
+ } catch (error) {
458
+ console.error(`${Platform.OS === 'android' ? 'Android' : 'iOS'} Payment V2 Error:`, error);
459
+ Alert.alert('Payment V2 Error', error.message || 'Unknown error');
460
+ }
461
+ };
462
+ ```
463
+
304
464
  **How It Works**:
305
- - **Android**: Pass the `config` object to `RNEasymerchantsdk.makePayment(config)`. The response may include `billingInfo` and `additional_info`, which are parsed if they are JSON strings.
306
- - **iOS**: Stringify the `config` (`JSON.stringify(config)`) and pass to `EasyMerchantSdk.makePayment(configString)`. Call `initializeEnvironment()` first. The response may include a `ref_token` for 3D Secure transactions.
307
- - **Validation**: Ensures `amount` is positive, at least one payment method is selected, and recurring payments have at least one interval.
465
+ - **makePayment**: Uses `configMakePayment` with `apiKey` and `secretKey`. Requires environment initialization on iOS.
466
+ - **makePaymentV2**: Uses `configMakePaymentV2` with `clientToken`. Does not require environment initialization.
467
+ - **Android**: Pass the config object directly. Parse `billingInfo` and `additional_info` if they are JSON strings.
468
+ - **iOS**: Stringify the config (`JSON.stringify(config)`) for both methods. Store `ref_token` for 3D Secure transactions.
469
+ - **Validation**: Ensures `amount` is positive, at least one payment method is selected, and a `clientToken` is provided for `makePaymentV2`.
308
470
  - **Error Handling**: Displays user-friendly alerts for errors.
309
471
 
310
- ### 5. Android Event Listeners
472
+ ### 6. Android Event Listeners
311
473
 
312
- For Android, set up event listeners to handle payment success, status, and errors:
474
+ Set up event listeners for Android to handle payment success, status, and errors:
313
475
 
314
476
  ```javascript
315
477
  const setupAndroidEventListeners = () => {
@@ -355,7 +517,7 @@ const setupAndroidEventListeners = () => {
355
517
 
356
518
  **Note**: Call `setupAndroidEventListeners()` during app initialization and clean up listeners when done (returned function).
357
519
 
358
- ### 6. Check Payment Status (Android Only)
520
+ ### 7. Check Payment Status (Android Only)
359
521
 
360
522
  Check the status of a payment on Android:
361
523
 
@@ -376,7 +538,7 @@ const checkPaymentStatus = async () => {
376
538
  };
377
539
  ```
378
540
 
379
- ### 7. Payment Reference (iOS Only)
541
+ ### 8. Payment Reference (iOS Only)
380
542
 
381
543
  Retrieve payment reference details on iOS using a `ref_token`:
382
544
 
@@ -399,38 +561,14 @@ const checkPaymentReference = async (refToken) => {
399
561
 
400
562
  ## Notes
401
563
 
402
- - **Payment Methods**:
403
- - Use `['card', 'ach']` (lowercase).
564
+ - **Payment Methods**: Use `['card', 'ach']` (lowercase).
404
565
  - **Recurring Payments**: Set `is_recurring: true` and include at least one interval in `recurringIntervals`.
405
- - **Security**: Store `apiKey` and `secretKey` securely (e.g., in environment variables) and ensure they match the `environment`.
566
+ - **Security**: Store `apiKey`, `secretKey`, and `clientToken` securely (e.g., in environment variables) and ensure they match the `environment`.
406
567
  - **Optional Fields**: Set `fields.billing` and `fields.additional` to `[]` if not needed. Use `fields.visibility` to control display.
407
568
  - **Theming**: Customize `appearanceSettings` for UI consistency. Ensure hex colors are valid.
408
569
  - **GrailPay**: Configure `grailPayParams` for bank search UI (used with ACH payments).
409
570
  - **Platform Differences**:
410
- - Android uses a direct object for `makePayment`; iOS requires a JSON string for `makePayment`.
411
- - iOS requires environment initialization before payment.
571
+ - Android uses a direct object for `makePayment` and `makePaymentV2`; iOS requires a JSON string.
572
+ - `makePayment` on iOS requires environment initialization; `makePaymentV2` does not.
412
573
  - Android supports event listeners; iOS uses direct method responses.
413
-
414
- ## Troubleshooting
415
-
416
- - **iOS Bridge Initialization**:
417
- - **Error**: "Failed to retrieve EasyMerchantSdkPlugin instance."
418
- - **Solution**: Verify `easymerchantsdk` pod installation (`pod install --repo-update`) and check `AppDelegate.swift` for correct bridge setup.
419
- - **Android Payment Issues**:
420
- - Ensure `config.paymentMethods` includes valid methods (`['card', 'ach']`).
421
- - Validate `apiKey` and `secretKey` in `config`.
422
- - Check `gradle.properties` for correct `GITHUB_USERNAME` and `GITHUB_PASSWORD`.
423
- - Log `config` for debugging: `console.log(JSON.stringify(config, null, 2))`.
424
- - **Pod Installation**:
425
- - **Error**: `pod install` fails.
426
- - **Solution**: Ensure Ruby 3.2.8 or higher is installed and run `pod install --repo-update`.
427
- - **Payment Failures**:
428
- - Check console logs for errors.
429
- - Verify `amount` is positive and `paymentMethods` is not empty.
430
- - Ensure `apiKey` and `secretKey` match the `environment`.
431
- - For recurring payments, confirm `recurringIntervals` has at least one entry.
432
- - **ACH Payments**:
433
- - Ensure `authenticatedACH` and `secureAuthentication` are set appropriately in `config` when using `ach`.
434
- - **Response Parsing**:
435
- - Android responses may include JSON strings in `billingInfo` and `additional_info`; parse them as shown.
436
- - iOS responses may include a `ref_token` for 3D Secure; store it for reference checks.
574
+ - **Client Token**: Required for `makePaymentV2`. Obtain via the payment intent API (`/api/v1/paymentintent`).