@finspringinnovations/fdsdk 0.0.4 → 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/hooks/usePaymentSSE.d.ts +7 -1
- package/lib/hooks/usePaymentSSE.js +101 -12
- package/lib/navigation/RootNavigator.js +10 -2
- package/lib/screens/AadhaarVerification.js +2 -2
- package/lib/screens/FDCalculator.js +6 -2
- 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/hooks/usePaymentSSE.ts +109 -15
- package/src/navigation/RootNavigator.tsx +8 -2
- package/src/screens/AadhaarVerification.tsx +2 -2
- package/src/screens/FDCalculator.tsx +7 -2
- 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}}',
|
|
@@ -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)(() => {
|
|
@@ -181,14 +181,22 @@ const RootNavigator = ({ config = {}, onExit, onPanRequired, }) => {
|
|
|
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', {
|
|
@@ -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({
|
|
@@ -127,8 +127,12 @@ const FDCalculator = ({ onGoBack, onExitSDK, onPanRequired, onNavigateToReviewKY
|
|
|
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(() => {
|
package/lib/screens/FDList.js
CHANGED
|
@@ -46,7 +46,6 @@ const customerApi_1 = require("../api/customerApi");
|
|
|
46
46
|
const masterDataApi_1 = require("../api/masterDataApi");
|
|
47
47
|
const MasterDataProvider_1 = require("../providers/MasterDataProvider");
|
|
48
48
|
const workflowApi_1 = require("../api/workflowApi");
|
|
49
|
-
const fdApi_1 = require("../api/fdApi");
|
|
50
49
|
const SafeAreaWrapper_1 = __importDefault(require("../components/SafeAreaWrapper"));
|
|
51
50
|
const appDataConfig_1 = require("../config/appDataConfig");
|
|
52
51
|
const helpers_1 = require("../navigation/helpers");
|
|
@@ -75,15 +74,8 @@ const FDList = ({ onGoBack, onSelectFD, onNavigateToFDCalculator, customStyles =
|
|
|
75
74
|
const [getInterestRates, { data: interestRates, error: interestRatesError, isLoading: isLoadingRates, }] = (0, interestRateApi_1.useGetInterestRatesMutation)();
|
|
76
75
|
const [getCustomerApplications, { data: customerApplications, error: customerApplicationsError, isLoading: isLoadingApplications, }] = (0, customerApi_1.useGetCustomerApplicationsMutation)();
|
|
77
76
|
const [terminateWorkflow, { data: terminateWorkflowData, error: terminateWorkflowError, isLoading: isTerminatingWorkflow, }] = (0, workflowApi_1.useTerminateWorkflowMutation)();
|
|
78
|
-
// Payment Reverse Feed API
|
|
79
|
-
const [paymentReverseFeed, { data: paymentReverseFeedResponse, error: paymentReverseFeedError, isLoading: isLoadingPaymentReverseFeed, }] = (0, fdApi_1.usePaymentReverseFeedMutation)();
|
|
80
77
|
const styles = createStyles(colors, typography, spacing, themeName);
|
|
81
78
|
const { setMasterData } = (0, MasterDataProvider_1.useMasterData)();
|
|
82
|
-
// Redux selectors for workflow IDs
|
|
83
|
-
const workflowInstanceId = (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.workflowInstanceId; });
|
|
84
|
-
const applicationId = (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.applicationId; });
|
|
85
|
-
const entityId = (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.entityid; });
|
|
86
|
-
const providerId = (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; });
|
|
87
79
|
// Helper function to check if customer applications is empty
|
|
88
80
|
const isCustomerApplicationsEmpty = () => {
|
|
89
81
|
if (!customerApplications) {
|
|
@@ -179,7 +171,12 @@ const FDList = ({ onGoBack, onSelectFD, onNavigateToFDCalculator, customStyles =
|
|
|
179
171
|
return interestRates.data.fdrScheme[0].providerId;
|
|
180
172
|
return defaultProviderId; // Use default if no rates data yet
|
|
181
173
|
}, [interestRates]);
|
|
182
|
-
const { data: masterData, isLoading: isLoadingMaster } = (0, masterDataApi_1.useGetMasterDataQuery)({ providerId: inferredProviderId }, {
|
|
174
|
+
const { data: masterData, isLoading: isLoadingMaster } = (0, masterDataApi_1.useGetMasterDataQuery)({ providerId: inferredProviderId }, {
|
|
175
|
+
skip: !inferredProviderId,
|
|
176
|
+
refetchOnMountOrArgChange: true,
|
|
177
|
+
refetchOnFocus: true,
|
|
178
|
+
refetchOnReconnect: true,
|
|
179
|
+
});
|
|
183
180
|
// Only render once all three API calls have completed (success or error)
|
|
184
181
|
// Show loading initially until all APIs have completed
|
|
185
182
|
const isAllDataReady = react_1.default.useMemo(() => {
|
|
@@ -413,25 +410,34 @@ const FDList = ({ onGoBack, onSelectFD, onNavigateToFDCalculator, customStyles =
|
|
|
413
410
|
// Customer applications loaded successfully
|
|
414
411
|
// Persist onboarding identifiers globally for subsequent API calls (like FDCalculator)
|
|
415
412
|
try {
|
|
416
|
-
// Extract workflow parameters from response
|
|
413
|
+
// Extract workflow parameters from response (support array / data[] / applications[])
|
|
417
414
|
const responseData = (customerApplications === null || customerApplications === void 0 ? void 0 : customerApplications.data) || customerApplications;
|
|
418
|
-
let
|
|
419
|
-
// Prefer the application with wf_status === 'Active'
|
|
415
|
+
let applicationsData = [];
|
|
420
416
|
if (Array.isArray(responseData)) {
|
|
421
|
-
|
|
417
|
+
applicationsData = responseData;
|
|
418
|
+
}
|
|
419
|
+
else if ((responseData === null || responseData === void 0 ? void 0 : responseData.applications) && Array.isArray(responseData.applications)) {
|
|
420
|
+
applicationsData = responseData.applications;
|
|
421
|
+
}
|
|
422
|
+
else if (Array.isArray(customerApplications === null || customerApplications === void 0 ? void 0 : customerApplications.applications)) {
|
|
423
|
+
applicationsData = customerApplications.applications;
|
|
424
|
+
}
|
|
425
|
+
let applicationData = applicationsData.length > 0 ? applicationsData[0] : (Array.isArray(responseData) ? responseData[0] : responseData);
|
|
426
|
+
// Prefer the application with wf_status === 'Active'
|
|
427
|
+
if (applicationsData.length > 0) {
|
|
428
|
+
const activeOnly = applicationsData.find((app) => {
|
|
422
429
|
const status = (app.wf_status || app.status || '').toString();
|
|
423
430
|
return status === 'Active';
|
|
424
431
|
});
|
|
425
432
|
if (activeOnly)
|
|
426
433
|
applicationData = activeOnly;
|
|
427
434
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
+
// Set completed flag robustly for downstream ReviewKYC/Aadhaar flow decisions
|
|
436
|
+
completeFDData = applicationsData.find((app) => {
|
|
437
|
+
const status = (app.wf_status || app.status || '').toString().toLowerCase();
|
|
438
|
+
return status === 'completed';
|
|
439
|
+
});
|
|
440
|
+
(0, globalData_1.setGlobalData)({ completeFDData: !!completeFDData });
|
|
435
441
|
if (applicationData) {
|
|
436
442
|
const ids = {
|
|
437
443
|
workflowInstanceId: applicationData.workflow_instance_id,
|
|
@@ -460,7 +466,6 @@ const FDList = ({ onGoBack, onSelectFD, onNavigateToFDCalculator, customStyles =
|
|
|
460
466
|
}, [customerApplications, dispatch]);
|
|
461
467
|
// Unified handler: behave like bottom sheet Continue flow
|
|
462
468
|
const handlePendingFDContinue = async () => {
|
|
463
|
-
var _a;
|
|
464
469
|
// Persist active FD data to store for use across screens
|
|
465
470
|
try {
|
|
466
471
|
if (activeFD) {
|
|
@@ -516,50 +521,18 @@ const FDList = ({ onGoBack, onSelectFD, onNavigateToFDCalculator, customStyles =
|
|
|
516
521
|
catch (error) {
|
|
517
522
|
// Handle error silently
|
|
518
523
|
}
|
|
519
|
-
// If current state is payment and transactionId is available,
|
|
524
|
+
// If current state is payment and transactionId is available,
|
|
525
|
+
// open PaymentStatus and let SSE (/events) drive status updates.
|
|
520
526
|
if (currentState === workflowConstants_1.WORKFLOW_STATES.PAYMENT && transactionId) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
applicationid: applicationId,
|
|
531
|
-
entityid: entityId,
|
|
532
|
-
// Body
|
|
533
|
-
transactionId: transactionId,
|
|
534
|
-
};
|
|
535
|
-
const response = await paymentReverseFeed(paymentReverseFeedRequest).unwrap();
|
|
536
|
-
// Handle the response based on payment status
|
|
537
|
-
const paymentStatus = (((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.paymentStatus) || '').toLowerCase();
|
|
538
|
-
const statusParam = paymentStatus === 'success' ? 'success' : paymentStatus === 'failed' ? 'failed' : 'pending';
|
|
539
|
-
// Build fdData for display
|
|
540
|
-
const fdDataParam = activeFD ? {
|
|
541
|
-
companyName: activeFD.name,
|
|
542
|
-
amount: Number(activeFD.invested) || 0,
|
|
543
|
-
fdRate: `${activeFD.returns}% p.a.`,
|
|
544
|
-
tenure: activeFD.maturityDate ? `${activeFD.maturityDate}` : '-',
|
|
545
|
-
interestPayout: activeFD.interestPayout || 'Yearly',
|
|
546
|
-
} : undefined;
|
|
547
|
-
(0, helpers_1.navigate)('PaymentStatus', { status: statusParam, transactionId, fdData: fdDataParam });
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
catch (error) {
|
|
551
|
-
// Handle error silently
|
|
552
|
-
// On error, navigate with pending status as fallback
|
|
553
|
-
const fdDataParam = activeFD ? {
|
|
554
|
-
companyName: activeFD.name,
|
|
555
|
-
amount: Number(activeFD.invested) || 0,
|
|
556
|
-
fdRate: `${activeFD.returns}% p.a.`,
|
|
557
|
-
tenure: activeFD.maturityDate ? `${activeFD.maturityDate}` : '-',
|
|
558
|
-
interestPayout: activeFD.interestPayout || 'Yearly',
|
|
559
|
-
} : undefined;
|
|
560
|
-
(0, helpers_1.navigate)('PaymentStatus', { status: 'pending', transactionId, fdData: fdDataParam });
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
527
|
+
const fdDataParam = activeFD ? {
|
|
528
|
+
companyName: activeFD.name,
|
|
529
|
+
amount: Number(activeFD.invested) || 0,
|
|
530
|
+
fdRate: `${activeFD.returns}% p.a.`,
|
|
531
|
+
tenure: activeFD.maturityDate ? `${activeFD.maturityDate}` : '-',
|
|
532
|
+
interestPayout: activeFD.interestPayout || 'Yearly',
|
|
533
|
+
} : undefined;
|
|
534
|
+
(0, helpers_1.navigate)('PaymentStatus', { status: 'pending', transactionId, fdData: fdDataParam });
|
|
535
|
+
return;
|
|
563
536
|
}
|
|
564
537
|
// Use workflow navigation based on current state (non-payment states or no transactionId)
|
|
565
538
|
if (currentState && Object.values(workflowConstants_1.WORKFLOW_STATES).includes(currentState)) {
|