@cashfreepayments/react-native-cashfree-cn-sdk 1.0.0-dev.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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/android/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  4. package/android/.gradle/7.2/dependencies-accessors/gc.properties +0 -0
  5. package/android/.gradle/7.2/executionHistory/executionHistory.lock +0 -0
  6. package/android/.gradle/7.2/fileChanges/last-build.bin +0 -0
  7. package/android/.gradle/7.2/fileHashes/fileHashes.bin +0 -0
  8. package/android/.gradle/7.2/fileHashes/fileHashes.lock +0 -0
  9. package/android/.gradle/7.2/fileHashes/resourceHashesCache.bin +0 -0
  10. package/android/.gradle/7.2/gc.properties +0 -0
  11. package/android/.gradle/7.5/checksums/checksums.lock +0 -0
  12. package/android/.gradle/7.5/checksums/md5-checksums.bin +0 -0
  13. package/android/.gradle/7.5/checksums/sha1-checksums.bin +0 -0
  14. package/android/.gradle/7.5/dependencies-accessors/dependencies-accessors.lock +0 -0
  15. package/android/.gradle/7.5/dependencies-accessors/gc.properties +0 -0
  16. package/android/.gradle/7.5/executionHistory/executionHistory.lock +0 -0
  17. package/android/.gradle/7.5/fileChanges/last-build.bin +0 -0
  18. package/android/.gradle/7.5/fileHashes/fileHashes.bin +0 -0
  19. package/android/.gradle/7.5/fileHashes/fileHashes.lock +0 -0
  20. package/android/.gradle/7.5/fileHashes/resourceHashesCache.bin +0 -0
  21. package/android/.gradle/7.5/gc.properties +0 -0
  22. package/android/.gradle/8.5/checksums/checksums.lock +0 -0
  23. package/android/.gradle/8.5/checksums/md5-checksums.bin +0 -0
  24. package/android/.gradle/8.5/checksums/sha1-checksums.bin +0 -0
  25. package/android/.gradle/8.5/dependencies-accessors/dependencies-accessors.lock +0 -0
  26. package/android/.gradle/8.5/dependencies-accessors/gc.properties +0 -0
  27. package/android/.gradle/8.5/fileChanges/last-build.bin +0 -0
  28. package/android/.gradle/8.5/fileHashes/fileHashes.lock +0 -0
  29. package/android/.gradle/8.5/gc.properties +0 -0
  30. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  31. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  32. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  33. package/android/.gradle/checksums/checksums.lock +0 -0
  34. package/android/.gradle/checksums/md5-checksums.bin +0 -0
  35. package/android/.gradle/checksums/sha1-checksums.bin +0 -0
  36. package/android/.gradle/config.properties +2 -0
  37. package/android/.gradle/nb-cache/trust/5D9F4D2F872AE83553369BAEF9EF62F30CBE0A19F76FE265082C658DB033E1DA +1 -0
  38. package/android/.gradle/nb-cache/trust/811DB8418F399FDF2AFA5CB6893343C7013E03D6360FA7A8FBFC8B0C8A38EE77 +1 -0
  39. package/android/.gradle/vcs-1/gc.properties +0 -0
  40. package/android/.idea/compiler.xml +6 -0
  41. package/android/.idea/gradle.xml +18 -0
  42. package/android/.idea/migrations.xml +10 -0
  43. package/android/.idea/misc.xml +9 -0
  44. package/android/.idea/other.xml +549 -0
  45. package/android/.idea/vcs.xml +6 -0
  46. package/android/build.gradle +77 -0
  47. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  48. package/android/local.properties +8 -0
  49. package/android/src/main/AndroidManifest.xml +4 -0
  50. package/android/src/main/java/com/reactnativecashfreecnsdk/CashfreePgApiModule.java +319 -0
  51. package/android/src/main/java/com/reactnativecashfreecnsdk/CashfreePgApiPackage.java +28 -0
  52. package/ios/CashfreeEmitter.swift +36 -0
  53. package/ios/CashfreeEventEmitter.m +16 -0
  54. package/ios/CashfreeEventEmitter.swift +28 -0
  55. package/ios/CashfreePgApi-Bridging-Header.h +5 -0
  56. package/ios/CashfreePgApi.m +21 -0
  57. package/ios/CashfreePgApi.swift +410 -0
  58. package/ios/CashfreePgApi.xcodeproj/project.pbxproj +293 -0
  59. package/ios/CashfreePgApi.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  60. package/ios/CashfreePgApi.xcodeproj/project.xcworkspace/xcuserdata/nikhil.kushwah.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  61. package/ios/CashfreePgApi.xcodeproj/xcuserdata/nikhil.kushwah.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  62. package/lib/commonjs/Card/CFCardComponent.js +287 -0
  63. package/lib/commonjs/Card/CFCardComponent.js.map +1 -0
  64. package/lib/commonjs/Card/index.js +14 -0
  65. package/lib/commonjs/Card/index.js.map +1 -0
  66. package/lib/commonjs/index.js +168 -0
  67. package/lib/commonjs/index.js.map +1 -0
  68. package/lib/module/Card/CFCardComponent.js +279 -0
  69. package/lib/module/Card/CFCardComponent.js.map +1 -0
  70. package/lib/module/Card/index.js +2 -0
  71. package/lib/module/Card/index.js.map +1 -0
  72. package/lib/module/index.js +159 -0
  73. package/lib/module/index.js.map +1 -0
  74. package/lib/typescript/src/Card/CFCardComponent.d.ts +12 -0
  75. package/lib/typescript/src/Card/index.d.ts +1 -0
  76. package/lib/typescript/src/index.d.ts +43 -0
  77. package/package.json +157 -0
  78. package/react-native-cashfree-cn-sdk.podspec +20 -0
  79. package/src/Card/CFCardComponent.js +238 -0
  80. package/src/Card/CFCardComponent.tsx +323 -0
  81. package/src/Card/index.js +1 -0
  82. package/src/Card/index.ts +1 -0
  83. package/src/index.js +167 -0
  84. package/src/index.ts +219 -0
@@ -0,0 +1,323 @@
1
+ import { TextInput, TextInputProps } from 'react-native';
2
+ import React, { forwardRef } from 'react';
3
+ import {
4
+ CFCardPayment,
5
+ CFEnvironment,
6
+ type CFSession,
7
+ ElementCard,
8
+ } from 'cashfree-pg-api-contract';
9
+ import { CFPaymentGatewayService } from '../index';
10
+
11
+ function luhnCheck(cardNumber: string): boolean {
12
+ if (cardNumber.length === 0) {
13
+ return false;
14
+ }
15
+
16
+ cardNumber = cardNumber.replace(/\s/g, ''); // Remove spaces
17
+
18
+ let sum = 0;
19
+ let isAlternate = false;
20
+
21
+ for (let i = cardNumber.length - 1; i >= 0; i--) {
22
+ let digit = parseInt(cardNumber[i], 10);
23
+
24
+ if (isAlternate) {
25
+ digit *= 2;
26
+ if (digit > 9) {
27
+ digit -= 9;
28
+ }
29
+ }
30
+
31
+ sum += digit;
32
+ isAlternate = !isAlternate;
33
+ }
34
+
35
+ return sum % 10 === 0;
36
+ }
37
+
38
+ function getInputValidationDetails(cardBinResponse: any) {
39
+ if (!cardBinResponse || !cardBinResponse.scheme) {
40
+ return null;
41
+ }
42
+
43
+ let schemeType = cardBinResponse.scheme.toLowerCase();
44
+ let inputValidationDetails: { max_input_length: number; cvv_length: number };
45
+ switch (schemeType) {
46
+ case 'amex':
47
+ inputValidationDetails = { max_input_length: 15, cvv_length: 4 };
48
+ break;
49
+ case 'diners':
50
+ inputValidationDetails = { max_input_length: 14, cvv_length: 3 };
51
+ break;
52
+ default: // Covers visa, mastercard, rupay, jcb, discover, and unknown schemes
53
+ inputValidationDetails = { max_input_length: 16, cvv_length: 3 };
54
+ }
55
+ return inputValidationDetails;
56
+ }
57
+
58
+ /**
59
+ * Fetching Tdr info with card bin data & cfSession object
60
+ * @param session : for payment sessionId & env
61
+ * @param bin : for card number
62
+ */
63
+ async function getTDR(session: CFSession, bin: string) {
64
+ const route: string = `/pg/sdk/js/${session.payment_session_id}/v2/tdr`;
65
+ const body: string = JSON.stringify({ code: bin, code_type: 'bin' });
66
+ return await getInfo(session.environment, route, body);
67
+ }
68
+
69
+ /**
70
+ * Fetching CardBin info with card bin data & cfSession object
71
+ * @param session : for payment sessionId & env
72
+ * @param bin : for card number
73
+ */
74
+ async function getCardBin(session: CFSession, bin: string) {
75
+ const route: string = `/pg/sdk/js/${session.payment_session_id}/cardBin`;
76
+ const body: string = JSON.stringify({ card_number: bin });
77
+ return await getInfo(session.environment, route, body);
78
+ }
79
+
80
+ async function getInfo(env: string, route: string, bodyData: string) {
81
+ let baseUrl = 'https://api.cashfree.com';
82
+ if (env === CFEnvironment.SANDBOX) {
83
+ baseUrl = 'https://sandbox.cashfree.com';
84
+ }
85
+ const url = baseUrl + route;
86
+ try {
87
+ const response = await fetch(url, {
88
+ method: 'POST',
89
+ headers: {
90
+ 'Content-Type': 'application/json',
91
+ },
92
+ body: bodyData,
93
+ });
94
+
95
+ if (!response.ok) {
96
+ return null;
97
+ }
98
+ return await response.json();
99
+ } catch (error) {
100
+ return null;
101
+ }
102
+ }
103
+
104
+ export type CardPaymentHandle = {
105
+ doPayment: (cardInfo: ElementCard) => void;
106
+ doPaymentWithPaymentSessionId: (
107
+ cardInfo: ElementCard,
108
+ cfSession: CFSession
109
+ ) => void;
110
+ };
111
+
112
+ export type CardInputProps = {
113
+ cfSession: CFSession;
114
+ cardListener: (response: string) => void;
115
+ } & TextInputProps;
116
+
117
+ const CardInput: any = forwardRef<CardPaymentHandle, CardInputProps>(
118
+ ({ cfSession, cardListener, style, ...props }: CardInputProps, ref) => {
119
+ const [inputNumber, setInputNumber] = React.useState('');
120
+ const inputNumberRef = React.useRef('');
121
+ const sessionRef = React.useRef(cfSession);
122
+ React.useImperativeHandle(ref, () => ({
123
+ doPayment,
124
+ doPaymentWithPaymentSessionId,
125
+ }));
126
+
127
+ const tdrJsonRef = React.useRef<any>(null);
128
+ const cardBinJsonRef = React.useRef<any>(null);
129
+ const firstEightDigitsRef = React.useRef<string>('');
130
+
131
+ const handleChange = React.useCallback(
132
+ async (cardNumber: string) => {
133
+ let completeResponse: any = {};
134
+ const textWithoutSpaces: string = cardNumber.replaceAll(' ', '');
135
+ if (textWithoutSpaces.length === 0) setInputNumber('');
136
+
137
+ let formattedText: string = '';
138
+ /**
139
+ * Code to format card input number & set to input box
140
+ */
141
+ for (let i: number = 0; i < textWithoutSpaces.length; i += 4) {
142
+ let end: number = i + 4;
143
+ if (end > textWithoutSpaces.length) {
144
+ end = textWithoutSpaces.length;
145
+ }
146
+ formattedText += textWithoutSpaces.substring(i, end);
147
+ if (end !== textWithoutSpaces.length) {
148
+ formattedText += ' ';
149
+ }
150
+ inputNumberRef.current = formattedText;
151
+ setInputNumber((prev) =>
152
+ prev === formattedText ? prev : formattedText
153
+ );
154
+ }
155
+
156
+ let tdrResponse: any = null;
157
+ let cardBinResponse: any = null;
158
+
159
+ /**
160
+ * Fetch Tdr & CardBin data & set to local variable
161
+ */
162
+ async function fetchDataAndSet() {
163
+ await getTDR(cfSession, textWithoutSpaces)
164
+ .then((response: string) => {
165
+ tdrResponse = response;
166
+ firstEightDigitsRef.current = textWithoutSpaces.substring(0, 8);
167
+ })
168
+ .catch(() => {
169
+ tdrResponse = null;
170
+ });
171
+
172
+ await getCardBin(cfSession, textWithoutSpaces)
173
+ .then((response: string) => {
174
+ cardBinResponse = response;
175
+ firstEightDigitsRef.current = textWithoutSpaces.substring(0, 8);
176
+ })
177
+ .catch(() => {
178
+ cardBinResponse = null;
179
+ });
180
+
181
+ if (tdrResponse) {
182
+ tdrJsonRef.current = tdrResponse;
183
+ completeResponse.tdr_info = tdrJsonRef.current;
184
+ }
185
+
186
+ if (cardBinResponse) {
187
+ cardBinJsonRef.current = cardBinResponse;
188
+ completeResponse.card_bin_info = cardBinJsonRef.current;
189
+ completeResponse.input_validation = getInputValidationDetails(
190
+ cardBinJsonRef.current
191
+ );
192
+ }
193
+ }
194
+
195
+ if (textWithoutSpaces.length === 8) {
196
+ await fetchDataAndSet();
197
+ } else if (textWithoutSpaces.length > 8) {
198
+ if (
199
+ firstEightDigitsRef.current === textWithoutSpaces.substring(0, 8)
200
+ ) {
201
+ completeResponse.tdr_info = tdrJsonRef.current;
202
+ completeResponse.card_bin_info = cardBinJsonRef.current;
203
+ completeResponse.input_validation = getInputValidationDetails(
204
+ cardBinJsonRef.current
205
+ );
206
+ } else {
207
+ tdrJsonRef.current = null;
208
+ cardBinJsonRef.current = null;
209
+ await fetchDataAndSet();
210
+ }
211
+ }
212
+
213
+ if (textWithoutSpaces.length < 8) {
214
+ tdrJsonRef.current = null;
215
+ cardBinJsonRef.current = null;
216
+ firstEightDigitsRef.current = '';
217
+ }
218
+
219
+ if (cardBinJsonRef.current !== null) {
220
+ completeResponse.card_network = cardBinJsonRef.current.scheme;
221
+ }
222
+ let luhnStatus = luhnCheck(textWithoutSpaces);
223
+ if (luhnStatus) {
224
+ completeResponse.luhn_check_info = 'SUCCESS';
225
+ if (textWithoutSpaces && textWithoutSpaces.length > 4) {
226
+ completeResponse.last_four_digit = textWithoutSpaces.substring(
227
+ textWithoutSpaces.length - 4
228
+ );
229
+ }
230
+ } else {
231
+ completeResponse.luhn_check_info = 'FAIL';
232
+ }
233
+ completeResponse.card_length = textWithoutSpaces.length;
234
+
235
+ return cardListener(JSON.stringify(completeResponse));
236
+ },
237
+ [cfSession, cardListener]
238
+ );
239
+
240
+ const doPayment = (cardInfo: ElementCard) => {
241
+ try {
242
+ let cfCardNumber = inputNumberRef.current;
243
+ cardInfo.cardNumber = cfCardNumber.replaceAll(' ', '');
244
+ const cardPayment = new CFCardPayment(sessionRef.current, cardInfo);
245
+ CFPaymentGatewayService.makePayment(cardPayment,"https://65da-163-116-214-55.ngrok-free.app");
246
+ } catch (e: any) {
247
+ console.log(e.message);
248
+ }
249
+ };
250
+
251
+ const doPaymentWithPaymentSessionId = (
252
+ cardInfo: ElementCard,
253
+ session: CFSession
254
+ ) => {
255
+ try {
256
+ sessionRef.current = session;
257
+ doPayment(cardInfo);
258
+ } catch (e: any) {
259
+ console.log(e.message);
260
+ }
261
+ };
262
+
263
+ const handleSubmitEditingEvent = (event: any) => {
264
+ const newEvent = { ...event };
265
+ delete newEvent.nativeEvent.text;
266
+ if (onSubmitEditing) {
267
+ onSubmitEditing(newEvent);
268
+ }
269
+ };
270
+
271
+ const handleEndEditingEvent = (event: any) => {
272
+ const newEvent = { ...event };
273
+ delete newEvent.nativeEvent.text;
274
+ if (onEndEditing) {
275
+ onEndEditing(newEvent);
276
+ }
277
+ };
278
+
279
+ const handleFocusEvent = (event: any) => {
280
+ const newEvent = { ...event };
281
+ delete newEvent.nativeEvent.text;
282
+ if (onFocus) {
283
+ onFocus(newEvent);
284
+ }
285
+ };
286
+
287
+ const handleBlurEvent = (event: any) => {
288
+ const newEvent = { ...event };
289
+ delete newEvent.nativeEvent.text;
290
+ if (onBlur) {
291
+ onBlur(newEvent);
292
+ }
293
+ };
294
+
295
+ const InputComponent: any = TextInput;
296
+ const {
297
+ onChangeText,
298
+ onChange,
299
+ onSubmitEditing,
300
+ onEndEditing,
301
+ onFocus,
302
+ onBlur,
303
+ ...otherProps
304
+ } = props;
305
+
306
+ return (
307
+ <InputComponent
308
+ keyboardType="numeric"
309
+ inputMode={'numeric'}
310
+ value={inputNumber}
311
+ onChangeText={handleChange}
312
+ onSubmitEditing={handleSubmitEditingEvent}
313
+ onEndEditing={handleEndEditingEvent}
314
+ onFocus={handleFocusEvent}
315
+ onBlur={handleBlurEvent}
316
+ style={style}
317
+ {...otherProps}
318
+ />
319
+ );
320
+ }
321
+ );
322
+
323
+ export default CardInput;
@@ -0,0 +1 @@
1
+ export { default } from './CFCardComponent';
@@ -0,0 +1 @@
1
+ export { default } from './CFCardComponent';
package/src/index.js ADDED
@@ -0,0 +1,167 @@
1
+ import { NativeAppEventEmitter, NativeEventEmitter, NativeModules, Platform, } from 'react-native';
2
+ import { version } from '../package.json';
3
+ import { CFUPIPayment, CFCardPayment } from 'cashfree-pg-api-contract';
4
+ import CFCardComponent from './Card/CFCardComponent';
5
+ const LINKING_ERROR = `The package 'react-native-cashfree-cn-api' doesn't seem to be linked. Make sure: \n\n` +
6
+ Platform.select({ ios: '- You have run \'pod install\'\n', default: '' }) +
7
+ '- You rebuilt the app after installing the package\n' +
8
+ '- You are not using Expo managed workflow\n';
9
+ const CashfreePgApi = NativeModules.CashfreePgApi
10
+ ? NativeModules.CashfreePgApi
11
+ : new Proxy({}, {
12
+ get() {
13
+ throw new Error(LINKING_ERROR);
14
+ },
15
+ });
16
+ class CFPaymentGateway {
17
+ emitter;
18
+ successSubscription = null;
19
+ failureSubscription = null;
20
+ eventSubscription = null;
21
+ upiAppsSubscription = null;
22
+ constructor() {
23
+ this.emitter =
24
+ Platform.OS === 'ios'
25
+ ? new NativeEventEmitter(NativeModules.CashfreeEventEmitter)
26
+ : NativeAppEventEmitter;
27
+ }
28
+ doPayment(checkoutPayment, baseUrl) {
29
+ checkoutPayment.version = version;
30
+ CashfreePgApi.doPayment(JSON.stringify(checkoutPayment), baseUrl);
31
+ }
32
+ doUPIPayment(checkoutPayment, baseUrl) {
33
+ checkoutPayment.version = version;
34
+ CashfreePgApi.doUPIPayment(JSON.stringify(checkoutPayment), baseUrl);
35
+ }
36
+ doWebPayment(cfSession, baseUrl) {
37
+ CashfreePgApi.doWebPayment(JSON.stringify(cfSession), baseUrl);
38
+ }
39
+ /**
40
+ * @deprecated : Instead call makePayment
41
+ */
42
+ doCardPayment(cardPayment, baseUrl) {
43
+ this.makePayment(cardPayment, baseUrl);
44
+ }
45
+ async getInstalledUpiApps() {
46
+ return new Promise((resolve, reject) => {
47
+ if (Platform.OS === 'ios') {
48
+ let fetchUpiList = (apps) => {
49
+ console.log(JSON.stringify(apps));
50
+ if (apps) {
51
+ resolve(apps);
52
+ }
53
+ else {
54
+ reject('No UPI apps found');
55
+ }
56
+ };
57
+ this.upiAppsSubscription = this.emitter.addListener('cfUpiApps', fetchUpiList);
58
+ CashfreePgApi.getInstalledUpiApps();
59
+ }
60
+ else {
61
+ CashfreePgApi.getInstalledUpiApps((apps) => {
62
+ if (apps) {
63
+ resolve(apps);
64
+ }
65
+ else {
66
+ reject('No UPI apps found');
67
+ }
68
+ });
69
+ }
70
+ });
71
+ }
72
+ makePayment(cfPayment, baseUrl) {
73
+ cfPayment.version = version;
74
+ const paymentData = JSON.stringify(cfPayment);
75
+ if (cfPayment instanceof CFUPIPayment) {
76
+ CashfreePgApi.doElementUPIPayment(paymentData, baseUrl);
77
+ }
78
+ else if (cfPayment instanceof CFCardPayment) {
79
+ CashfreePgApi.doCardPayment(paymentData, baseUrl);
80
+ }
81
+ else {
82
+ console.log('makePayment::==> Wrong payment object');
83
+ }
84
+ }
85
+ setEventSubscriber(cfEventCallback) {
86
+ let eventFunction = (event) => {
87
+ console.log(JSON.stringify(event));
88
+ let data = JSON.parse(event);
89
+ cfEventCallback.onReceivedEvent(data.eventName, data.meta);
90
+ };
91
+ this.eventSubscription = this.emitter.addListener('cfEvent', eventFunction);
92
+ CashfreePgApi.setEventSubscriber();
93
+ }
94
+ removeEventSubscriber() {
95
+ if (this.eventSubscription !== undefined &&
96
+ this.eventSubscription !== null) {
97
+ this.eventSubscription.remove();
98
+ this.eventSubscription = null;
99
+ }
100
+ CashfreePgApi.removeEventSubscriber();
101
+ }
102
+ setCallback(cfCallback) {
103
+ // this.cfCallback = cfCallback;
104
+ let successFunction = (orderID) => {
105
+ console.log('response is : ' + JSON.stringify(orderID));
106
+ cfCallback.onVerify(orderID);
107
+ };
108
+ let failureFunction = (error) => {
109
+ console.log('reason: ' + JSON.stringify(error));
110
+ const response = new CFErrorResponse();
111
+ // @ts-ignore
112
+ const message = JSON.parse(error);
113
+ response.fromJSON(message.error);
114
+ // @ts-ignore
115
+ cfCallback.onError(response, message.orderID);
116
+ };
117
+ this.successSubscription = this.emitter.addListener('cfSuccess', successFunction);
118
+ this.failureSubscription = this.emitter.addListener('cfFailure', failureFunction);
119
+ CashfreePgApi.setCallback();
120
+ }
121
+ removeCallback() {
122
+ if (this.successSubscription !== undefined &&
123
+ this.successSubscription !== null) {
124
+ this.successSubscription.remove();
125
+ this.successSubscription = null;
126
+ }
127
+ if (this.failureSubscription !== undefined &&
128
+ this.failureSubscription !== null) {
129
+ this.failureSubscription.remove();
130
+ this.failureSubscription = null;
131
+ }
132
+ if (this.upiAppsSubscription !== undefined &&
133
+ this.upiAppsSubscription !== null) {
134
+ this.upiAppsSubscription.remove();
135
+ this.upiAppsSubscription = null;
136
+ }
137
+ }
138
+ }
139
+ export class CFErrorResponse {
140
+ status = 'FAILED';
141
+ message = 'payment has failed';
142
+ code = 'payment_failed';
143
+ type = 'request_failed';
144
+ fromJSON(errorString) {
145
+ console.log('errorString :' + errorString);
146
+ const object = JSON.parse(errorString);
147
+ console.log('errorStringObject :' + object);
148
+ this.status = object.status;
149
+ this.message = object.message;
150
+ this.code = object.code;
151
+ this.type = object.type;
152
+ }
153
+ getStatus() {
154
+ return this.status;
155
+ }
156
+ getMessage() {
157
+ return this.message;
158
+ }
159
+ getCode() {
160
+ return this.code;
161
+ }
162
+ getType() {
163
+ return this.type;
164
+ }
165
+ }
166
+ export const CFCard = CFCardComponent;
167
+ export const CFPaymentGatewayService = new CFPaymentGateway();
package/src/index.ts ADDED
@@ -0,0 +1,219 @@
1
+ import {
2
+ EmitterSubscription,
3
+ EventEmitter,
4
+ NativeAppEventEmitter,
5
+ NativeEventEmitter,
6
+ NativeModules,
7
+ Platform,
8
+ } from 'react-native';
9
+ import { version } from '../package.json';
10
+ import { type CheckoutPayment, type CFSession, CFUPIPayment, CFCardPayment } from 'cashfree-pg-api-contract';
11
+ import CFCardComponent from './Card/CFCardComponent';
12
+
13
+ const LINKING_ERROR =
14
+ `The package 'react-native-cashfree-cn-api' doesn't seem to be linked. Make sure: \n\n` +
15
+ Platform.select({ ios: '- You have run \'pod install\'\n', default: '' }) +
16
+ '- You rebuilt the app after installing the package\n' +
17
+ '- You are not using Expo managed workflow\n';
18
+
19
+ const CashfreePgApi = NativeModules.CashfreePgApi
20
+ ? NativeModules.CashfreePgApi
21
+ : new Proxy(
22
+ {},
23
+ {
24
+ get() {
25
+ throw new Error(LINKING_ERROR);
26
+ },
27
+ },
28
+ );
29
+
30
+ class CFPaymentGateway {
31
+ private emitter: EventEmitter;
32
+ private successSubscription: EmitterSubscription | null = null;
33
+ private failureSubscription: EmitterSubscription | null = null;
34
+ private eventSubscription: EmitterSubscription | null = null;
35
+ private upiAppsSubscription: EmitterSubscription | null = null;
36
+
37
+ constructor() {
38
+ this.emitter =
39
+ Platform.OS === 'ios'
40
+ ? new NativeEventEmitter(NativeModules.CashfreeEventEmitter)
41
+ : NativeAppEventEmitter;
42
+ }
43
+
44
+ doPayment(checkoutPayment: CheckoutPayment,baseUrl: String) {
45
+ checkoutPayment.version = version;
46
+ CashfreePgApi.doPayment(JSON.stringify(checkoutPayment),baseUrl);
47
+ }
48
+
49
+ doUPIPayment(checkoutPayment: CheckoutPayment,baseUrl: String) {
50
+ checkoutPayment.version = version;
51
+ CashfreePgApi.doUPIPayment(JSON.stringify(checkoutPayment),baseUrl);
52
+ }
53
+
54
+ doWebPayment(cfSession: CFSession,baseUrl: String) {
55
+ CashfreePgApi.doWebPayment(JSON.stringify(cfSession),baseUrl);
56
+ }
57
+
58
+ /**
59
+ * @deprecated : Instead call makePayment
60
+ */
61
+ doCardPayment(cardPayment: CheckoutPayment,baseUrl: String) {
62
+ this.makePayment(cardPayment,baseUrl);
63
+ }
64
+
65
+ async getInstalledUpiApps() {
66
+ return new Promise((resolve, reject) => {
67
+ if(Platform.OS === 'ios'){
68
+ let fetchUpiList = (apps: string) => {
69
+ console.log(JSON.stringify(apps));
70
+ if (apps) {
71
+ resolve(apps);
72
+ } else {
73
+ reject('No UPI apps found');
74
+ }
75
+ };
76
+ this.upiAppsSubscription = this.emitter.addListener('cfUpiApps', fetchUpiList);
77
+ CashfreePgApi.getInstalledUpiApps()
78
+ }
79
+ else {
80
+ CashfreePgApi.getInstalledUpiApps((apps: string) => {
81
+ if (apps) {
82
+ resolve(apps);
83
+ } else {
84
+ reject('No UPI apps found');
85
+ }
86
+ });
87
+ }
88
+ });
89
+ }
90
+
91
+ makePayment(cfPayment: CheckoutPayment,baseUrl: String) {
92
+ cfPayment.version = version;
93
+ const paymentData = JSON.stringify(cfPayment);
94
+ if (cfPayment instanceof CFUPIPayment) {
95
+ CashfreePgApi.doElementUPIPayment(paymentData,baseUrl);
96
+ } else if (cfPayment instanceof CFCardPayment) {
97
+ CashfreePgApi.doCardPayment(paymentData,baseUrl);
98
+ } else {
99
+ console.log('makePayment::==> Wrong payment object');
100
+ }
101
+ }
102
+
103
+ setEventSubscriber(cfEventCallback: CFEventCallback) {
104
+ let eventFunction = (event: string) => {
105
+ console.log(JSON.stringify(event));
106
+ let data = JSON.parse(event);
107
+ cfEventCallback.onReceivedEvent(data.eventName, data.meta);
108
+ };
109
+ this.eventSubscription = this.emitter.addListener('cfEvent', eventFunction);
110
+ CashfreePgApi.setEventSubscriber();
111
+ }
112
+
113
+ removeEventSubscriber() {
114
+ if (
115
+ this.eventSubscription !== undefined &&
116
+ this.eventSubscription !== null
117
+ ) {
118
+ this.eventSubscription.remove();
119
+ this.eventSubscription = null;
120
+ }
121
+ CashfreePgApi.removeEventSubscriber();
122
+ }
123
+
124
+ setCallback(cfCallback: CFCallback) {
125
+ // this.cfCallback = cfCallback;
126
+ let successFunction = (orderID: string) => {
127
+ console.log('response is : ' + JSON.stringify(orderID));
128
+ cfCallback.onVerify(orderID);
129
+ };
130
+ let failureFunction = (error: string) => {
131
+ console.log('reason: ' + JSON.stringify(error));
132
+ const response = new CFErrorResponse();
133
+ // @ts-ignore
134
+ const message = JSON.parse(error);
135
+ response.fromJSON(message.error);
136
+ // @ts-ignore
137
+ cfCallback.onError(response, message.orderID);
138
+ };
139
+ this.successSubscription = this.emitter.addListener(
140
+ 'cfSuccess',
141
+ successFunction,
142
+ );
143
+ this.failureSubscription = this.emitter.addListener(
144
+ 'cfFailure',
145
+ failureFunction,
146
+ );
147
+ CashfreePgApi.setCallback();
148
+ }
149
+
150
+ removeCallback() {
151
+ if (
152
+ this.successSubscription !== undefined &&
153
+ this.successSubscription !== null
154
+ ) {
155
+ this.successSubscription.remove();
156
+ this.successSubscription = null;
157
+ }
158
+ if (
159
+ this.failureSubscription !== undefined &&
160
+ this.failureSubscription !== null
161
+ ) {
162
+ this.failureSubscription.remove();
163
+ this.failureSubscription = null;
164
+ }
165
+ if (
166
+ this.upiAppsSubscription !== undefined &&
167
+ this.upiAppsSubscription !== null
168
+ ) {
169
+ this.upiAppsSubscription.remove();
170
+ this.upiAppsSubscription = null;
171
+ }
172
+ }
173
+ }
174
+
175
+ export interface CFCallback {
176
+ onVerify(orderID: string): void;
177
+
178
+ onError(error: CFErrorResponse, orderID: string): void;
179
+ }
180
+
181
+ export interface CFEventCallback {
182
+ onReceivedEvent(eventName: string, map: Map<string, string>): void;
183
+ }
184
+
185
+ export class CFErrorResponse {
186
+ private status: string = 'FAILED';
187
+ private message: string = 'payment has failed';
188
+ private code: string = 'payment_failed';
189
+ private type: string = 'request_failed';
190
+
191
+ fromJSON(errorString: string) {
192
+ console.log('errorString :' + errorString);
193
+ const object = JSON.parse(errorString);
194
+ console.log('errorStringObject :' + object);
195
+ this.status = object.status;
196
+ this.message = object.message;
197
+ this.code = object.code;
198
+ this.type = object.type;
199
+ }
200
+
201
+ getStatus(): string {
202
+ return this.status;
203
+ }
204
+
205
+ getMessage(): string {
206
+ return this.message;
207
+ }
208
+
209
+ getCode(): string {
210
+ return this.code;
211
+ }
212
+
213
+ getType(): string {
214
+ return this.type;
215
+ }
216
+ }
217
+
218
+ export const CFCard = CFCardComponent
219
+ export const CFPaymentGatewayService = new CFPaymentGateway();