@finspringinnovations/fdsdk 0.0.3 → 0.0.5
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.
- package/lib/api/baseApi.js +17 -6
- package/lib/api/masterDataApi.js +21 -1
- package/lib/api/workflowApi.js +46 -1
- package/lib/assets/images/images.d.ts +1 -0
- package/lib/assets/images/images.js +1 -0
- package/lib/components/FDCard.js +9 -0
- package/lib/hooks/usePaymentSSE.d.ts +7 -1
- package/lib/hooks/usePaymentSSE.js +101 -12
- package/lib/navigation/RootNavigator.d.ts +1 -0
- package/lib/navigation/RootNavigator.js +12 -4
- package/lib/navigation/index.d.ts +1 -0
- package/lib/navigation/index.js +2 -2
- package/lib/screens/AadhaarVerification.js +2 -2
- package/lib/screens/FDCalculator.d.ts +1 -0
- package/lib/screens/FDCalculator.js +11 -4
- package/lib/screens/FDList.js +37 -64
- package/lib/screens/Payment.js +42 -28
- package/lib/screens/PaymentStatus.js +24 -26
- package/lib/screens/ReviewKYC.js +45 -97
- package/package.json +1 -1
- package/src/api/baseApi.ts +19 -6
- package/src/api/masterDataApi.ts +21 -3
- package/src/api/workflowApi.ts +50 -1
- package/src/assets/images/images.js +1 -0
- package/src/assets/images/shriram.png +0 -0
- package/src/components/FDCard.tsx +15 -0
- package/src/hooks/usePaymentSSE.ts +109 -15
- package/src/navigation/RootNavigator.tsx +12 -3
- package/src/navigation/index.tsx +3 -1
- package/src/screens/AadhaarVerification.tsx +2 -2
- package/src/screens/FDCalculator.tsx +12 -4
- package/src/screens/FDList.tsx +37 -76
- package/src/screens/Payment.tsx +45 -35
- package/src/screens/PaymentStatus.tsx +25 -40
- package/src/screens/ReviewKYC.tsx +94 -170
package/lib/api/baseApi.js
CHANGED
|
@@ -237,7 +237,7 @@ const generateRequestId = () => (0, uuid_1.v4)();
|
|
|
237
237
|
// Custom Base Query with Encryption
|
|
238
238
|
// ------------------------------
|
|
239
239
|
const baseQueryWithEncryption = async (args, api, extraOptions) => {
|
|
240
|
-
var _a, _b, _c, _d, _e, _f
|
|
240
|
+
var _a, _b, _c, _d, _e, _f;
|
|
241
241
|
const apiConfig = ensureApiConfig(); // 👈 Load config before first API call
|
|
242
242
|
const encryptionConfig = (0, encryptionConfig_1.getEncryptionConfig)();
|
|
243
243
|
const requestId = generateRequestId();
|
|
@@ -295,6 +295,10 @@ const baseQueryWithEncryption = async (args, api, extraOptions) => {
|
|
|
295
295
|
timeout: apiConfig.timeout,
|
|
296
296
|
prepareHeaders: (headers, { getState }) => {
|
|
297
297
|
var _a, _b;
|
|
298
|
+
// Disable HTTP-level caching for all SDK API calls
|
|
299
|
+
headers.set('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
300
|
+
headers.set('Pragma', 'no-cache');
|
|
301
|
+
headers.set('Expires', '0');
|
|
298
302
|
const token = (_b = (_a = getState()) === null || _a === void 0 ? void 0 : _a.auth) === null || _b === void 0 ? void 0 : _b.token;
|
|
299
303
|
if (token)
|
|
300
304
|
headers.set('authorization', `Bearer ${token}`);
|
|
@@ -391,9 +395,13 @@ const baseQueryWithEncryption = async (args, api, extraOptions) => {
|
|
|
391
395
|
}
|
|
392
396
|
// Log response
|
|
393
397
|
const duration = Date.now() - timestamp;
|
|
398
|
+
const statusFromMeta = (_b = (_a = result.meta) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.status;
|
|
399
|
+
const statusFromError = typeof ((_c = result.error) === null || _c === void 0 ? void 0 : _c.status) === 'number' ? result.error.status : undefined;
|
|
400
|
+
const status = (_d = statusFromMeta !== null && statusFromMeta !== void 0 ? statusFromMeta : statusFromError) !== null && _d !== void 0 ? _d : (result.error ? 0 : 200);
|
|
401
|
+
const statusText = ((_f = (_e = result.meta) === null || _e === void 0 ? void 0 : _e.response) === null || _f === void 0 ? void 0 : _f.statusText) || (result.error ? 'ERROR' : 'OK');
|
|
394
402
|
const responseLogData = {
|
|
395
|
-
status
|
|
396
|
-
statusText
|
|
403
|
+
status,
|
|
404
|
+
statusText,
|
|
397
405
|
headers: {},
|
|
398
406
|
data: result.data,
|
|
399
407
|
timestamp: Date.now(),
|
|
@@ -405,8 +413,7 @@ const baseQueryWithEncryption = async (args, api, extraOptions) => {
|
|
|
405
413
|
apiLogger_1.apiLogger.logResponse(responseLogData);
|
|
406
414
|
// Log response details in DEV mode (AFTER decryption)
|
|
407
415
|
if (__DEV__) {
|
|
408
|
-
const
|
|
409
|
-
const isSuccess = status >= 200 && status < 300;
|
|
416
|
+
const isSuccess = !result.error && status >= 200 && status < 300;
|
|
410
417
|
console.log('═══════════════════════════════════════════════════════════════');
|
|
411
418
|
console.log(isSuccess ? '✅ [ShriramSDK] API RESPONSE - SUCCESS' : '❌ [ShriramSDK] API RESPONSE - ERROR');
|
|
412
419
|
console.log('───────────────────────────────────────────────────────────────');
|
|
@@ -414,7 +421,7 @@ const baseQueryWithEncryption = async (args, api, extraOptions) => {
|
|
|
414
421
|
console.log('🔗 Endpoint:', url);
|
|
415
422
|
console.log('📌 Full URL:', `${apiConfig.baseUrl}${url}`);
|
|
416
423
|
console.log('🔧 Method:', method);
|
|
417
|
-
console.log('📊 Status:', status,
|
|
424
|
+
console.log('📊 Status:', status, statusText);
|
|
418
425
|
console.log('⏱️ Duration:', `${duration}ms`);
|
|
419
426
|
console.log('🔐 Encryption:', currentEncryptionState ? 'Enabled' : 'Disabled');
|
|
420
427
|
console.log('🆔 Request ID:', requestId);
|
|
@@ -451,6 +458,10 @@ exports.baseApi = (0, react_1.createApi)({
|
|
|
451
458
|
baseQuery: baseQueryWithEncryption,
|
|
452
459
|
tagTypes: ['InterestRate'],
|
|
453
460
|
endpoints: () => ({}),
|
|
461
|
+
keepUnusedDataFor: 0,
|
|
462
|
+
refetchOnMountOrArgChange: true,
|
|
463
|
+
refetchOnFocus: true,
|
|
464
|
+
refetchOnReconnect: true,
|
|
454
465
|
});
|
|
455
466
|
// Export hooks
|
|
456
467
|
exports.usePrefetch = exports.baseApi.usePrefetch;
|
package/lib/api/masterDataApi.js
CHANGED
|
@@ -13,17 +13,37 @@ exports.masterDataApi = baseApi_1.baseApi.injectEndpoints({
|
|
|
13
13
|
const request = {
|
|
14
14
|
url: 'masterdata',
|
|
15
15
|
method: 'GET',
|
|
16
|
+
cache: 'no-store',
|
|
16
17
|
headers: {
|
|
17
18
|
workflowInstanceId: '{{workflowInstanceId}}',
|
|
18
19
|
'x-api-key': '{{X-API-KEY}}',
|
|
19
20
|
encryptdecrypt: 'false',
|
|
21
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
22
|
+
Pragma: 'no-cache',
|
|
23
|
+
Expires: '0',
|
|
20
24
|
provider: providerId || '{{shriramprovider}}',
|
|
21
25
|
},
|
|
22
26
|
};
|
|
23
27
|
return request;
|
|
24
28
|
},
|
|
25
29
|
transformResponse: (response) => {
|
|
26
|
-
|
|
30
|
+
if (response == null)
|
|
31
|
+
return response;
|
|
32
|
+
// If API returns a JSON string, parse it
|
|
33
|
+
let data = response;
|
|
34
|
+
if (typeof response === 'string') {
|
|
35
|
+
try {
|
|
36
|
+
data = JSON.parse(response);
|
|
37
|
+
}
|
|
38
|
+
catch (_a) {
|
|
39
|
+
return response;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Unwrap { data: ... } so consumers get a consistent shape
|
|
43
|
+
if (typeof data === 'object' && data !== null && 'data' in data && Object.keys(data).length === 1) {
|
|
44
|
+
return data.data;
|
|
45
|
+
}
|
|
46
|
+
return data;
|
|
27
47
|
},
|
|
28
48
|
}),
|
|
29
49
|
}),
|
package/lib/api/workflowApi.js
CHANGED
|
@@ -13,6 +13,37 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.usePreviousStateMutation = exports.useUpdateStateMutation = exports.useUpdateTaskMutation = exports.useTerminateWorkflowMutation = exports.workflowApi = void 0;
|
|
15
15
|
const baseApi_1 = require("./baseApi");
|
|
16
|
+
const TASK_ID_TO_CAPTION = {
|
|
17
|
+
'11042': 'SHRIRAM_V1_S1_T1_START',
|
|
18
|
+
'11043': 'SHRIRAM_V1_S1_T2_GET_PERSONAL_DETAILS_AND_BASIC_FD_INFO',
|
|
19
|
+
'11044': 'SHRIRAM_V1_S1_T3_END',
|
|
20
|
+
'11050': 'SHRIRAM_V1_S2_T1_KYC_START',
|
|
21
|
+
'11051': 'SHRIRAM_V1_S2_T2_CHECK_FOR_PAN_RAPID_STATUS',
|
|
22
|
+
'11052': 'SHRIRAM_V1_S2_T3_CHECK_IF_AADHAAR_ALREADY_VERIFIED',
|
|
23
|
+
'11045': 'SHRIRAM_V1_S2_T4_SEND_AADHAR_OTP',
|
|
24
|
+
'11046': 'SHRIRAM_V1_S2_T5_CHECK_FOR_OTP',
|
|
25
|
+
'11047': 'SHRIRAM_V1_S2_T6_VALIDATE_AADHAR_OTP',
|
|
26
|
+
'11053': 'SHRIRAM_V1_S2_T7_AADHAAR_VERIFIED',
|
|
27
|
+
'11049': 'SHRIRAM_V1_S2_T8_TERMINATE_TASK_AND_WORKFLOW_AFTER_KYC_RETRIES',
|
|
28
|
+
'11048': 'SHRIRAM_V1_S2_T9_KYC_END',
|
|
29
|
+
'11054': 'SHRIRAM_V1_S3_T1_OCCUPATION_START',
|
|
30
|
+
'11055': 'SHRIRAM_V1_S3_T2_CAPTURE_OCCUPATION_DETAILS',
|
|
31
|
+
'11056': 'SHRIRAM_V1_S3_T3_OCCUPATION_END',
|
|
32
|
+
'11057': 'SHRIRAM_V1_S4_T1_NOMINEE_START',
|
|
33
|
+
'11058': 'SHRIRAM_V1_S4_T2_CAPTURE_NOMINEE_DETAILS',
|
|
34
|
+
'11059': 'SHRIRAM_V1_S4_T3_NOMINEE_END',
|
|
35
|
+
'11060': 'SHRIRAM_V1_S5_T1_BANK_DETAILS_START',
|
|
36
|
+
'11061': 'SHRIRAM_V1_S5_T2_CAPTURE_BANK_DETAILS',
|
|
37
|
+
'11062': 'SHRIRAM_V1_S5_T3_BANK_DETAILS_END',
|
|
38
|
+
'11063': 'SHRIRAM_V1_S6_T1_FD_CREATION_START',
|
|
39
|
+
'11064': 'SHRIRAM_V1_S6_T2_CREATE_FD',
|
|
40
|
+
'11065': 'SHRIRAM_V1_S6_T3_FD_CREATION_END',
|
|
41
|
+
'11069': 'SHRIRAM_V1_S7_T1_PAYMENT_START',
|
|
42
|
+
'11068': 'SHRIRAM_V1_S7_T2_PAYMENT',
|
|
43
|
+
'11067': 'SHRIRAM_V1_S7_T3_CHECK_FOR_PAYMENT_STATUS',
|
|
44
|
+
'11070': 'SHRIRAM_V1_S7_T4_TERMINATE_TASK_AND_WORKFLOW_AFTER_PAYMENT_RETRIES',
|
|
45
|
+
'11066': 'SHRIRAM_V1_S7_T5_PAYMENT_END',
|
|
46
|
+
};
|
|
16
47
|
exports.workflowApi = baseApi_1.baseApi.injectEndpoints({
|
|
17
48
|
endpoints: (builder) => ({
|
|
18
49
|
terminateWorkflow: builder.mutation({
|
|
@@ -37,10 +68,24 @@ exports.workflowApi = baseApi_1.baseApi.injectEndpoints({
|
|
|
37
68
|
updateTask: builder.mutation({
|
|
38
69
|
query: (body) => {
|
|
39
70
|
const { providerId, workflowInstanceId, userreferenceid, applicationid, entityid } = body, requestBody = __rest(body, ["providerId", "workflowInstanceId", "userreferenceid", "applicationid", "entityid"]);
|
|
71
|
+
const normalizedRequestBody = Object.assign({}, requestBody);
|
|
72
|
+
// Backend now expects caption-based field name.
|
|
73
|
+
// Keep compatibility if any caller still passes targetTaskId.
|
|
74
|
+
if (!normalizedRequestBody.targetTaskCaption && normalizedRequestBody.targetTaskId) {
|
|
75
|
+
normalizedRequestBody.targetTaskCaption = normalizedRequestBody.targetTaskId;
|
|
76
|
+
delete normalizedRequestBody.targetTaskId;
|
|
77
|
+
}
|
|
78
|
+
// Normalize numeric task IDs to caption values if provided.
|
|
79
|
+
if (normalizedRequestBody.targetTaskCaption !== undefined && normalizedRequestBody.targetTaskCaption !== null) {
|
|
80
|
+
const key = String(normalizedRequestBody.targetTaskCaption).trim();
|
|
81
|
+
if (TASK_ID_TO_CAPTION[key]) {
|
|
82
|
+
normalizedRequestBody.targetTaskCaption = TASK_ID_TO_CAPTION[key];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
40
85
|
return {
|
|
41
86
|
url: 'taskflow/update',
|
|
42
87
|
method: 'POST',
|
|
43
|
-
body: Object.assign(Object.assign({},
|
|
88
|
+
body: Object.assign(Object.assign({}, normalizedRequestBody), { workflowInstanceId: workflowInstanceId }),
|
|
44
89
|
headers: {
|
|
45
90
|
provider: providerId || '{{shriramprovider}}',
|
|
46
91
|
workflowInstanceId: workflowInstanceId || '{{workflowInstanceId}}',
|
package/lib/components/FDCard.js
CHANGED
|
@@ -7,6 +7,7 @@ const react_1 = __importDefault(require("react"));
|
|
|
7
7
|
const react_native_1 = require("react-native");
|
|
8
8
|
const ThemeContext_1 = require("../theme/ThemeContext");
|
|
9
9
|
const theme_1 = require("../theme");
|
|
10
|
+
const base64Images_1 = require("../constants/strings/base64Images");
|
|
10
11
|
const FDCard = ({ id, name, accountNumber, roi, tenure, amount, maturityDate, status, creditRating, onPress, customStyles = {}, }) => {
|
|
11
12
|
const colors = (0, ThemeContext_1.useColors)();
|
|
12
13
|
const typography = (0, ThemeContext_1.useTypography)();
|
|
@@ -31,6 +32,8 @@ const FDCard = ({ id, name, accountNumber, roi, tenure, amount, maturityDate, st
|
|
|
31
32
|
};
|
|
32
33
|
return (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.fdCard, customStyles.container], onPress: () => onPress === null || onPress === void 0 ? void 0 : onPress(id), activeOpacity: 0.8 },
|
|
33
34
|
react_1.default.createElement(react_native_1.View, { style: styles.fdCardHeader },
|
|
35
|
+
react_1.default.createElement(react_native_1.View, null,
|
|
36
|
+
react_1.default.createElement(react_native_1.Image, { source: { uri: base64Images_1.base64Images.shriramLogo }, style: styles.logo, resizeMode: "contain" })),
|
|
34
37
|
react_1.default.createElement(react_native_1.Text, { style: [styles.fdName, customStyles.name] }, name)),
|
|
35
38
|
react_1.default.createElement(react_native_1.View, { style: styles.fdDetailsRow },
|
|
36
39
|
react_1.default.createElement(react_native_1.View, { style: styles.fdDetailItem },
|
|
@@ -91,6 +94,12 @@ const createStyles = (colors, typography, spacing, shadows, themeName) => {
|
|
|
91
94
|
roiText: {
|
|
92
95
|
color: colors.success,
|
|
93
96
|
},
|
|
97
|
+
logo: {
|
|
98
|
+
width: 25,
|
|
99
|
+
height: 25,
|
|
100
|
+
marginRight: 5,
|
|
101
|
+
borderRadius: 15,
|
|
102
|
+
},
|
|
94
103
|
});
|
|
95
104
|
};
|
|
96
105
|
exports.default = FDCard;
|
|
@@ -17,8 +17,14 @@ interface UsePaymentSSECallbacks {
|
|
|
17
17
|
onError?: (error: any) => void;
|
|
18
18
|
onConnected?: () => void;
|
|
19
19
|
}
|
|
20
|
+
export interface PaymentSSEExtraHeaders {
|
|
21
|
+
workflowInstanceId?: string;
|
|
22
|
+
applicationId?: string;
|
|
23
|
+
entityid?: string;
|
|
24
|
+
providerId?: string;
|
|
25
|
+
}
|
|
20
26
|
export declare function usePaymentSSE(): {
|
|
21
|
-
start: (applicationId: string, callbacks: UsePaymentSSECallbacks) => void;
|
|
27
|
+
start: (applicationId: string, callbacks: UsePaymentSSECallbacks, extraHeaders?: PaymentSSEExtraHeaders) => void;
|
|
22
28
|
stop: () => void;
|
|
23
29
|
};
|
|
24
30
|
export {};
|
|
@@ -19,6 +19,8 @@ const react_1 = require("react");
|
|
|
19
19
|
const sseParser_1 = require("../utils/sseParser");
|
|
20
20
|
const appDataConfig_1 = require("../config/appDataConfig");
|
|
21
21
|
const apiConfig_1 = require("../config/apiConfig");
|
|
22
|
+
const encryption_1 = require("../utils/encryption");
|
|
23
|
+
const encryptionConfig_1 = require("../config/encryptionConfig");
|
|
22
24
|
// -- Hook --
|
|
23
25
|
function usePaymentSSE() {
|
|
24
26
|
// Store the XMLHttpRequest so we can abort it later
|
|
@@ -27,7 +29,7 @@ function usePaymentSSE() {
|
|
|
27
29
|
const lastIndexRef = (0, react_1.useRef)(0);
|
|
28
30
|
// SSE text buffer (persists across onprogress calls)
|
|
29
31
|
const bufferRef = (0, react_1.useRef)({ value: '' });
|
|
30
|
-
const start = (0, react_1.useCallback)((applicationId, callbacks) => {
|
|
32
|
+
const start = (0, react_1.useCallback)((applicationId, callbacks, extraHeaders) => {
|
|
31
33
|
var _a;
|
|
32
34
|
// Clean up any existing connection first
|
|
33
35
|
if (xhrRef.current) {
|
|
@@ -40,8 +42,13 @@ function usePaymentSSE() {
|
|
|
40
42
|
// 1. Build the SSE endpoint URL
|
|
41
43
|
const envData = (0, appDataConfig_1.getEnvironmentData)();
|
|
42
44
|
const apiConfig = (0, apiConfig_1.getApiConfig)();
|
|
43
|
-
const baseUrl = (envData === null || envData === void 0 ? void 0 : envData.apiBaseUrl) || (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.baseUrl) || '';
|
|
44
|
-
const url = `${baseUrl}/events?applicationId=${encodeURIComponent(applicationId)}
|
|
45
|
+
const baseUrl = ((envData === null || envData === void 0 ? void 0 : envData.apiBaseUrl) || (apiConfig === null || apiConfig === void 0 ? void 0 : apiConfig.baseUrl) || '').replace(/\/$/, '');
|
|
46
|
+
const url = baseUrl ? `${baseUrl}/events?applicationId=${encodeURIComponent(applicationId)}` : '';
|
|
47
|
+
if (!url) {
|
|
48
|
+
if (__DEV__)
|
|
49
|
+
console.warn('[usePaymentSSE] No base URL, skipping SSE');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
45
52
|
// 2. Create XMLHttpRequest
|
|
46
53
|
const xhr = new XMLHttpRequest();
|
|
47
54
|
xhrRef.current = xhr;
|
|
@@ -51,11 +58,49 @@ function usePaymentSSE() {
|
|
|
51
58
|
if (apiKey) {
|
|
52
59
|
xhr.setRequestHeader('x-api-key', apiKey);
|
|
53
60
|
}
|
|
61
|
+
// Add secure headers (Content-Type, User-Agent, etc.)
|
|
62
|
+
const secureHeaders = (0, apiConfig_1.getSecureHeaders)();
|
|
63
|
+
Object.entries(secureHeaders).forEach(([key, value]) => {
|
|
64
|
+
if (key.toLowerCase() !== 'content-type') {
|
|
65
|
+
xhr.setRequestHeader(key, value);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
// SSE-specific headers
|
|
54
69
|
xhr.setRequestHeader('Accept', 'text/event-stream');
|
|
55
|
-
xhr.setRequestHeader('Cache-Control', 'no-cache');
|
|
70
|
+
xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
71
|
+
xhr.setRequestHeader('Pragma', 'no-cache');
|
|
72
|
+
xhr.setRequestHeader('Expires', '0');
|
|
73
|
+
// Add userreferenceid header (required for authentication) - both cases
|
|
74
|
+
try {
|
|
75
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
76
|
+
const userRefId = (userInfo === null || userInfo === void 0 ? void 0 : userInfo.userReferenceId) || (userInfo === null || userInfo === void 0 ? void 0 : userInfo.id);
|
|
77
|
+
if (userRefId) {
|
|
78
|
+
xhr.setRequestHeader('userreferenceid', userRefId);
|
|
79
|
+
xhr.setRequestHeader('userReferenceId', userRefId);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (_b) {
|
|
83
|
+
if (__DEV__)
|
|
84
|
+
console.warn('[usePaymentSSE] Could not get userReferenceId');
|
|
85
|
+
}
|
|
86
|
+
// Add provider header (required for authentication)
|
|
87
|
+
if (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.providerId) {
|
|
88
|
+
xhr.setRequestHeader('provider', extraHeaders.providerId);
|
|
89
|
+
}
|
|
90
|
+
// Add onboarding headers - both camelCase and lowercase variants
|
|
91
|
+
if (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.workflowInstanceId) {
|
|
92
|
+
xhr.setRequestHeader('workflowInstanceId', extraHeaders.workflowInstanceId);
|
|
93
|
+
}
|
|
94
|
+
if (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.applicationId) {
|
|
95
|
+
xhr.setRequestHeader('applicationId', extraHeaders.applicationId);
|
|
96
|
+
xhr.setRequestHeader('applicationid', extraHeaders.applicationId);
|
|
97
|
+
}
|
|
98
|
+
if (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.entityid) {
|
|
99
|
+
xhr.setRequestHeader('entityid', extraHeaders.entityid);
|
|
100
|
+
xhr.setRequestHeader('entityId', extraHeaders.entityid);
|
|
101
|
+
}
|
|
56
102
|
// 4. Handle incoming data
|
|
57
103
|
xhr.onprogress = () => {
|
|
58
|
-
var _a;
|
|
59
104
|
// responseText contains ALL text received so far
|
|
60
105
|
// Only parse the NEW text since last call
|
|
61
106
|
const newText = xhr.responseText.slice(lastIndexRef.current);
|
|
@@ -64,18 +109,46 @@ function usePaymentSSE() {
|
|
|
64
109
|
return;
|
|
65
110
|
// Parse new text into SSE events
|
|
66
111
|
const events = (0, sseParser_1.parseSSEBuffer)(bufferRef.current, newText);
|
|
67
|
-
// Handle each event
|
|
112
|
+
// Handle each event (support encrypted payload like web)
|
|
113
|
+
const handleEventData = async (rawData) => {
|
|
114
|
+
var _a, _b;
|
|
115
|
+
try {
|
|
116
|
+
const parsed = JSON.parse(rawData || '{}');
|
|
117
|
+
let payload = parsed;
|
|
118
|
+
if (typeof (parsed === null || parsed === void 0 ? void 0 : parsed.encryptedResponse) === 'string' && parsed.encryptedResponse) {
|
|
119
|
+
try {
|
|
120
|
+
const config = (0, encryptionConfig_1.getEncryptionConfig)();
|
|
121
|
+
const decrypted = await (0, encryption_1.decryptResponse)({ encryptedResponse: parsed.encryptedResponse }, config);
|
|
122
|
+
payload = (decrypted || {});
|
|
123
|
+
}
|
|
124
|
+
catch (_c) {
|
|
125
|
+
if (__DEV__)
|
|
126
|
+
console.warn('[usePaymentSSE] Decrypt failed, using raw');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const status = String((_b = (_a = payload === null || payload === void 0 ? void 0 : payload.paymentStatus) !== null && _a !== void 0 ? _a : payload === null || payload === void 0 ? void 0 : payload.payment_status) !== null && _b !== void 0 ? _b : '').toUpperCase();
|
|
130
|
+
if (status)
|
|
131
|
+
callbacks.onPaymentStatus(status, payload);
|
|
132
|
+
}
|
|
133
|
+
catch (parseError) {
|
|
134
|
+
if (__DEV__)
|
|
135
|
+
console.error('[usePaymentSSE] Failed to parse event data:', parseError);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
68
138
|
for (const { eventType, data } of events) {
|
|
139
|
+
if (!data)
|
|
140
|
+
continue;
|
|
69
141
|
if (eventType === 'fd_payment_status') {
|
|
142
|
+
handleEventData(data);
|
|
143
|
+
}
|
|
144
|
+
else if (eventType === 'message') {
|
|
70
145
|
try {
|
|
71
146
|
const parsed = JSON.parse(data);
|
|
72
|
-
|
|
73
|
-
|
|
147
|
+
if ((parsed === null || parsed === void 0 ? void 0 : parsed.event) === 'fd_payment_status')
|
|
148
|
+
handleEventData(data);
|
|
74
149
|
}
|
|
75
|
-
catch (
|
|
76
|
-
|
|
77
|
-
console.error('[usePaymentSSE] Failed to parse event data:', parseError);
|
|
78
|
-
}
|
|
150
|
+
catch (_a) {
|
|
151
|
+
// ignore
|
|
79
152
|
}
|
|
80
153
|
}
|
|
81
154
|
}
|
|
@@ -118,6 +191,22 @@ function usePaymentSSE() {
|
|
|
118
191
|
xhr.send();
|
|
119
192
|
if (__DEV__) {
|
|
120
193
|
console.log('[usePaymentSSE] Starting SSE connection to:', url);
|
|
194
|
+
console.log('[usePaymentSSE] Headers:', {
|
|
195
|
+
'x-api-key': apiKey ? '***' : 'missing',
|
|
196
|
+
'userreferenceid': (() => {
|
|
197
|
+
try {
|
|
198
|
+
const userInfo = (0, appDataConfig_1.getUserInfoForAPI)();
|
|
199
|
+
return (userInfo === null || userInfo === void 0 ? void 0 : userInfo.userReferenceId) || (userInfo === null || userInfo === void 0 ? void 0 : userInfo.id) || 'missing';
|
|
200
|
+
}
|
|
201
|
+
catch (_a) {
|
|
202
|
+
return 'missing';
|
|
203
|
+
}
|
|
204
|
+
})(),
|
|
205
|
+
'provider': (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.providerId) || 'missing',
|
|
206
|
+
'workflowInstanceId': (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.workflowInstanceId) || 'missing',
|
|
207
|
+
'applicationId': (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.applicationId) || 'missing',
|
|
208
|
+
'entityid': (extraHeaders === null || extraHeaders === void 0 ? void 0 : extraHeaders.entityid) || 'missing',
|
|
209
|
+
});
|
|
121
210
|
}
|
|
122
211
|
}, []);
|
|
123
212
|
const stop = (0, react_1.useCallback)(() => {
|
|
@@ -3,6 +3,7 @@ import type { SDKNavigationConfig } from './types';
|
|
|
3
3
|
interface RootNavigatorProps {
|
|
4
4
|
config?: SDKNavigationConfig;
|
|
5
5
|
onExit?: (fdDetails?: any) => void;
|
|
6
|
+
onPanRequired?: () => void;
|
|
6
7
|
}
|
|
7
8
|
declare const RootNavigator: React.FC<RootNavigatorProps>;
|
|
8
9
|
export default RootNavigator;
|
|
@@ -57,7 +57,7 @@ const PaymentStatus_1 = __importDefault(require("../screens/PaymentStatus"));
|
|
|
57
57
|
const helpers_2 = require("./helpers");
|
|
58
58
|
const paymentSession_1 = require("../state/paymentSession");
|
|
59
59
|
const Stack = (0, stack_1.createStackNavigator)();
|
|
60
|
-
const RootNavigator = ({ config = {}, onExit }) => {
|
|
60
|
+
const RootNavigator = ({ config = {}, onExit, onPanRequired, }) => {
|
|
61
61
|
// Handle Android hardware back button
|
|
62
62
|
(0, react_1.useEffect)(() => {
|
|
63
63
|
if (react_native_1.Platform.OS !== 'android')
|
|
@@ -131,7 +131,7 @@ const RootNavigator = ({ config = {}, onExit }) => {
|
|
|
131
131
|
} }, props)))),
|
|
132
132
|
react_1.default.createElement(Stack.Screen, { name: "FDCalculator", options: { title: 'FD Calculator' } }, (props) => {
|
|
133
133
|
var _a;
|
|
134
|
-
return (react_1.default.createElement(FDCalculator_1.default, Object.assign({ onGoBack: () => (0, helpers_2.goBack)(), onExitSDK: () => onExit === null || onExit === void 0 ? void 0 : onExit(), onNavigateToReviewKYC: () => { var _a; return (0, helpers_2.navigate)('ReviewKYC', { fdData: (_a = props.route.params) === null || _a === void 0 ? void 0 : _a.fdData }); }, fdData: (_a = props.route.params) === null || _a === void 0 ? void 0 : _a.fdData }, props)));
|
|
134
|
+
return (react_1.default.createElement(FDCalculator_1.default, Object.assign({ onGoBack: () => (0, helpers_2.goBack)(), onExitSDK: () => onExit === null || onExit === void 0 ? void 0 : onExit(), onPanRequired: onPanRequired, onNavigateToReviewKYC: () => { var _a; return (0, helpers_2.navigate)('ReviewKYC', { fdData: (_a = props.route.params) === null || _a === void 0 ? void 0 : _a.fdData }); }, fdData: (_a = props.route.params) === null || _a === void 0 ? void 0 : _a.fdData }, props)));
|
|
135
135
|
}),
|
|
136
136
|
react_1.default.createElement(Stack.Screen, { name: "AadhaarVerification", options: { title: 'Aadhaar Verification' } }, (props) => (react_1.default.createElement(AadhaarVerification_1.default, Object.assign({ onGoBack: () => (0, helpers_2.goBack)(), onVerificationComplete: (aadhaarNumber) => {
|
|
137
137
|
// Navigate to Employee (occupation) screen after verification
|
|
@@ -181,14 +181,22 @@ const RootNavigator = ({ config = {}, onExit }) => {
|
|
|
181
181
|
}, fdData: (_a = props.route.params) === null || _a === void 0 ? void 0 : _a.fdData }, props)));
|
|
182
182
|
}),
|
|
183
183
|
react_1.default.createElement(Stack.Screen, { name: "Payment", options: { title: 'Payment' } }, (props) => (react_1.default.createElement(Payment_1.default, Object.assign({ onGoBack: () => (0, helpers_2.goBack)(), paymentUrl: ((0, paymentSession_1.getPaymentSession)().paymentUrl) || '', onPaymentSuccess: (data) => {
|
|
184
|
+
var _a, _b;
|
|
185
|
+
const payload = data && typeof data === 'object' ? data : {};
|
|
186
|
+
const transactionId = (_b = (_a = payload === null || payload === void 0 ? void 0 : payload.transactionId) !== null && _a !== void 0 ? _a : payload === null || payload === void 0 ? void 0 : payload.transaction_id) !== null && _b !== void 0 ? _b : payload === null || payload === void 0 ? void 0 : payload.TransactionId;
|
|
184
187
|
(0, helpers_2.navigate)('PaymentStatus', {
|
|
185
188
|
status: 'success',
|
|
186
|
-
paymentData: data
|
|
189
|
+
paymentData: data,
|
|
190
|
+
transactionId,
|
|
187
191
|
});
|
|
188
192
|
}, onPaymentFailure: (error) => {
|
|
193
|
+
var _a, _b;
|
|
194
|
+
const payload = error && typeof error === 'object' ? error : {};
|
|
195
|
+
const transactionId = (_b = (_a = payload === null || payload === void 0 ? void 0 : payload.transactionId) !== null && _a !== void 0 ? _a : payload === null || payload === void 0 ? void 0 : payload.transaction_id) !== null && _b !== void 0 ? _b : payload === null || payload === void 0 ? void 0 : payload.TransactionId;
|
|
189
196
|
(0, helpers_2.navigate)('PaymentStatus', {
|
|
190
197
|
status: 'failed',
|
|
191
|
-
paymentData: error
|
|
198
|
+
paymentData: error,
|
|
199
|
+
transactionId,
|
|
192
200
|
});
|
|
193
201
|
}, onPaymentPending: (info) => {
|
|
194
202
|
(0, helpers_2.navigate)('PaymentStatus', {
|
|
@@ -6,6 +6,7 @@ import { type CustomColors } from '../config/appDataConfig';
|
|
|
6
6
|
interface SDKNavigationContainerProps {
|
|
7
7
|
config?: SDKNavigationConfig;
|
|
8
8
|
onExit?: (fdDetails?: any) => void;
|
|
9
|
+
onPanRequired?: () => void;
|
|
9
10
|
children?: React.ReactNode;
|
|
10
11
|
theme?: ThemeName | Theme;
|
|
11
12
|
colors?: CustomColors;
|
package/lib/navigation/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const MasterDataProvider_1 = require("../providers/MasterDataProvider");
|
|
|
15
15
|
const helpers_1 = require("./helpers");
|
|
16
16
|
const appDataConfig_1 = require("../config/appDataConfig");
|
|
17
17
|
// Main navigation container for the SDK
|
|
18
|
-
const SDKNavigationContainer = ({ config, onExit, children, theme, colors: propColors, useReactNavigation = true, // Default to React Navigation
|
|
18
|
+
const SDKNavigationContainer = ({ config, onExit, onPanRequired, children, theme, colors: propColors, useReactNavigation = true, // Default to React Navigation
|
|
19
19
|
}) => {
|
|
20
20
|
// Merge color overrides: prop-level colors take priority over global SDK colors
|
|
21
21
|
const globalColors = (0, appDataConfig_1.getSDKColors)();
|
|
@@ -23,7 +23,7 @@ const SDKNavigationContainer = ({ config, onExit, children, theme, colors: propC
|
|
|
23
23
|
? Object.assign(Object.assign({}, (globalColors || {})), (propColors || {})) : null;
|
|
24
24
|
// Choose navigator based on flag
|
|
25
25
|
const navigator = useReactNavigation
|
|
26
|
-
? react_1.default.createElement(RootNavigator_1.default, { config: config, onExit: onExit })
|
|
26
|
+
? react_1.default.createElement(RootNavigator_1.default, { config: config, onExit: onExit, onPanRequired: onPanRequired })
|
|
27
27
|
: react_1.default.createElement(SimpleNavigator_1.default, { config: config, onExit: onExit });
|
|
28
28
|
const content = children || (useReactNavigation ? (react_1.default.createElement(native_1.NavigationContainer, { ref: helpers_1.navigationRef }, navigator)) : (navigator));
|
|
29
29
|
// Build ThemeProvider props
|
|
@@ -297,7 +297,7 @@ const AadhaarVerification = ({ onGoBack, onVerificationComplete, }) => {
|
|
|
297
297
|
applicationid: applicationId,
|
|
298
298
|
entityid: entityId,
|
|
299
299
|
// Request params/body
|
|
300
|
-
|
|
300
|
+
targetTaskCaption: workflowConstants_1.WORKFLOW_TASKS.VALIDATE_OTP,
|
|
301
301
|
}).unwrap();
|
|
302
302
|
setIsValidateOtpTaskCalled(true);
|
|
303
303
|
}
|
|
@@ -355,7 +355,7 @@ const AadhaarVerification = ({ onGoBack, onVerificationComplete, }) => {
|
|
|
355
355
|
applicationid: applicationId,
|
|
356
356
|
entityid: entityId,
|
|
357
357
|
// Request params/body
|
|
358
|
-
|
|
358
|
+
targetTaskCaption: workflowConstants_1.WORKFLOW_TASKS.RESEND_OTP,
|
|
359
359
|
}).unwrap();
|
|
360
360
|
// 2) Then call OTP API with the updateTask response
|
|
361
361
|
const response = await sendOtp({
|
|
@@ -55,7 +55,7 @@ const fdListSelectedSlice_1 = require("../store/fdListSelectedSlice");
|
|
|
55
55
|
const helpers_1 = require("../navigation/helpers");
|
|
56
56
|
const strings_1 = require("../constants/strings");
|
|
57
57
|
const base64Images_1 = require("../constants/strings/base64Images");
|
|
58
|
-
const FDCalculator = ({ onGoBack, onExitSDK, onNavigateToReviewKYC, fdData }) => {
|
|
58
|
+
const FDCalculator = ({ onGoBack, onExitSDK, onPanRequired, onNavigateToReviewKYC, fdData }) => {
|
|
59
59
|
const typography = (0, ThemeContext_1.useTypography)();
|
|
60
60
|
const colors = (0, ThemeContext_1.useColors)();
|
|
61
61
|
const { themeName } = (0, ThemeContext_1.useTheme)();
|
|
@@ -127,8 +127,12 @@ const FDCalculator = ({ onGoBack, onExitSDK, onNavigateToReviewKYC, fdData }) =>
|
|
|
127
127
|
const defaultProviderId = (0, store_1.useAppSelector)((state) => { var _a; return (_a = state === null || state === void 0 ? void 0 : state.onboarding) === null || _a === void 0 ? void 0 : _a.providerId; }); // Default Shriram provider ID
|
|
128
128
|
// Default Shriram provider ID
|
|
129
129
|
const { data: fallbackMasterData, isLoading: isLoadingFallback, error: fallbackError, refetch: refetchMasterData } = (0, masterDataApi_1.useGetMasterDataQuery)({ providerId: defaultProviderId }, // Use default provider ID
|
|
130
|
-
{
|
|
131
|
-
|
|
130
|
+
{
|
|
131
|
+
skip: !!masterData || !defaultProviderId,
|
|
132
|
+
refetchOnMountOrArgChange: true,
|
|
133
|
+
refetchOnFocus: true,
|
|
134
|
+
refetchOnReconnect: true,
|
|
135
|
+
});
|
|
132
136
|
// Use fallback master data if global master data is not available
|
|
133
137
|
// Store only the data parameter after stringifying instead of complete response
|
|
134
138
|
const effectiveMasterData = react_1.default.useMemo(() => {
|
|
@@ -339,7 +343,10 @@ const FDCalculator = ({ onGoBack, onExitSDK, onNavigateToReviewKYC, fdData }) =>
|
|
|
339
343
|
{
|
|
340
344
|
text: 'OK',
|
|
341
345
|
onPress: () => {
|
|
342
|
-
if (
|
|
346
|
+
if (onPanRequired) {
|
|
347
|
+
onPanRequired();
|
|
348
|
+
}
|
|
349
|
+
else if (onExitSDK) {
|
|
343
350
|
onExitSDK();
|
|
344
351
|
}
|
|
345
352
|
},
|