insert-affiliate-react-native-sdk 1.13.0 → 1.15.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.
- package/dist/DeepLinkIapProvider.d.ts +7 -0
- package/dist/DeepLinkIapProvider.js +109 -93
- package/dist/index.d.ts +1 -1
- package/dist/useDeepLinkIapProvider.d.ts +1 -0
- package/dist/useDeepLinkIapProvider.js +2 -1
- package/package.json +1 -1
- package/readme.md +39 -0
- package/src/DeepLinkIapProvider.tsx +120 -109
- package/src/index.ts +1 -1
- package/src/useDeepLinkIapProvider.tsx +2 -0
|
@@ -54,6 +54,7 @@ type T_DEEPLINK_IAP_CONTEXT = {
|
|
|
54
54
|
setInsertAffiliateIdentifierChangeCallback: (callback: InsertAffiliateIdentifierChangeCallback | null) => void;
|
|
55
55
|
handleInsertLinks: (url: string) => Promise<boolean>;
|
|
56
56
|
initialize: (code: string | null, verboseLogging?: boolean, insertLinksEnabled?: boolean, insertLinksClipboardEnabled?: boolean, affiliateAttributionActiveTime?: number, preventAffiliateTransfer?: boolean) => Promise<void>;
|
|
57
|
+
setLogger: (logger: InsertAffiliateLogger) => void;
|
|
57
58
|
isInitialized: boolean;
|
|
58
59
|
};
|
|
59
60
|
|
|
@@ -83,6 +84,7 @@ const ASYNC_KEYS = {
|
|
|
83
84
|
AFFILIATE_STORED_DATE: '@app_affiliate_stored_date',
|
|
84
85
|
SDK_INIT_REPORTED: '@app_sdk_init_reported',
|
|
85
86
|
REPORTED_AFFILIATE_ASSOCIATIONS: '@app_reported_affiliate_associations',
|
|
87
|
+
SYSTEM_INFO_SENT: '@app_system_info_sent',
|
|
86
88
|
};
|
|
87
89
|
|
|
88
90
|
// Source types for affiliate association tracking
|
|
@@ -94,6 +96,21 @@ type AffiliateAssociationSource =
|
|
|
94
96
|
| 'short_code_manual' // Developer called setShortCode()
|
|
95
97
|
| 'referring_link'; // Developer called setInsertAffiliateIdentifier()
|
|
96
98
|
|
|
99
|
+
// Logger interface for custom logging
|
|
100
|
+
export type InsertAffiliateLogger = {
|
|
101
|
+
debug: (message: string, ...args: any[]) => void;
|
|
102
|
+
info: (message: string, ...args: any[]) => void;
|
|
103
|
+
warn: (message: string, ...args: any[]) => void;
|
|
104
|
+
error: (message: string, ...args: any[]) => void;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const DEFAULT_LOGGER: InsertAffiliateLogger = {
|
|
108
|
+
debug: (message, ...args) => console.debug(`[Insert Affiliate] ${message}`, ...args),
|
|
109
|
+
info: (message, ...args) => console.log(`[Insert Affiliate] ${message}`, ...args),
|
|
110
|
+
warn: (message, ...args) => console.warn(`[Insert Affiliate] ${message}`, ...args),
|
|
111
|
+
error: (message, ...args) => console.error(`[Insert Affiliate] ${message}`, ...args),
|
|
112
|
+
};
|
|
113
|
+
|
|
97
114
|
// STARTING CONTEXT IMPLEMENTATION
|
|
98
115
|
export const DeepLinkIapContext = createContext<T_DEEPLINK_IAP_CONTEXT>({
|
|
99
116
|
referrerLink: '',
|
|
@@ -118,6 +135,7 @@ export const DeepLinkIapContext = createContext<T_DEEPLINK_IAP_CONTEXT>({
|
|
|
118
135
|
setInsertAffiliateIdentifierChangeCallback: (callback: InsertAffiliateIdentifierChangeCallback | null) => {},
|
|
119
136
|
handleInsertLinks: async (url: string) => false,
|
|
120
137
|
initialize: async (code: string | null, verboseLogging?: boolean, insertLinksEnabled?: boolean, insertLinksClipboardEnabled?: boolean, affiliateAttributionActiveTime?: number, preventAffiliateTransfer?: boolean) => {},
|
|
138
|
+
setLogger: (logger: InsertAffiliateLogger) => {},
|
|
121
139
|
isInitialized: false,
|
|
122
140
|
});
|
|
123
141
|
|
|
@@ -137,6 +155,9 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
137
155
|
const insertAffiliateIdentifierChangeCallbackRef = useRef<InsertAffiliateIdentifierChangeCallback | null>(null);
|
|
138
156
|
const isInitializingRef = useRef<boolean>(false);
|
|
139
157
|
|
|
158
|
+
// Logger ref - defaults to console-based logging, can be swapped via setLogger()
|
|
159
|
+
const loggerRef = useRef<InsertAffiliateLogger>(DEFAULT_LOGGER);
|
|
160
|
+
|
|
140
161
|
// Refs for values that need to be current inside callbacks (to avoid stale closures)
|
|
141
162
|
const companyCodeRef = useRef<string | null>(null);
|
|
142
163
|
const verboseLoggingRef = useRef<boolean>(false);
|
|
@@ -176,9 +197,9 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
176
197
|
preventAffiliateTransferRef.current = preventAffiliateTransferParam;
|
|
177
198
|
|
|
178
199
|
if (verboseLoggingParam) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
200
|
+
loggerRef.current.debug('[VERBOSE] Starting SDK initialization...');
|
|
201
|
+
loggerRef.current.debug('[VERBOSE] Company code provided:', companyCodeParam ? 'Yes' : 'No');
|
|
202
|
+
loggerRef.current.debug('[VERBOSE] Verbose logging enabled');
|
|
182
203
|
}
|
|
183
204
|
|
|
184
205
|
if (companyCodeParam && companyCodeParam.trim() !== '') {
|
|
@@ -186,32 +207,36 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
186
207
|
companyCodeRef.current = companyCodeParam;
|
|
187
208
|
await saveValueInAsync(ASYNC_KEYS.COMPANY_CODE, companyCodeParam);
|
|
188
209
|
setIsInitialized(true);
|
|
189
|
-
|
|
190
|
-
`[Insert Affiliate] SDK initialized with company code: ${companyCodeParam}`
|
|
191
|
-
);
|
|
210
|
+
loggerRef.current.info(`SDK initialized with company code: ${companyCodeParam}`);
|
|
192
211
|
if (verboseLoggingParam) {
|
|
193
|
-
|
|
194
|
-
|
|
212
|
+
loggerRef.current.debug('[VERBOSE] Company code saved to AsyncStorage');
|
|
213
|
+
loggerRef.current.debug('[VERBOSE] SDK marked as initialized');
|
|
195
214
|
}
|
|
196
215
|
|
|
197
216
|
// Report SDK initialization for onboarding verification (fire and forget)
|
|
198
217
|
reportSdkInitIfNeeded(companyCodeParam, verboseLoggingParam);
|
|
199
218
|
} else {
|
|
200
|
-
|
|
201
|
-
'[Insert Affiliate] SDK initialized without a company code.'
|
|
202
|
-
);
|
|
219
|
+
loggerRef.current.warn('SDK initialized without a company code.');
|
|
203
220
|
setIsInitialized(true);
|
|
204
221
|
if (verboseLoggingParam) {
|
|
205
|
-
|
|
222
|
+
loggerRef.current.debug('[VERBOSE] No company code provided, SDK initialized in limited mode');
|
|
206
223
|
}
|
|
207
224
|
}
|
|
208
225
|
|
|
209
226
|
if (insertLinksEnabledParam && Platform.OS === 'ios') {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
227
|
+
const systemInfoSent = await getValueFromAsync(ASYNC_KEYS.SYSTEM_INFO_SENT);
|
|
228
|
+
verboseLog(`System info sent flag: ${systemInfoSent ? 'true (skipping)' : 'false (will send)'}`);
|
|
229
|
+
if (!systemInfoSent) {
|
|
230
|
+
// Set flag immediately to prevent concurrent init calls from sending twice
|
|
231
|
+
await saveValueInAsync(ASYNC_KEYS.SYSTEM_INFO_SENT, 'pending');
|
|
232
|
+
try {
|
|
233
|
+
const enhancedSystemInfo = await getEnhancedSystemInfo();
|
|
234
|
+
await sendSystemInfoToBackend(enhancedSystemInfo);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
// Remove flag on failure so it retries next launch
|
|
237
|
+
await AsyncStorage.removeItem(ASYNC_KEYS.SYSTEM_INFO_SENT);
|
|
238
|
+
verboseLog(`Error sending system info for clipboard check: ${error}`);
|
|
239
|
+
}
|
|
215
240
|
}
|
|
216
241
|
}
|
|
217
242
|
};
|
|
@@ -293,7 +318,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
293
318
|
}
|
|
294
319
|
}
|
|
295
320
|
} catch (error) {
|
|
296
|
-
|
|
321
|
+
loggerRef.current.error('Error getting initial URL:', error);
|
|
297
322
|
}
|
|
298
323
|
};
|
|
299
324
|
|
|
@@ -308,7 +333,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
308
333
|
verboseLog('URL was not handled by Insert Affiliate SDK');
|
|
309
334
|
}
|
|
310
335
|
} catch (error) {
|
|
311
|
-
|
|
336
|
+
loggerRef.current.error('Error handling URL change:', error);
|
|
312
337
|
}
|
|
313
338
|
};
|
|
314
339
|
|
|
@@ -389,7 +414,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
389
414
|
const reset = (): void => {
|
|
390
415
|
setCompanyCode(null);
|
|
391
416
|
setIsInitialized(false);
|
|
392
|
-
|
|
417
|
+
loggerRef.current.info('SDK has been reset.');
|
|
393
418
|
};
|
|
394
419
|
|
|
395
420
|
// MARK: Deep Link Handling
|
|
@@ -602,16 +627,16 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
602
627
|
// Handles Insert Links deep linking - equivalent to iOS handleInsertLinks
|
|
603
628
|
const handleInsertLinksImpl = async (url: string): Promise<boolean> => {
|
|
604
629
|
try {
|
|
605
|
-
|
|
630
|
+
loggerRef.current.info(`Attempting to handle URL: ${url}`);
|
|
606
631
|
|
|
607
632
|
if (!url || typeof url !== 'string') {
|
|
608
|
-
|
|
633
|
+
loggerRef.current.info('Invalid URL provided to handleInsertLinks');
|
|
609
634
|
return false;
|
|
610
635
|
}
|
|
611
636
|
|
|
612
637
|
// Check if deep links are enabled synchronously
|
|
613
638
|
if (!insertLinksEnabled) {
|
|
614
|
-
|
|
639
|
+
loggerRef.current.info('Deep links are disabled, not handling URL');
|
|
615
640
|
return false;
|
|
616
641
|
}
|
|
617
642
|
|
|
@@ -629,7 +654,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
629
654
|
|
|
630
655
|
return false;
|
|
631
656
|
} catch (error) {
|
|
632
|
-
|
|
657
|
+
loggerRef.current.error('Error handling Insert Link:', error);
|
|
633
658
|
verboseLog(`Error in handleInsertLinks: ${error}`);
|
|
634
659
|
return false;
|
|
635
660
|
}
|
|
@@ -649,32 +674,26 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
649
674
|
|
|
650
675
|
const shortCode = parseShortCodeFromURLString(url);
|
|
651
676
|
if (!shortCode) {
|
|
652
|
-
|
|
677
|
+
loggerRef.current.info(`Failed to parse short code from deep link: ${url}`);
|
|
653
678
|
return false;
|
|
654
679
|
}
|
|
655
680
|
|
|
656
|
-
|
|
681
|
+
loggerRef.current.info(`Custom URL scheme detected - Company: ${companyCode}, Short code: ${shortCode}`);
|
|
657
682
|
|
|
658
683
|
// Validate company code matches initialized one
|
|
659
684
|
const activeCompanyCode = await getActiveCompanyCode();
|
|
660
685
|
if (activeCompanyCode && companyCode.toLowerCase() !== activeCompanyCode.toLowerCase()) {
|
|
661
|
-
|
|
686
|
+
loggerRef.current.info(`Warning: URL company code (${companyCode}) doesn't match initialized company code (${activeCompanyCode})`);
|
|
662
687
|
}
|
|
663
688
|
|
|
664
689
|
// If URL scheme is used, we can straight away store the short code as the referring link
|
|
665
690
|
await storeInsertAffiliateIdentifier({ link: shortCode, source: 'deep_link_ios' });
|
|
666
691
|
|
|
667
|
-
//
|
|
668
|
-
try {
|
|
669
|
-
const enhancedSystemInfo = await getEnhancedSystemInfo();
|
|
670
|
-
await sendSystemInfoToBackend(enhancedSystemInfo);
|
|
671
|
-
} catch (error) {
|
|
672
|
-
verboseLog(`Error sending system info for deep link: ${error}`);
|
|
673
|
-
}
|
|
692
|
+
// System info not needed here - affiliate code already received via URL scheme
|
|
674
693
|
|
|
675
694
|
return true;
|
|
676
695
|
} catch (error) {
|
|
677
|
-
|
|
696
|
+
loggerRef.current.error('Error handling custom URL scheme:', error);
|
|
678
697
|
return false;
|
|
679
698
|
}
|
|
680
699
|
};
|
|
@@ -686,19 +705,19 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
686
705
|
|
|
687
706
|
// // Expected format: /V1/companycode/shortcode
|
|
688
707
|
// if (pathComponents.length < 3 || pathComponents[0] !== 'V1') {
|
|
689
|
-
//
|
|
708
|
+
// loggerRef.current.info(`Invalid universal link format: ${url.href}`);
|
|
690
709
|
// return false;
|
|
691
710
|
// }
|
|
692
711
|
|
|
693
712
|
// const companyCode = pathComponents[1];
|
|
694
713
|
// const shortCode = pathComponents[2];
|
|
695
714
|
|
|
696
|
-
//
|
|
715
|
+
// loggerRef.current.info(`Universal link detected - Company: ${companyCode}, Short code: ${shortCode}`);
|
|
697
716
|
|
|
698
717
|
// // Validate company code matches initialized one
|
|
699
718
|
// const activeCompanyCode = await getActiveCompanyCode();
|
|
700
719
|
// if (activeCompanyCode && companyCode.toLowerCase() !== activeCompanyCode.toLowerCase()) {
|
|
701
|
-
//
|
|
720
|
+
// loggerRef.current.info(`Warning: URL company code (${companyCode}) doesn't match initialized company code (${activeCompanyCode})`);
|
|
702
721
|
// }
|
|
703
722
|
|
|
704
723
|
// // Process the affiliate attribution
|
|
@@ -707,7 +726,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
707
726
|
|
|
708
727
|
// return true;
|
|
709
728
|
// } catch (error) {
|
|
710
|
-
//
|
|
729
|
+
// loggerRef.current.error('Error handling universal link:', error);
|
|
711
730
|
// return false;
|
|
712
731
|
// }
|
|
713
732
|
// };
|
|
@@ -750,7 +769,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
750
769
|
// First try to extract from query parameter (new format: scheme://insert-affiliate?code=SHORTCODE)
|
|
751
770
|
const queryCode = parseShortCodeFromQuery(url);
|
|
752
771
|
if (queryCode) {
|
|
753
|
-
|
|
772
|
+
loggerRef.current.info(`Found short code in query parameter: ${queryCode}`);
|
|
754
773
|
return queryCode;
|
|
755
774
|
}
|
|
756
775
|
|
|
@@ -764,7 +783,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
764
783
|
if (shortCode === 'insert-affiliate' || shortCode.startsWith('insert-affiliate?')) {
|
|
765
784
|
return null;
|
|
766
785
|
}
|
|
767
|
-
|
|
786
|
+
loggerRef.current.info(`Found short code in URL path (legacy format): ${shortCode}`);
|
|
768
787
|
return shortCode;
|
|
769
788
|
}
|
|
770
789
|
return null;
|
|
@@ -812,7 +831,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
812
831
|
// Helper function for verbose logging (uses ref to avoid stale closures)
|
|
813
832
|
const verboseLog = (message: string) => {
|
|
814
833
|
if (verboseLoggingRef.current) {
|
|
815
|
-
|
|
834
|
+
loggerRef.current.debug(`[VERBOSE] ${message}`);
|
|
816
835
|
}
|
|
817
836
|
};
|
|
818
837
|
|
|
@@ -820,13 +839,13 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
820
839
|
const errorLog = (message: string, type?: 'error' | 'warn' | 'log') => {
|
|
821
840
|
switch (type) {
|
|
822
841
|
case 'error':
|
|
823
|
-
|
|
842
|
+
loggerRef.current.error(`ENCOUNTER ERROR ~ ${message}`);
|
|
824
843
|
break;
|
|
825
844
|
case 'warn':
|
|
826
|
-
|
|
845
|
+
loggerRef.current.warn(`ENCOUNTER WARNING ~ ${message}`);
|
|
827
846
|
break;
|
|
828
847
|
default:
|
|
829
|
-
|
|
848
|
+
loggerRef.current.info(`LOGGING ~ ${message}`);
|
|
830
849
|
break;
|
|
831
850
|
}
|
|
832
851
|
};
|
|
@@ -894,7 +913,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
894
913
|
}
|
|
895
914
|
|
|
896
915
|
if (verboseLogging) {
|
|
897
|
-
|
|
916
|
+
loggerRef.current.info('Reporting SDK initialization for onboarding verification...');
|
|
898
917
|
}
|
|
899
918
|
|
|
900
919
|
const response = await fetch('https://api.insertaffiliate.com/V1/onboarding/sdk-init', {
|
|
@@ -908,15 +927,15 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
908
927
|
if (response.ok) {
|
|
909
928
|
await AsyncStorage.setItem(ASYNC_KEYS.SDK_INIT_REPORTED, 'true');
|
|
910
929
|
if (verboseLogging) {
|
|
911
|
-
|
|
930
|
+
loggerRef.current.info('SDK initialization reported successfully');
|
|
912
931
|
}
|
|
913
932
|
} else if (verboseLogging) {
|
|
914
|
-
|
|
933
|
+
loggerRef.current.info(`SDK initialization report failed with status: ${response.status}`);
|
|
915
934
|
}
|
|
916
935
|
} catch (error) {
|
|
917
936
|
// Silently fail - this is non-critical telemetry
|
|
918
937
|
if (verboseLogging) {
|
|
919
|
-
|
|
938
|
+
loggerRef.current.info(`SDK initialization report error: ${error}`);
|
|
920
939
|
}
|
|
921
940
|
}
|
|
922
941
|
};
|
|
@@ -1154,7 +1173,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1154
1173
|
}
|
|
1155
1174
|
|
|
1156
1175
|
if (verboseLogging) {
|
|
1157
|
-
|
|
1176
|
+
loggerRef.current.info('system info:', systemInfo);
|
|
1158
1177
|
}
|
|
1159
1178
|
|
|
1160
1179
|
return systemInfo;
|
|
@@ -1315,7 +1334,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1315
1334
|
// Sends enhanced system info to the backend API for deep link event tracking
|
|
1316
1335
|
const sendSystemInfoToBackend = async (systemInfo: {[key: string]: any}): Promise<void> => {
|
|
1317
1336
|
if (verboseLogging) {
|
|
1318
|
-
|
|
1337
|
+
loggerRef.current.info('Sending system info to backend...');
|
|
1319
1338
|
}
|
|
1320
1339
|
|
|
1321
1340
|
try {
|
|
@@ -1347,6 +1366,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1347
1366
|
|
|
1348
1367
|
// Check for a successful response
|
|
1349
1368
|
if (response.status >= 200 && response.status <= 299) {
|
|
1369
|
+
await saveValueInAsync(ASYNC_KEYS.SYSTEM_INFO_SENT, 'true');
|
|
1350
1370
|
verboseLog('System info sent successfully');
|
|
1351
1371
|
} else {
|
|
1352
1372
|
verboseLog(`Failed to send system info with status code: ${response.status}`);
|
|
@@ -1453,13 +1473,13 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1453
1473
|
return null;
|
|
1454
1474
|
} catch (error) {
|
|
1455
1475
|
verboseLog(`Error getting affiliate details: ${error}`);
|
|
1456
|
-
|
|
1476
|
+
loggerRef.current.error('Error getting affiliate details:', error);
|
|
1457
1477
|
return null;
|
|
1458
1478
|
}
|
|
1459
1479
|
};
|
|
1460
1480
|
|
|
1461
1481
|
const setShortCodeImpl = async (shortCode: string): Promise<boolean> => {
|
|
1462
|
-
|
|
1482
|
+
loggerRef.current.info('Setting short code.');
|
|
1463
1483
|
await generateThenSetUserID();
|
|
1464
1484
|
|
|
1465
1485
|
// Validate it is a short code
|
|
@@ -1472,10 +1492,10 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1472
1492
|
if (exists) {
|
|
1473
1493
|
// If affiliate exists, set the Insert Affiliate Identifier
|
|
1474
1494
|
await storeInsertAffiliateIdentifier({ link: capitalisedShortCode, source: 'short_code_manual' });
|
|
1475
|
-
|
|
1495
|
+
loggerRef.current.info(`Short code ${capitalisedShortCode} validated and stored successfully.`);
|
|
1476
1496
|
return true;
|
|
1477
1497
|
} else {
|
|
1478
|
-
|
|
1498
|
+
loggerRef.current.warn(`Short code ${capitalisedShortCode} does not exist. Not storing.`);
|
|
1479
1499
|
return false;
|
|
1480
1500
|
}
|
|
1481
1501
|
};
|
|
@@ -1495,15 +1515,15 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1495
1515
|
try {
|
|
1496
1516
|
const shortCode = await returnInsertAffiliateIdentifierImpl();
|
|
1497
1517
|
if (!shortCode) {
|
|
1498
|
-
|
|
1518
|
+
loggerRef.current.info('No affiliate stored - not saving expected transaction.');
|
|
1499
1519
|
return null;
|
|
1500
1520
|
}
|
|
1501
1521
|
|
|
1502
1522
|
const userAccountToken = await getOrCreateUserAccountToken();
|
|
1503
|
-
|
|
1523
|
+
loggerRef.current.info('User account token:', userAccountToken);
|
|
1504
1524
|
|
|
1505
1525
|
if (!userAccountToken) {
|
|
1506
|
-
|
|
1526
|
+
loggerRef.current.error('Failed to generate user account token.');
|
|
1507
1527
|
return null;
|
|
1508
1528
|
} else {
|
|
1509
1529
|
await storeExpectedStoreTransactionImpl(userAccountToken);
|
|
@@ -1515,13 +1535,13 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1515
1535
|
(error instanceof Error && error.message.includes('E_IAP_NOT_AVAILABLE'))) {
|
|
1516
1536
|
|
|
1517
1537
|
if (isDevelopmentEnvironment) {
|
|
1518
|
-
|
|
1538
|
+
loggerRef.current.warn('IAP not available in development environment. Cannot store expected transaction.');
|
|
1519
1539
|
verboseLog('E_IAP_NOT_AVAILABLE error in returnUserAccountTokenAndStoreExpectedTransaction - gracefully handling in development');
|
|
1520
1540
|
}
|
|
1521
1541
|
return null; // Return null but don't crash
|
|
1522
1542
|
}
|
|
1523
1543
|
|
|
1524
|
-
|
|
1544
|
+
loggerRef.current.error('Error in returnUserAccountTokenAndStoreExpectedTransaction:', error);
|
|
1525
1545
|
return null;
|
|
1526
1546
|
};
|
|
1527
1547
|
};
|
|
@@ -1657,19 +1677,17 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1657
1677
|
const setInsertAffiliateIdentifierImpl = async (
|
|
1658
1678
|
referringLink: string
|
|
1659
1679
|
): Promise<void | string> => {
|
|
1660
|
-
|
|
1680
|
+
loggerRef.current.info('Setting affiliate identifier.');
|
|
1661
1681
|
verboseLog(`Input referringLink: ${referringLink}`);
|
|
1662
1682
|
|
|
1663
1683
|
try {
|
|
1664
1684
|
verboseLog('Generating or retrieving user ID...');
|
|
1665
1685
|
const customerID = await generateThenSetUserID();
|
|
1666
|
-
|
|
1667
|
-
'[Insert Affiliate] Completed generateThenSetUserID within setInsertAffiliateIdentifier.'
|
|
1668
|
-
);
|
|
1686
|
+
loggerRef.current.info('Completed generateThenSetUserID within setInsertAffiliateIdentifier.');
|
|
1669
1687
|
verboseLog(`Customer ID: ${customerID}`);
|
|
1670
1688
|
|
|
1671
1689
|
if (!referringLink) {
|
|
1672
|
-
|
|
1690
|
+
loggerRef.current.warn('Referring link is invalid.');
|
|
1673
1691
|
verboseLog('Referring link is empty or invalid, storing as-is');
|
|
1674
1692
|
await storeInsertAffiliateIdentifier({ link: referringLink, source: 'referring_link' });
|
|
1675
1693
|
return `${referringLink}-${customerID}`;
|
|
@@ -1681,9 +1699,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1681
1699
|
verboseLog(`Active company code: ${activeCompanyCode || 'Not found'}`);
|
|
1682
1700
|
|
|
1683
1701
|
if (!activeCompanyCode) {
|
|
1684
|
-
|
|
1685
|
-
'[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.'
|
|
1686
|
-
);
|
|
1702
|
+
loggerRef.current.error('Company code is not set. Please initialize the SDK with a valid company code.');
|
|
1687
1703
|
verboseLog('Company code missing, cannot proceed with API call');
|
|
1688
1704
|
return;
|
|
1689
1705
|
}
|
|
@@ -1691,9 +1707,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1691
1707
|
// Check if referring link is already a short code, if so save it and stop here.
|
|
1692
1708
|
verboseLog('Checking if referring link is already a short code...');
|
|
1693
1709
|
if (isShortCode(referringLink)) {
|
|
1694
|
-
|
|
1695
|
-
'[Insert Affiliate] Referring link is already a short code.'
|
|
1696
|
-
);
|
|
1710
|
+
loggerRef.current.info('Referring link is already a short code.');
|
|
1697
1711
|
verboseLog('Link is already a short code, storing directly');
|
|
1698
1712
|
await storeInsertAffiliateIdentifier({ link: referringLink, source: 'referring_link' });
|
|
1699
1713
|
return `${referringLink}-${customerID}`;
|
|
@@ -1706,7 +1720,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1706
1720
|
verboseLog('Encoding referring link for API call...');
|
|
1707
1721
|
const encodedAffiliateLink = encodeURIComponent(referringLink);
|
|
1708
1722
|
if (!encodedAffiliateLink) {
|
|
1709
|
-
|
|
1723
|
+
loggerRef.current.error('Failed to encode affiliate link.');
|
|
1710
1724
|
verboseLog('Failed to encode link, storing original');
|
|
1711
1725
|
await storeInsertAffiliateIdentifier({ link: referringLink, source: 'referring_link' });
|
|
1712
1726
|
return `${referringLink}-${customerID}`;
|
|
@@ -1714,7 +1728,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1714
1728
|
|
|
1715
1729
|
// Create the request URL
|
|
1716
1730
|
const urlString = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${activeCompanyCode}&deepLinkUrl=${encodedAffiliateLink}`;
|
|
1717
|
-
|
|
1731
|
+
loggerRef.current.info('urlString .', urlString);
|
|
1718
1732
|
verboseLog('Making API request to convert deep link to short code...');
|
|
1719
1733
|
|
|
1720
1734
|
const response = await axios.get(urlString, {
|
|
@@ -1728,21 +1742,21 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1728
1742
|
// Call to the backend for the short code and save the resolse in valid
|
|
1729
1743
|
if (response.status === 200 && response.data.shortLink) {
|
|
1730
1744
|
const shortLink = response.data.shortLink;
|
|
1731
|
-
|
|
1745
|
+
loggerRef.current.info('Short link received:', shortLink);
|
|
1732
1746
|
verboseLog(`Successfully converted to short link: ${shortLink}`);
|
|
1733
1747
|
verboseLog('Storing short link to AsyncStorage...');
|
|
1734
1748
|
await storeInsertAffiliateIdentifier({ link: shortLink, source: 'referring_link' });
|
|
1735
1749
|
verboseLog('Short link stored successfully');
|
|
1736
1750
|
return `${shortLink}-${customerID}`;
|
|
1737
1751
|
} else {
|
|
1738
|
-
|
|
1752
|
+
loggerRef.current.warn('Unexpected response format.');
|
|
1739
1753
|
verboseLog(`Unexpected API response. Status: ${response.status}, Data: ${JSON.stringify(response.data)}`);
|
|
1740
1754
|
verboseLog('Storing original link as fallback');
|
|
1741
1755
|
await storeInsertAffiliateIdentifier({ link: referringLink, source: 'referring_link' });
|
|
1742
1756
|
return `${referringLink}-${customerID}`;
|
|
1743
1757
|
}
|
|
1744
1758
|
} catch (error) {
|
|
1745
|
-
|
|
1759
|
+
loggerRef.current.error('Error:', error);
|
|
1746
1760
|
verboseLog(`Error in setInsertAffiliateIdentifier: ${error}`);
|
|
1747
1761
|
}
|
|
1748
1762
|
};
|
|
@@ -1807,10 +1821,10 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1807
1821
|
(typeof jsonIapPurchase === 'string' && (jsonIapPurchase as string).includes('E_IAP_NOT_AVAILABLE'))) {
|
|
1808
1822
|
|
|
1809
1823
|
if (isDevelopmentEnvironment) {
|
|
1810
|
-
|
|
1824
|
+
loggerRef.current.warn('IAP not available in development environment. This is expected behavior.');
|
|
1811
1825
|
verboseLog('E_IAP_NOT_AVAILABLE error detected in development - gracefully handling');
|
|
1812
1826
|
} else {
|
|
1813
|
-
|
|
1827
|
+
loggerRef.current.error('IAP not available in production environment. Please check your IAP configuration.');
|
|
1814
1828
|
}
|
|
1815
1829
|
return false; // Return false but don't crash
|
|
1816
1830
|
}
|
|
@@ -1866,10 +1880,10 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1866
1880
|
});
|
|
1867
1881
|
|
|
1868
1882
|
if (response.status === 200) {
|
|
1869
|
-
|
|
1883
|
+
loggerRef.current.info('Validation successful:', response.data);
|
|
1870
1884
|
return true;
|
|
1871
1885
|
} else {
|
|
1872
|
-
|
|
1886
|
+
loggerRef.current.error('Validation failed:', response.data);
|
|
1873
1887
|
return false;
|
|
1874
1888
|
}
|
|
1875
1889
|
} catch (error) {
|
|
@@ -1878,22 +1892,18 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1878
1892
|
(error instanceof Error && error.message.includes('E_IAP_NOT_AVAILABLE'))) {
|
|
1879
1893
|
|
|
1880
1894
|
if (isDevelopmentEnvironment) {
|
|
1881
|
-
|
|
1895
|
+
loggerRef.current.warn('IAP not available in development environment. SDK will continue without purchase validation.');
|
|
1882
1896
|
verboseLog('E_IAP_NOT_AVAILABLE error caught in validatePurchaseWithIapticAPI - gracefully handling in development');
|
|
1883
1897
|
} else {
|
|
1884
|
-
|
|
1898
|
+
loggerRef.current.error('IAP not available in production environment. Please check your IAP configuration.');
|
|
1885
1899
|
}
|
|
1886
1900
|
return false; // Return false but don't crash
|
|
1887
1901
|
}
|
|
1888
1902
|
|
|
1889
1903
|
if (error instanceof Error) {
|
|
1890
|
-
|
|
1904
|
+
loggerRef.current.error(`validatePurchaseWithIapticAPI Error: ${error.message}`);
|
|
1891
1905
|
} else {
|
|
1892
|
-
|
|
1893
|
-
`validatePurchaseWithIapticAPI Unknown Error: ${JSON.stringify(
|
|
1894
|
-
error
|
|
1895
|
-
)}`
|
|
1896
|
-
);
|
|
1906
|
+
loggerRef.current.error(`validatePurchaseWithIapticAPI Unknown Error: ${JSON.stringify(error)}`);
|
|
1897
1907
|
}
|
|
1898
1908
|
|
|
1899
1909
|
return false;
|
|
@@ -1905,14 +1915,14 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1905
1915
|
|
|
1906
1916
|
const activeCompanyCode = await getActiveCompanyCode();
|
|
1907
1917
|
if (!activeCompanyCode) {
|
|
1908
|
-
|
|
1918
|
+
loggerRef.current.error("Company code is not set. Please initialize the SDK with a valid company code.");
|
|
1909
1919
|
verboseLog("Cannot store transaction: no company code available");
|
|
1910
1920
|
return;
|
|
1911
1921
|
}
|
|
1912
1922
|
|
|
1913
1923
|
const shortCode = await returnInsertAffiliateIdentifierImpl();
|
|
1914
1924
|
if (!shortCode) {
|
|
1915
|
-
|
|
1925
|
+
loggerRef.current.error("No affiliate identifier found. Please set one before tracking events.");
|
|
1916
1926
|
verboseLog("Cannot store transaction: no affiliate identifier available");
|
|
1917
1927
|
return;
|
|
1918
1928
|
}
|
|
@@ -1927,7 +1937,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1927
1937
|
storedDate: new Date().toISOString(), // ISO8601 format
|
|
1928
1938
|
};
|
|
1929
1939
|
|
|
1930
|
-
|
|
1940
|
+
loggerRef.current.info("Storing expected transaction: ", payload);
|
|
1931
1941
|
verboseLog("Making API call to store expected transaction...");
|
|
1932
1942
|
|
|
1933
1943
|
try {
|
|
@@ -1942,15 +1952,15 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1942
1952
|
verboseLog(`API response status: ${response.status}`);
|
|
1943
1953
|
|
|
1944
1954
|
if (response.ok) {
|
|
1945
|
-
|
|
1955
|
+
loggerRef.current.info("Expected transaction stored successfully.");
|
|
1946
1956
|
verboseLog("Expected transaction stored successfully on server");
|
|
1947
1957
|
} else {
|
|
1948
1958
|
const errorText = await response.text();
|
|
1949
|
-
|
|
1959
|
+
loggerRef.current.error(`Failed to store expected transaction with status code: ${response.status}. Response: ${errorText}`);
|
|
1950
1960
|
verboseLog(`API error response: ${errorText}`);
|
|
1951
1961
|
}
|
|
1952
1962
|
} catch (error) {
|
|
1953
|
-
|
|
1963
|
+
loggerRef.current.error(`Error storing expected transaction: ${error}`);
|
|
1954
1964
|
verboseLog(`Network error storing transaction: ${error}`);
|
|
1955
1965
|
}
|
|
1956
1966
|
};
|
|
@@ -1962,17 +1972,15 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1962
1972
|
|
|
1963
1973
|
const activeCompanyCode = await getActiveCompanyCode();
|
|
1964
1974
|
if (!activeCompanyCode) {
|
|
1965
|
-
|
|
1975
|
+
loggerRef.current.error("Company code is not set. Please initialize the SDK with a valid company code.");
|
|
1966
1976
|
verboseLog("Cannot track event: no company code available");
|
|
1967
1977
|
return Promise.resolve();
|
|
1968
1978
|
}
|
|
1969
1979
|
|
|
1970
|
-
|
|
1980
|
+
loggerRef.current.info("track event called with - companyCode: ", activeCompanyCode);
|
|
1971
1981
|
|
|
1972
1982
|
if (!referrerLink || !userId) {
|
|
1973
|
-
|
|
1974
|
-
'[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.'
|
|
1975
|
-
);
|
|
1983
|
+
loggerRef.current.warn('No affiliate identifier found. Please set one before tracking events.');
|
|
1976
1984
|
verboseLog("Cannot track event: no affiliate identifier available");
|
|
1977
1985
|
return Promise.resolve();
|
|
1978
1986
|
}
|
|
@@ -2001,16 +2009,14 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
2001
2009
|
verboseLog(`Track event API response status: ${response.status}`);
|
|
2002
2010
|
|
|
2003
2011
|
if (response.status === 200) {
|
|
2004
|
-
|
|
2012
|
+
loggerRef.current.info('Event tracked successfully');
|
|
2005
2013
|
verboseLog("Event tracked successfully on server");
|
|
2006
2014
|
} else {
|
|
2007
|
-
|
|
2008
|
-
`[Insert Affiliate] Failed to track event with status code: ${response.status}`
|
|
2009
|
-
);
|
|
2015
|
+
loggerRef.current.error(`Failed to track event with status code: ${response.status}`);
|
|
2010
2016
|
verboseLog(`Track event API error: status ${response.status}, response: ${JSON.stringify(response.data)}`);
|
|
2011
2017
|
}
|
|
2012
2018
|
} catch (error) {
|
|
2013
|
-
|
|
2019
|
+
loggerRef.current.error('Error tracking event:', error);
|
|
2014
2020
|
verboseLog(`Network error tracking event: ${error}`);
|
|
2015
2021
|
return Promise.reject(error);
|
|
2016
2022
|
}
|
|
@@ -2050,7 +2056,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
2050
2056
|
offerCode.includes("errorAffiliateoffercodenotfoundinanycompanyAffiliatelinkwas") ||
|
|
2051
2057
|
offerCode.includes("Routenotfound")
|
|
2052
2058
|
)) {
|
|
2053
|
-
|
|
2059
|
+
loggerRef.current.warn(`Offer code not found or invalid: ${offerCode}`);
|
|
2054
2060
|
verboseLog(`Offer code not found or invalid: ${offerCode}`);
|
|
2055
2061
|
return null;
|
|
2056
2062
|
}
|
|
@@ -2059,12 +2065,12 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
2059
2065
|
verboseLog(`Successfully fetched and cleaned offer code: ${cleanedOfferCode}`);
|
|
2060
2066
|
return cleanedOfferCode;
|
|
2061
2067
|
} else {
|
|
2062
|
-
|
|
2068
|
+
loggerRef.current.error(`Failed to fetch offer code. Status code: ${response.status}, Response: ${JSON.stringify(response.data)}`);
|
|
2063
2069
|
verboseLog(`Failed to fetch offer code. Status code: ${response.status}, Response: ${JSON.stringify(response.data)}`);
|
|
2064
2070
|
return null;
|
|
2065
2071
|
}
|
|
2066
2072
|
} catch (error) {
|
|
2067
|
-
|
|
2073
|
+
loggerRef.current.error('Error fetching offer code:', error);
|
|
2068
2074
|
verboseLog(`Error fetching offer code: ${error}`);
|
|
2069
2075
|
return null;
|
|
2070
2076
|
}
|
|
@@ -2081,7 +2087,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
2081
2087
|
await saveValueInAsync(ASYNC_KEYS.OFFER_CODE, offerCode);
|
|
2082
2088
|
setOfferCode(offerCode);
|
|
2083
2089
|
verboseLog(`Successfully stored offer code: ${offerCode}`);
|
|
2084
|
-
|
|
2090
|
+
loggerRef.current.info('Offer code retrieved and stored successfully');
|
|
2085
2091
|
return offerCode;
|
|
2086
2092
|
} else {
|
|
2087
2093
|
verboseLog('No valid offer code found to store');
|
|
@@ -2091,7 +2097,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
2091
2097
|
return null;
|
|
2092
2098
|
}
|
|
2093
2099
|
} catch (error) {
|
|
2094
|
-
|
|
2100
|
+
loggerRef.current.error('Error retrieving and storing offer code:', error);
|
|
2095
2101
|
verboseLog(`Error in retrieveAndStoreOfferCode: ${error}`);
|
|
2096
2102
|
return null;
|
|
2097
2103
|
}
|
|
@@ -2212,6 +2218,10 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
2212
2218
|
return handleInsertLinksImplRef.current(url);
|
|
2213
2219
|
}, []);
|
|
2214
2220
|
|
|
2221
|
+
const setLogger = useCallback((logger: InsertAffiliateLogger) => {
|
|
2222
|
+
loggerRef.current = logger;
|
|
2223
|
+
}, []);
|
|
2224
|
+
|
|
2215
2225
|
return (
|
|
2216
2226
|
<DeepLinkIapContext.Provider
|
|
2217
2227
|
value={{
|
|
@@ -2232,6 +2242,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
2232
2242
|
setInsertAffiliateIdentifierChangeCallback: setInsertAffiliateIdentifierChangeCallbackHandler,
|
|
2233
2243
|
handleInsertLinks,
|
|
2234
2244
|
initialize,
|
|
2245
|
+
setLogger,
|
|
2235
2246
|
isInitialized,
|
|
2236
2247
|
}}
|
|
2237
2248
|
>
|