@finspringinnovations/fixeddepositsdk 1.0.1 → 1.0.3

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.
@@ -1,43 +1,43 @@
1
1
  // AppData Configuration - Data received from main app when SDK starts
2
2
 
3
3
  export interface EnvironmentData {
4
- environment: string;
5
- apiBaseUrl?: string;
6
- apiKey?: string;
7
- encryptionKey?: string;
8
- enableLogging?: boolean;
4
+ environment: string;
5
+ apiBaseUrl?: string;
6
+ apiKey?: string;
7
+ encryptionKey?: string;
8
+ enableLogging?: boolean;
9
9
  }
10
10
 
11
11
  export interface AppData {
12
- // Required user identification fields
13
- id: string; // Required: User ID from main app
14
- name: string; // Required: User full name
15
- dob: string; // Required: Date of birth in YYYY-MM-DD format
16
- gender?: string | null; // Optional: Male, Female (initial state may be null)
17
- mobNo: string; // Required: Mobile number (10 digits)
18
- email: string; // Required: Email address
19
- panNumber?: string; // Optional: PAN can be collected later in provider SDK flow
20
-
21
- // Optional fields - can be collected in SDK if not provided
22
- address?: string;
23
- area?: string;
24
- city?: string;
25
- state?: string;
26
- country?: string;
27
- pinCode?: string;
28
- accountNo?: string;
29
- nameOfBank?: string;
30
- ifsc?: string;
31
- typeOfAccount?: string; // Optional: Savings, Current, Fixed Deposit, Recurring Deposit
32
- maritalStatus?: string; // Optional: Single, Married, Divorced, Widowed
33
- userReferenceId?: string; // Optional: User reference ID from main app
34
- eventNotifyUrl?: string;
35
- kycRelation?: string;
36
- kycRelationName?: string;
37
- // Optional custom alert text shown when PAN is required on Start FD
38
- startFDAlertMessage?: string;
39
- // Optional powered-by logo URI/base64 for FDList header branding
40
- poweredByLogo?: string;
12
+ // Required user identification fields
13
+ id: string; // Required: User ID from main app
14
+ name: string; // Required: User full name
15
+ dob: string; // Required: Date of birth in YYYY-MM-DD format
16
+ gender?: string | null; // Optional: Male, Female (initial state may be null)
17
+ mobNo: string; // Required: Mobile number (10 digits)
18
+ email: string; // Required: Email address
19
+ panNumber?: string; // Optional: PAN can be collected later in provider SDK flow
20
+
21
+ // Optional fields - can be collected in SDK if not provided
22
+ address?: string;
23
+ area?: string;
24
+ city?: string;
25
+ state?: string;
26
+ country?: string;
27
+ pinCode?: string;
28
+ accountNo?: string;
29
+ nameOfBank?: string;
30
+ ifsc?: string;
31
+ typeOfAccount?: string; // Optional: Savings, Current, Fixed Deposit, Recurring Deposit
32
+ maritalStatus?: string; // Optional: Single, Married, Divorced, Widowed
33
+ userReferenceId?: string; // Optional: User reference ID from main app
34
+ eventNotifyUrl?: string;
35
+ kycRelation?: string;
36
+ kycRelationName?: string;
37
+ // Optional custom alert text shown when PAN is required on Start FD
38
+ startFDAlertMessage?: string;
39
+ // Optional powered-by logo URI/base64 for FDList header branding
40
+ poweredByLogo?: string;
41
41
  }
42
42
 
43
43
  // Global app data storage
@@ -48,29 +48,29 @@ let globalEnvironmentData: EnvironmentData | null = null;
48
48
 
49
49
  // Global custom color overrides for theming
50
50
  export interface CustomColors {
51
- primary?: string;
52
- tabSelected?: string;
53
- headerBg?: string;
54
- headerText?: string;
55
- success?: string;
56
- textSecondary?: string;
57
- border?: string;
58
- shadow?: string;
59
- background?: string;
60
- surface?: string;
61
- text?: string;
62
- textLight?: string;
63
- error?: string;
64
- warning?: string;
65
- info?: string;
66
- muted?: string;
67
- inputBackground?: string;
68
- inputBorder?: string;
69
- placeholderColor?: string;
70
- labelColor?: string;
71
- buttonBackground?: string;
72
- buttonTextColor?: string;
73
- cancelButtonBg?: string;
51
+ primary?: string;
52
+ tabSelected?: string;
53
+ headerBg?: string;
54
+ headerText?: string;
55
+ success?: string;
56
+ textSecondary?: string;
57
+ border?: string;
58
+ shadow?: string;
59
+ background?: string;
60
+ surface?: string;
61
+ text?: string;
62
+ textLight?: string;
63
+ error?: string;
64
+ warning?: string;
65
+ info?: string;
66
+ muted?: string;
67
+ inputBackground?: string;
68
+ inputBorder?: string;
69
+ placeholderColor?: string;
70
+ labelColor?: string;
71
+ buttonBackground?: string;
72
+ buttonTextColor?: string;
73
+ cancelButtonBg?: string;
74
74
  }
75
75
 
76
76
  let globalCustomColors: CustomColors | null = null;
@@ -80,57 +80,60 @@ let globalCustomColors: CustomColors | null = null;
80
80
  * This should be called when the SDK starts
81
81
  */
82
82
  export const initializeSDK = (appData: AppData, onValidationError?: (errors: string[]) => void): void => {
83
- // Validate required user identification fields
84
- const requiredFields = [
85
- { field: 'id', label: 'User ID' },
86
- { field: 'name', label: 'User Name' },
87
- { field: 'dob', label: 'Date of Birth' },
88
- { field: 'gender', label: 'Gender' },
89
- { field: 'mobNo', label: 'Mobile Number' },
90
- { field: 'email', label: 'Email' },
91
- ];
92
-
93
- const missingFields: string[] = [];
94
-
95
- requiredFields.forEach(({ field, label }) => {
96
- const value = (appData as any)[field];
97
- if (!value || (typeof value === 'string' && !value.trim())) {
98
- missingFields.push(label);
99
- }
100
- });
101
-
102
- // If required fields are missing, call error handler
103
- if (missingFields.length > 0) {
104
- const errorMessage = `Missing required user information from main app:\n${missingFields.join(', ')}`;
105
-
106
- if (onValidationError) {
107
- onValidationError(missingFields);
108
- }
109
-
110
- throw new Error(errorMessage);
111
- }
112
-
113
- // Validate all fields
114
- const validation = validateAppData(appData);
115
- if (!validation.isValid) {
116
- if (onValidationError) {
117
- onValidationError(validation.errors);
118
- }
119
-
120
- throw new Error(`App data validation failed: ${validation.errors.join(', ')}`);
121
- }
122
-
123
- globalAppData = appData;
124
-
125
- // SDK initialization started
126
- try {
127
- // logging removed
128
- } catch { }
129
-
130
- // Import and call environment logging
131
- import('./apiConfig').then(({ logEnvironmentInfo }) => {
132
- logEnvironmentInfo();
133
- });
83
+ // Validate required user identification fields
84
+ const requiredFields = [
85
+ { field: 'id', label: 'User ID' },
86
+ { field: 'name', label: 'User Name' },
87
+ { field: 'dob', label: 'Date of Birth' },
88
+ { field: 'gender', label: 'Gender' },
89
+ { field: 'mobNo', label: 'Mobile Number' },
90
+ { field: 'email', label: 'Email' },
91
+ ];
92
+
93
+ const missingFields: string[] = [];
94
+
95
+ requiredFields.forEach(({ field, label }) => {
96
+ const value = (appData as any)[field];
97
+ if (!value || (typeof value === 'string' && !value.trim())) {
98
+ missingFields.push(label);
99
+ }
100
+ });
101
+
102
+ // If required fields are missing, call error handler
103
+ if (missingFields.length > 0) {
104
+ const errorMessage = `Missing required user information from main app:\n${missingFields.join(', ')}`;
105
+
106
+ if (onValidationError) {
107
+ onValidationError(missingFields);
108
+ }
109
+
110
+ throw new Error(errorMessage);
111
+ }
112
+
113
+ // Validate all fields
114
+ const validation = validateAppData(appData);
115
+ if (!validation.isValid) {
116
+ if (onValidationError) {
117
+ onValidationError(validation.errors);
118
+ }
119
+
120
+ throw new Error(`App data validation failed: ${validation.errors.join(', ')}`);
121
+ }
122
+
123
+ globalAppData = appData;
124
+
125
+ // SDK initialization started
126
+ try {
127
+ // logging removed
128
+ } catch { }
129
+
130
+ // Import and call environment logging
131
+ import('./apiConfig').then(({ logEnvironmentInfo }) => {
132
+ logEnvironmentInfo();
133
+
134
+ console.log('SDK initialized with app data:', { logEnvironmentInfo });
135
+
136
+ });
134
137
  };
135
138
 
136
139
  /**
@@ -138,178 +141,178 @@ export const initializeSDK = (appData: AppData, onValidationError?: (errors: str
138
141
  * This should be called to configure SDK environment settings
139
142
  */
140
143
  export const initializeEnvironment = (environmentData: EnvironmentData): void => {
141
- globalEnvironmentData = environmentData;
144
+ globalEnvironmentData = environmentData;
142
145
 
143
- // Environment initialization started
144
- try {
145
- // logging removed
146
- } catch { }
146
+ // Environment initialization started
147
+ try {
148
+ // logging removed
149
+ } catch { }
147
150
 
148
- // Environment initialized
151
+ // Environment initialized
149
152
  };
150
153
 
151
154
  /**
152
155
  * Get the current app data
153
156
  */
154
157
  export const getAppData = (): AppData | null => {
155
- return globalAppData;
158
+ return globalAppData;
156
159
  };
157
160
 
158
161
  /**
159
162
  * Get the current environment data
160
163
  */
161
164
  export const getEnvironmentData = (): EnvironmentData | null => {
162
- return globalEnvironmentData;
165
+ return globalEnvironmentData;
163
166
  };
164
167
 
165
168
  /**
166
169
  * Check if SDK is initialized with app data
167
170
  */
168
171
  export const isSDKInitialized = (): boolean => {
169
- return globalAppData !== null;
172
+ return globalAppData !== null;
170
173
  };
171
174
 
172
175
  /**
173
176
  * Check if environment is initialized
174
177
  */
175
178
  export const isEnvironmentInitialized = (): boolean => {
176
- return globalEnvironmentData !== null;
179
+ return globalEnvironmentData !== null;
177
180
  };
178
181
 
179
182
  /**
180
183
  * Get specific user information for API requests
181
184
  */
182
185
  export const getUserInfoForAPI = () => {
183
- if (!globalAppData) {
184
- throw new Error('SDK not initialized. Call initializeSDK() first.');
185
- }
186
-
187
- return {
188
- id: globalAppData.id,
189
- name: globalAppData.name,
190
- dob: globalAppData.dob,
191
- gender: globalAppData.gender,
192
- panNumber: globalAppData.panNumber,
193
- mobileNumber: globalAppData.mobNo,
194
- email: globalAppData.email,
195
- eventNotifyUrl: globalAppData.eventNotifyUrl,
196
- userReferenceId: globalAppData.id, // Use userReferenceId or fallback to id
197
- address: {
198
- line1: globalAppData.address,
199
- area: globalAppData.area,
200
- city: globalAppData.city,
201
- state: globalAppData.state,
202
- country: globalAppData.country,
203
- pinCode: globalAppData.pinCode,
204
- },
205
- bankDetails: {
206
- accountNumber: globalAppData.accountNo,
207
- bankName: globalAppData.nameOfBank,
208
- ifsc: globalAppData.ifsc,
209
- accountType: globalAppData.typeOfAccount,
210
- },
211
- maritalStatus: globalAppData.maritalStatus,
212
- };
186
+ if (!globalAppData) {
187
+ throw new Error('SDK not initialized. Call initializeSDK() first.');
188
+ }
189
+
190
+ return {
191
+ id: globalAppData.id,
192
+ name: globalAppData.name,
193
+ dob: globalAppData.dob,
194
+ gender: globalAppData.gender,
195
+ panNumber: globalAppData.panNumber,
196
+ mobileNumber: globalAppData.mobNo,
197
+ email: globalAppData.email,
198
+ eventNotifyUrl: globalAppData.eventNotifyUrl,
199
+ userReferenceId: globalAppData.id, // Use userReferenceId or fallback to id
200
+ address: {
201
+ line1: globalAppData.address,
202
+ area: globalAppData.area,
203
+ city: globalAppData.city,
204
+ state: globalAppData.state,
205
+ country: globalAppData.country,
206
+ pinCode: globalAppData.pinCode,
207
+ },
208
+ bankDetails: {
209
+ accountNumber: globalAppData.accountNo,
210
+ bankName: globalAppData.nameOfBank,
211
+ ifsc: globalAppData.ifsc,
212
+ accountType: globalAppData.typeOfAccount,
213
+ },
214
+ maritalStatus: globalAppData.maritalStatus,
215
+ };
213
216
  };
214
217
 
215
218
  /**
216
219
  * Get user demographics for interest rate calculations
217
220
  */
218
221
  export const getUserDemographics = () => {
219
- if (!globalAppData) {
220
- throw new Error('SDK not initialized. Call initializeSDK() first.');
221
- }
222
-
223
- // Calculate age from DOB
224
- const calculateAge = (dob: string): number => {
225
- const today = new Date();
226
- const birthDate = new Date(dob);
227
- let age = today.getFullYear() - birthDate.getFullYear();
228
- const monthDiff = today.getMonth() - birthDate.getMonth();
229
-
230
- if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
231
- age--;
232
- }
233
-
234
- return age;
235
- };
236
-
237
- const age = calculateAge(globalAppData.dob);
238
- const isSeniorCitizen = age >= 60;
239
- const isWomenDepositor = globalAppData.gender === 'Female' || globalAppData.gender === 'female';
240
-
241
- return {
242
- age,
243
- isSeniorCitizen,
244
- isWomenDepositor,
245
- gender: globalAppData.gender,
246
- maritalStatus: globalAppData.maritalStatus,
247
- dob: globalAppData.dob,
248
- };
222
+ if (!globalAppData) {
223
+ throw new Error('SDK not initialized. Call initializeSDK() first.');
224
+ }
225
+
226
+ // Calculate age from DOB
227
+ const calculateAge = (dob: string): number => {
228
+ const today = new Date();
229
+ const birthDate = new Date(dob);
230
+ let age = today.getFullYear() - birthDate.getFullYear();
231
+ const monthDiff = today.getMonth() - birthDate.getMonth();
232
+
233
+ if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
234
+ age--;
235
+ }
236
+
237
+ return age;
238
+ };
239
+
240
+ const age = calculateAge(globalAppData.dob);
241
+ const isSeniorCitizen = age >= 60;
242
+ const isWomenDepositor = globalAppData.gender === 'Female' || globalAppData.gender === 'female';
243
+
244
+ return {
245
+ age,
246
+ isSeniorCitizen,
247
+ isWomenDepositor,
248
+ gender: globalAppData.gender,
249
+ maritalStatus: globalAppData.maritalStatus,
250
+ dob: globalAppData.dob,
251
+ };
249
252
  };
250
253
 
251
254
  /**
252
255
  * Validate app data
253
256
  */
254
257
  export const validateAppData = (appData: AppData): { isValid: boolean; errors: string[] } => {
255
- const errors: string[] = [];
256
-
257
- // Required fields validation
258
- if (!appData.id?.trim()) errors.push('ID is required');
259
- if (!appData.name?.trim()) errors.push('Name is required');
260
- if (!appData.dob?.trim()) errors.push('Date of birth is required');
261
- if (!appData.gender) errors.push('Gender is required');
262
- if (!appData.mobNo?.trim()) errors.push('Mobile number is required');
263
- if (!appData.email?.trim()) errors.push('Email is required');
264
-
265
- // Format validation (only if fields are provided)
266
- if (appData.dob && !/^\d{4}-\d{2}-\d{2}$/.test(appData.dob)) {
267
- errors.push('Date of birth must be in YYYY-MM-DD format');
268
- }
269
-
270
- if (appData.panNumber && appData.panNumber.trim() && !/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/.test(appData.panNumber)) {
271
- errors.push('PAN number must be in valid format (e.g., ABCDE1234F)');
272
- }
273
-
274
- if (appData.mobNo && !/^[6-9]\d{9}$/.test(appData.mobNo)) {
275
- errors.push('Mobile number must be 10 digits starting with 6-9');
276
- }
277
-
278
- if (appData.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(appData.email)) {
279
- errors.push('Email must be in valid format');
280
- }
281
-
282
- if (appData.ifsc && appData.ifsc.trim() && !/^[A-Z]{4}0[A-Z0-9]{6}$/.test(appData.ifsc)) {
283
- errors.push('IFSC code must be in valid format (e.g., SBIN0001234)');
284
- }
285
-
286
- return {
287
- isValid: errors.length === 0,
288
- errors,
289
- };
258
+ const errors: string[] = [];
259
+
260
+ // Required fields validation
261
+ if (!appData.id?.trim()) errors.push('ID is required');
262
+ if (!appData.name?.trim()) errors.push('Name is required');
263
+ if (!appData.dob?.trim()) errors.push('Date of birth is required');
264
+ if (!appData.gender) errors.push('Gender is required');
265
+ if (!appData.mobNo?.trim()) errors.push('Mobile number is required');
266
+ if (!appData.email?.trim()) errors.push('Email is required');
267
+
268
+ // Format validation (only if fields are provided)
269
+ if (appData.dob && !/^\d{4}-\d{2}-\d{2}$/.test(appData.dob)) {
270
+ errors.push('Date of birth must be in YYYY-MM-DD format');
271
+ }
272
+
273
+ if (appData.panNumber && appData.panNumber.trim() && !/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/.test(appData.panNumber)) {
274
+ errors.push('PAN number must be in valid format (e.g., ABCDE1234F)');
275
+ }
276
+
277
+ if (appData.mobNo && !/^[6-9]\d{9}$/.test(appData.mobNo)) {
278
+ errors.push('Mobile number must be 10 digits starting with 6-9');
279
+ }
280
+
281
+ if (appData.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(appData.email)) {
282
+ errors.push('Email must be in valid format');
283
+ }
284
+
285
+ if (appData.ifsc && appData.ifsc.trim() && !/^[A-Z]{4}0[A-Z0-9]{6}$/.test(appData.ifsc)) {
286
+ errors.push('IFSC code must be in valid format (e.g., SBIN0001234)');
287
+ }
288
+
289
+ return {
290
+ isValid: errors.length === 0,
291
+ errors,
292
+ };
290
293
  };
291
294
 
292
295
  /**
293
296
  * Clear app data (for testing or logout scenarios)
294
297
  */
295
298
  export const clearAppData = (): void => {
296
- globalAppData = null;
299
+ globalAppData = null;
297
300
  };
298
301
 
299
302
  /**
300
303
  * Clear environment data (for testing or logout scenarios)
301
304
  */
302
305
  export const clearEnvironmentData = (): void => {
303
- globalEnvironmentData = null;
306
+ globalEnvironmentData = null;
304
307
  };
305
308
 
306
309
  /**
307
310
  * Clear all data (app data and environment data)
308
311
  */
309
312
  export const clearAllData = (): void => {
310
- globalAppData = null;
311
- globalEnvironmentData = null;
312
- globalCustomColors = null;
313
+ globalAppData = null;
314
+ globalEnvironmentData = null;
315
+ globalCustomColors = null;
313
316
  };
314
317
 
315
318
  /**
@@ -321,40 +324,40 @@ export const clearAllData = (): void => {
321
324
  * so a single call centralizes theming across all SDKs.
322
325
  */
323
326
  export const setSDKColors = (customColors: CustomColors): void => {
324
- globalCustomColors = customColors;
325
-
326
- // Best-effort: propagate to external SDKs when they are available
327
- try {
328
- // eslint-disable-next-line @typescript-eslint/no-var-requires
329
- const shriram = require('@finspringinnovations/shriramsdk');
330
- if (shriram && typeof shriram.setSDKColors === 'function') {
331
- shriram.setSDKColors(customColors);
332
- }
333
- } catch {
334
- // Ignore if Shriram SDK is not installed
335
- }
336
-
337
- try {
338
- // eslint-disable-next-line @typescript-eslint/no-var-requires
339
- const mahindra = require('@finspringinnovations/mahindrasdk');
340
- if (mahindra && typeof mahindra.setSDKColors === 'function') {
341
- mahindra.setSDKColors(customColors);
342
- }
343
- } catch {
344
- // Ignore if Mahindra SDK is not installed
345
- }
327
+ globalCustomColors = customColors;
328
+
329
+ // Best-effort: propagate to external SDKs when they are available
330
+ try {
331
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
332
+ const shriram = require('@finspringinnovations/shriramfdsdk');
333
+ if (shriram && typeof shriram.setSDKColors === 'function') {
334
+ shriram.setSDKColors(customColors);
335
+ }
336
+ } catch {
337
+ // Ignore if Shriram SDK is not installed
338
+ }
339
+
340
+ try {
341
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
342
+ const mahindra = require('@finspringinnovations/mahindrafdsdk');
343
+ if (mahindra && typeof mahindra.setSDKColors === 'function') {
344
+ mahindra.setSDKColors(customColors);
345
+ }
346
+ } catch {
347
+ // Ignore if Mahindra SDK is not installed
348
+ }
346
349
  };
347
350
 
348
351
  /**
349
352
  * Get the current custom color overrides
350
353
  */
351
354
  export const getSDKColors = (): CustomColors | null => {
352
- return globalCustomColors;
355
+ return globalCustomColors;
353
356
  };
354
357
 
355
358
  /**
356
359
  * Clear custom color overrides
357
360
  */
358
361
  export const clearSDKColors = (): void => {
359
- globalCustomColors = null;
362
+ globalCustomColors = null;
360
363
  };
@@ -118,7 +118,7 @@ export const FD_STRINGS = {
118
118
  AMOUNT_MULTIPLES_ERROR: 'Amount must be in multiples of ₹1,000',
119
119
 
120
120
  // Senior citizen benefits
121
- SENIOR_CITIZEN_BENEFIT: '+0.25% p.a. more for senior citizens',
121
+ SENIOR_CITIZEN_BENEFIT: '+0.5% p.a. more for senior citizens',
122
122
 
123
123
  // Tax resident confirmation
124
124
  TAX_RESIDENT_CONFIRMATION: 'I confirm I am a tax resident of India',
@@ -135,7 +135,7 @@ export const FD_STRINGS = {
135
135
  TRUSTED_BY: 'Trusted By ',
136
136
  CRORES_INDIANS: '4.6 Crores Indians',
137
137
  AAA_RATING: 'Stable Rating',
138
- RATING: 'AA+',
138
+ RATING: 'AAA',
139
139
 
140
140
  // Fallback tenure options
141
141
  TENURE_12_MONTHS: '12 Months',