@jimrising/easymerchantsdk-react-native 2.2.9 → 2.3.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 (102) hide show
  1. package/.idea/caches/deviceStreaming.xml +11 -0
  2. package/README.md +310 -171
  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 +571 -369
  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.9"
22
+ "@jimrising/easymerchantsdk-react-native": "^2.3.1"
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,51 @@ 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
+ amount: '5.0', // String or number, must be positive
161
+ appearanceSettings: {
162
+ bodyBackgroundColor: '#121212', // String: hex color
163
+ borderRadius: '8', // String: border radius in pixels
164
+ containerBackgroundColor: '#1E1E1E', // String: hex color
165
+ fontFamily: '"Inter", sans-serif', // String: font family
166
+ fontSize: '16', // String: font size in pixels
167
+ fontWeight: 500, // Number: font weight
168
+ primaryButtonBackgroundColor: '#2563EB', // String: hex color
169
+ primaryButtonFontColor: '#FFFFFF', // String: hex color
170
+ primaryButtonHoverColor: '#1D4ED8', // String: hex color
171
+ primaryFontColor: '#FFFFFF', // String: hex color
172
+ secondaryButtonBackgroundColor: '#374151', // String: hex color
173
+ secondaryButtonFontColor: '#E5E7EB', // String: hex color
174
+ secondaryButtonHoverColor: '#4B5563', // String: hex color
175
+ secondaryFontColor: '#B0B0B0', // String: hex color
176
+ theme: 'light', // String: 'light' or 'dark'
177
+ },
178
+ apiKey: 'replace-with-api-key', // String: environment-specific API key
179
+ authenticatedACH: true, // Boolean: enable authenticated ACH
180
+ currency: 'usd', // String: currency code, e.g., 'usd'
181
+ email: 'john.doe@example.com', // String: customer email
182
+ environment: 'sandbox', // String: 'sandbox' or 'production'
174
183
  fields: {
175
- visibility: { billing: false, additional: false }, // Object, visibility for fields
184
+ additional: [
185
+ { name: 'phone_number', required: false, value: '+1-555-123-4567' },
186
+ { name: 'description', required: true, value: 'Test payment for development purposes' }
187
+ ],
176
188
  billing: [
177
189
  { name: 'address', required: true, value: '123 Main Street, Suite 100' },
178
190
  { name: 'country', required: true, value: 'United States' },
@@ -180,69 +192,124 @@ const config = {
180
192
  { name: 'city', required: false, value: 'San Francisco' },
181
193
  { name: 'postal_code', required: true, value: '94105' }
182
194
  ],
195
+ visibility: { additional: false, billing: false }, // Object: field visibility
196
+ },
197
+ grailPayParams: {
198
+ brandingName: 'Lyfecycle Payments', // String: branding name
199
+ finderSubtitle: 'Search for your bank', // String: bank finder subtitle
200
+ role: 'business', // String: GrailPay role
201
+ searchPlaceholder: 'Enter bank name', // String: search placeholder
202
+ timeout: 10, // Number: timeout in seconds
203
+ },
204
+ isEmail: true, // Boolean: allow email editing
205
+ is_recurring: false, // Boolean: enable recurring payments
206
+ metadata: {
207
+ metadataOne: 'metadataOne', // String: custom metadata
208
+ metadataTwo: 'metadataTwo' // String: custom metadata
209
+ },
210
+ name: 'John Doe', // String: customer name
211
+ numOfCycle: 2, // if is_recurring == true
212
+ paymentMethods: ['card', 'ach'], // Array: at least one method ('card', 'ach')
213
+ recurringIntervals: ['daily', 'weekly', 'monthly'], // if is_recurring == true
214
+ recurringStartDate: 'dd/MM/yyyy', // must be today // required if is_recurring == true
215
+ recurringStartDateType: 'fixed', // if is_recurring == true
216
+ saveAccount: true, // Boolean: save account details for ACH
217
+ saveCard: true, // Boolean: save card details
218
+ secretKey: 'replace-with-secret-key', // String: environment-specific secret key
219
+ secureAuthentication: true, // Boolean: enable 3D Secure
220
+ showDonate: false, // Boolean: show donation option
221
+ showReceipt: true, // Boolean: show receipt after payment
222
+ showSubmitButton: true, // Boolean: show submit button
223
+ showTotal: true, // Boolean: display total amount
224
+ submitButtonText: 'Submit', // String: payment button text
225
+ tokenOnly: false, // Boolean: true for tokenization, false for full payment
226
+ };
227
+
228
+ ```
229
+
230
+ #### Configuration for `makePaymentV2`
231
+
232
+ The `makePaymentV2` flow requires a `clientToken` and omits `apiKey` and `secretKey`. Below is a sample configuration:
233
+
234
+ ```javascript
235
+ const configMakePaymentV2 = {
236
+ appearanceSettings: {
237
+ bodyBackgroundColor: '#121212', // String: hex color
238
+ borderRadius: '8', // String: border radius in pixels
239
+ containerBackgroundColor: '#1E1E1E', // String: hex color
240
+ fontFamily: '"Inter", sans-serif', // String: font family
241
+ fontSize: '16', // String: font size in pixels
242
+ fontWeight: 500, // Number: font weight
243
+ primaryButtonBackgroundColor: '#2563EB', // String: hex color
244
+ primaryButtonFontColor: '#FFFFFF', // String: hex color
245
+ primaryButtonHoverColor: '#1D4ED8', // String: hex color
246
+ primaryFontColor: '#FFFFFF', // String: hex color
247
+ secondaryButtonBackgroundColor: '#374151', // String: hex color
248
+ secondaryButtonFontColor: '#E5E7EB', // String: hex color
249
+ secondaryButtonHoverColor: '#4B5563', // String: hex color
250
+ secondaryFontColor: '#B0B0B0', // String: hex color
251
+ theme: 'light', // String: 'light' or 'dark'
252
+ },
253
+ authenticatedACH: true, // Boolean: enable authenticated ACH
254
+ clientToken: 'replace-with-client-token', // String: client token from payment intent API
255
+ currency: 'usd', // String: currency code, e.g., 'usd'
256
+ email: 'john.doe@example.com', // String: customer email
257
+ environment: 'sandbox', // String: 'sandbox' or 'production'
258
+ fields: {
183
259
  additional: [
184
260
  { name: 'phone_number', required: false, value: '+1-555-123-4567' },
185
261
  { name: 'description', required: true, value: 'Test payment for development purposes' }
186
- ]
262
+ ],
263
+ billing: [
264
+ { name: 'address', required: true, value: '123 Main Street, Suite 100' },
265
+ { name: 'country', required: true, value: 'United States' },
266
+ { name: 'state', required: true, value: 'California' },
267
+ { name: 'city', required: false, value: 'San Francisco' },
268
+ { name: 'postal_code', required: true, value: '94105' }
269
+ ],
270
+ visibility: { additional: false, billing: false }, // Object: field visibility
187
271
  },
188
- 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
272
+ grailPayParams: {
273
+ brandingName: 'Lyfecycle Payments', // String: branding name
274
+ finderSubtitle: 'Search for your bank', // String: bank finder subtitle
275
+ role: 'business', // String: GrailPay role
276
+ searchPlaceholder: 'Enter bank name', // String: search placeholder
277
+ timeout: 10, // Number: timeout in seconds
204
278
  },
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
279
+ isEmail: true, // Boolean: allow email editing
208
280
  metadata: {
209
- metadataOne: 'metadataOne', // String, custom metadata key-value
210
- metadataTwo: 'metadataTwo' // String, custom metadata key-value
281
+ metadataOne: 'metadataOne', // String: custom metadata
282
+ metadataTwo: 'metadataTwo', // String: custom metadata
211
283
  },
212
- 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
219
- },
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
284
+ name: 'John Doe', // String: customer name
285
+ paymentMethods: ['card', 'ach'], // Array: at least one method ('card', 'ach')
286
+ saveAccount: true, // Boolean: save account details for ACH
287
+ saveCard: true, // Boolean: save card details
288
+ secureAuthentication: true, // Boolean: enable 3D Secure
289
+ showDonate: false, // Boolean: show donation option
290
+ showReceipt: true, // Boolean: show receipt after payment
291
+ showSubmitButton: true, // Boolean: show submit button
292
+ showTotal: true, // Boolean: display total amount
293
+ submitButtonText: 'Submit', // String: payment button text
225
294
  };
226
295
  ```
227
296
 
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).
297
+ **Key Differences**:
298
+ - **makePayment**: Requires `apiKey` and `secretKey`, used for direct payment processing.
299
+ - **makePaymentV2**: Requires `clientToken` (obtained from the payment intent API) and omits `apiKey` and `secretKey`.
300
+ - **Environment Initialization**: Required for `makePayment` on iOS; not needed for `makePaymentV2`.
235
301
 
236
- ### 3. Initialize Environment (iOS Only)
237
302
 
238
- For iOS, configure the environment before processing payments:
303
+ ### 3. Initialize Environment (iOS Only, for `makePayment`)
304
+
305
+ For `makePayment` on iOS, configure the environment before processing payments:
239
306
 
240
307
  ```javascript
241
308
  const initializeEnvironment = async () => {
242
309
  try {
243
310
  await EasyMerchantSdk.setViewController();
244
- await EasyMerchantSdk.configureEnvironment(config.environment, config.apiKey, config.secretKey);
245
- console.log(`iOS Environment configured: ${config.environment}`);
311
+ await EasyMerchantSdk.configureEnvironment(configMakePayment.environment, configMakePayment.apiKey, configMakePayment.secretKey);
312
+ console.log(`iOS Environment configured: ${configMakePayment.environment}`);
246
313
  } catch (error) {
247
314
  console.error('iOS Initialization Error:', error);
248
315
  Alert.alert('Error', `Failed to configure iOS environment: ${error.message}`);
@@ -250,32 +317,84 @@ const initializeEnvironment = async () => {
250
317
  };
251
318
  ```
252
319
 
253
- **Note**: Call `initializeEnvironment()` before processing payments on iOS. Android does not require this step.
320
+ **Note**: This step is required only for `makePayment` on iOS. Android and `makePaymentV2` do not require environment initialization.
254
321
 
255
- ### 4. Process Payments
322
+ ### 4. Retrieve Client Token (for `makePaymentV2`)
256
323
 
257
- Use the `config` object to initiate payments. The process differs slightly by platform:
324
+ For `makePaymentV2`, obtain a client token from the EasyMerchant payment intent API:
325
+
326
+ ```javascript
327
+ const apiUrls = {
328
+ sandbox: 'sandbox-url-here',
329
+ production: 'production-url-here'
330
+ };
331
+
332
+ const handleGetClientToken = async () => {
333
+ try {
334
+ const { apiKey, secretKey } = configMakePayment; // Use credentials from makePayment config
335
+ const apiUrl = apiUrls[configMakePaymentV2.environment];
336
+ const params = {
337
+ amount: 13.53,
338
+ intervals: [ "weekly","monthly"],
339
+ is_recurring: true,
340
+ recurring_start_date: "02/09/2025",
341
+ allowed_cycles: 2,
342
+ recurring_start_date_type: "fixed"
343
+ };
344
+
345
+ const response = await fetch(apiUrl, {
346
+ method: 'POST',
347
+ headers: {
348
+ 'Content-Type': 'application/json',
349
+ 'X-Api-Key': apiKey,
350
+ 'X-Api-Secret': secretKey
351
+ },
352
+ body: JSON.stringify(params)
353
+ });
354
+
355
+ const data = await response.json();
356
+ if (data.status === true && data.client_token) {
357
+ configMakePaymentV2.clientToken = data.client_token;
358
+ console.log('Client Token:', data.client_token);
359
+ Alert.alert('Success', 'Client token retrieved successfully');
360
+ } else {
361
+ throw new Error(data.message || 'No client_token in response');
362
+ }
363
+ } catch (error) {
364
+ console.error('Get Client Token Error:', error);
365
+ Alert.alert('Error', `Failed to retrieve client token: ${error.message}`);
366
+ }
367
+ };
368
+ ```
369
+
370
+ **Notes**:
371
+ - Call `handleGetClientToken` before `makePaymentV2`.
372
+ - The API endpoint varies by environment (`sandbox` or `production`).
373
+ - Use `apiKey` and `secretKey` from `configMakePayment` to authenticate the API request.
374
+ - Include recurring payment parameters if `is_recurring` is `true`.
375
+
376
+ ### 5. Process Payments
377
+
378
+ #### Using `makePayment` (Direct Payment)
258
379
 
259
380
  ```javascript
260
381
  const handlePayment = async () => {
261
- // Validate inputs
262
- if (!config.amount || isNaN(parseFloat(config.amount)) || parseFloat(config.amount) <= 0) {
382
+ if (!configMakePayment.amount || isNaN(parseFloat(configMakePayment.amount)) || parseFloat(configMakePayment.amount) <= 0) {
263
383
  Alert.alert('Error', 'Please set a valid amount');
264
384
  return;
265
385
  }
266
- if (!config.paymentMethods || config.paymentMethods.length === 0) {
386
+ if (!configMakePayment.paymentMethods || configMakePayment.paymentMethods.length === 0) {
267
387
  Alert.alert('Error', 'Please select at least one payment method');
268
388
  return;
269
389
  }
270
- if (config.is_recurring && (!config.recurringIntervals || config.recurringIntervals.length === 0)) {
390
+ if (configMakePayment.is_recurring && (!configMakePayment.recurringIntervals || configMakePayment.recurringIntervals.length === 0)) {
271
391
  Alert.alert('Error', 'Please select at least one interval for recurring payment');
272
392
  return;
273
393
  }
274
394
 
275
395
  try {
276
396
  if (Platform.OS === 'android') {
277
- // Android: Pass config object directly
278
- const response = await RNEasymerchantsdk.makePayment(config);
397
+ const response = await RNEasymerchantsdk.makePayment(configMakePayment);
279
398
  const raw = response?.response ? JSON.parse(response.response) : {};
280
399
  const parsedResponse = {
281
400
  ...raw,
@@ -285,9 +404,8 @@ const handlePayment = async () => {
285
404
  console.log('Android Payment Response:', parsedResponse);
286
405
  Alert.alert('Success', 'Payment processed!');
287
406
  } else {
288
- // iOS: Initialize environment and pass config as JSON string
289
407
  await initializeEnvironment();
290
- const configString = JSON.stringify(config);
408
+ const configString = JSON.stringify(configMakePayment);
291
409
  const result = await EasyMerchantSdk.makePayment(configString);
292
410
  const refToken = result?.additionalInfo?.threeDSecureStatus?.data?.ref_token;
293
411
  console.log('iOS Payment Response:', result);
@@ -301,15 +419,60 @@ const handlePayment = async () => {
301
419
  };
302
420
  ```
303
421
 
422
+ #### Using `makePaymentV2` (Client Token-Based)
423
+
424
+ ```javascript
425
+ const handlePaymentV2 = async () => {
426
+ if (!configMakePaymentV2.clientToken) {
427
+ Alert.alert('Error', 'Please provide a valid client token');
428
+ return;
429
+ }
430
+ if (!configMakePaymentV2.paymentMethods || configMakePaymentV2.paymentMethods.length === 0) {
431
+ Alert.alert('Error', 'Please select at least one payment method');
432
+ return;
433
+ }
434
+ if (configMakePaymentV2.is_recurring && (!configMakePaymentV2.recurringIntervals || configMakePaymentV2.recurringIntervals.length === 0)) {
435
+ Alert.alert('Error', 'Please select at least one interval for recurring payment');
436
+ return;
437
+ }
438
+
439
+ try {
440
+ if (Platform.OS === 'android') {
441
+ const response = await RNEasymerchantsdk.makePaymentV2(configMakePaymentV2);
442
+ const raw = response?.response ? JSON.parse(response.response) : {};
443
+ const parsedResponse = {
444
+ ...raw,
445
+ billingInfo: raw.billingInfo ? JSON.parse(raw.billingInfo) : raw.billingInfo,
446
+ additional_info: raw.additional_info ? JSON.parse(raw.additional_info) : raw.additional_info
447
+ };
448
+ console.log('Android Payment V2 Response:', parsedResponse);
449
+ Alert.alert('Success', 'Payment V2 processed!');
450
+ } else {
451
+ const configString = JSON.stringify(configMakePaymentV2);
452
+ const result = await EasyMerchantSdk.makePaymentV2(configString);
453
+ const refToken = result?.additionalInfo?.threeDSecureStatus?.data?.ref_token;
454
+ console.log('iOS Payment V2 Response:', result);
455
+ if (refToken) console.log('Reference Token:', refToken);
456
+ Alert.alert('Success', 'Payment V2 processed!');
457
+ }
458
+ } catch (error) {
459
+ console.error(`${Platform.OS === 'android' ? 'Android' : 'iOS'} Payment V2 Error:`, error);
460
+ Alert.alert('Payment V2 Error', error.message || 'Unknown error');
461
+ }
462
+ };
463
+ ```
464
+
304
465
  **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.
466
+ - **makePayment**: Uses `configMakePayment` with `apiKey` and `secretKey`. Requires environment initialization on iOS.
467
+ - **makePaymentV2**: Uses `configMakePaymentV2` with `clientToken`. Does not require environment initialization.
468
+ - **Android**: Pass the config object directly. Parse `billingInfo` and `additional_info` if they are JSON strings.
469
+ - **iOS**: Stringify the config (`JSON.stringify(config)`) for both methods. Store `ref_token` for 3D Secure transactions.
470
+ - **Validation**: Ensures `amount` is positive, at least one payment method is selected, and a `clientToken` is provided for `makePaymentV2`.
308
471
  - **Error Handling**: Displays user-friendly alerts for errors.
309
472
 
310
- ### 5. Android Event Listeners
473
+ ### 6. Android Event Listeners
311
474
 
312
- For Android, set up event listeners to handle payment success, status, and errors:
475
+ Set up event listeners for Android to handle payment success, status, and errors:
313
476
 
314
477
  ```javascript
315
478
  const setupAndroidEventListeners = () => {
@@ -355,7 +518,7 @@ const setupAndroidEventListeners = () => {
355
518
 
356
519
  **Note**: Call `setupAndroidEventListeners()` during app initialization and clean up listeners when done (returned function).
357
520
 
358
- ### 6. Check Payment Status (Android Only)
521
+ ### 7. Check Payment Status (Android Only)
359
522
 
360
523
  Check the status of a payment on Android:
361
524
 
@@ -376,7 +539,7 @@ const checkPaymentStatus = async () => {
376
539
  };
377
540
  ```
378
541
 
379
- ### 7. Payment Reference (iOS Only)
542
+ ### 8. Payment Reference (iOS Only)
380
543
 
381
544
  Retrieve payment reference details on iOS using a `ref_token`:
382
545
 
@@ -399,38 +562,14 @@ const checkPaymentReference = async (refToken) => {
399
562
 
400
563
  ## Notes
401
564
 
402
- - **Payment Methods**:
403
- - Use `['card', 'ach']` (lowercase).
565
+ - **Payment Methods**: Use `['card', 'ach']` (lowercase).
404
566
  - **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`.
567
+ - **Security**: Store `apiKey`, `secretKey`, and `clientToken` securely (e.g., in environment variables) and ensure they match the `environment`.
406
568
  - **Optional Fields**: Set `fields.billing` and `fields.additional` to `[]` if not needed. Use `fields.visibility` to control display.
407
569
  - **Theming**: Customize `appearanceSettings` for UI consistency. Ensure hex colors are valid.
408
570
  - **GrailPay**: Configure `grailPayParams` for bank search UI (used with ACH payments).
409
571
  - **Platform Differences**:
410
- - Android uses a direct object for `makePayment`; iOS requires a JSON string for `makePayment`.
411
- - iOS requires environment initialization before payment.
572
+ - Android uses a direct object for `makePayment` and `makePaymentV2`; iOS requires a JSON string.
573
+ - `makePayment` on iOS requires environment initialization; `makePaymentV2` does not.
412
574
  - 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.
575
+ - **Client Token**: Required for `makePaymentV2`. Obtain via the payment intent API (`/api/v1/paymentintent`).