insert-affiliate-react-native-sdk 1.4.9 → 1.5.1

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.
@@ -15,7 +15,7 @@ type T_DEEPLINK_IAP_CONTEXT = {
15
15
  trackEvent: (eventName: string) => Promise<void>;
16
16
  setShortCode: (shortCode: string) => Promise<void>;
17
17
  setInsertAffiliateIdentifier: (referringLink: string) => Promise<void | string>;
18
- initialize: (code: string | null) => Promise<void>;
18
+ initialize: (code: string | null, verboseLogging?: boolean) => Promise<void>;
19
19
  isInitialized: boolean;
20
20
  };
21
21
  export declare const DeepLinkIapContext: React.Context<T_DEEPLINK_IAP_CONTEXT>;
@@ -58,7 +58,7 @@ exports.DeepLinkIapContext = (0, react_1.createContext)({
58
58
  trackEvent: (eventName) => __awaiter(void 0, void 0, void 0, function* () { }),
59
59
  setShortCode: (shortCode) => __awaiter(void 0, void 0, void 0, function* () { }),
60
60
  setInsertAffiliateIdentifier: (referringLink) => __awaiter(void 0, void 0, void 0, function* () { }),
61
- initialize: (code) => __awaiter(void 0, void 0, void 0, function* () { }),
61
+ initialize: (code, verboseLogging) => __awaiter(void 0, void 0, void 0, function* () { }),
62
62
  isInitialized: false,
63
63
  });
64
64
  const DeepLinkIapProvider = ({ children, }) => {
@@ -66,8 +66,15 @@ const DeepLinkIapProvider = ({ children, }) => {
66
66
  const [userId, setUserId] = (0, react_1.useState)('');
67
67
  const [companyCode, setCompanyCode] = (0, react_1.useState)(null);
68
68
  const [isInitialized, setIsInitialized] = (0, react_1.useState)(false);
69
+ const [verboseLogging, setVerboseLogging] = (0, react_1.useState)(false);
69
70
  // MARK: Initialize the SDK
70
- const initialize = (companyCode) => __awaiter(void 0, void 0, void 0, function* () {
71
+ const initialize = (companyCode_1, ...args_1) => __awaiter(void 0, [companyCode_1, ...args_1], void 0, function* (companyCode, verboseLogging = false) {
72
+ setVerboseLogging(verboseLogging);
73
+ if (verboseLogging) {
74
+ console.log('[Insert Affiliate] [VERBOSE] Starting SDK initialization...');
75
+ console.log('[Insert Affiliate] [VERBOSE] Company code provided:', companyCode ? 'Yes' : 'No');
76
+ console.log('[Insert Affiliate] [VERBOSE] Verbose logging enabled');
77
+ }
71
78
  if (isInitialized) {
72
79
  console.error('[Insert Affiliate] SDK is already initialized.');
73
80
  return;
@@ -77,10 +84,17 @@ const DeepLinkIapProvider = ({ children, }) => {
77
84
  yield saveValueInAsync(ASYNC_KEYS.COMPANY_CODE, companyCode);
78
85
  setIsInitialized(true);
79
86
  console.log(`[Insert Affiliate] SDK initialized with company code: ${companyCode}`);
87
+ if (verboseLogging) {
88
+ console.log('[Insert Affiliate] [VERBOSE] Company code saved to AsyncStorage');
89
+ console.log('[Insert Affiliate] [VERBOSE] SDK marked as initialized');
90
+ }
80
91
  }
81
92
  else {
82
93
  console.warn('[Insert Affiliate] SDK initialized without a company code.');
83
94
  setIsInitialized(true);
95
+ if (verboseLogging) {
96
+ console.log('[Insert Affiliate] [VERBOSE] No company code provided, SDK initialized in limited mode');
97
+ }
84
98
  }
85
99
  });
86
100
  // EFFECT TO FETCH USER ID AND REF LINK
@@ -88,28 +102,43 @@ const DeepLinkIapProvider = ({ children, }) => {
88
102
  (0, react_1.useEffect)(() => {
89
103
  const fetchAsyncEssentials = () => __awaiter(void 0, void 0, void 0, function* () {
90
104
  try {
105
+ verboseLog('Loading stored data from AsyncStorage...');
91
106
  const uId = yield getValueFromAsync(ASYNC_KEYS.USER_ID);
92
107
  const refLink = yield getValueFromAsync(ASYNC_KEYS.REFERRER_LINK);
108
+ const companyCodeFromStorage = yield getValueFromAsync(ASYNC_KEYS.COMPANY_CODE);
109
+ verboseLog(`User ID found: ${uId ? 'Yes' : 'No'}`);
110
+ verboseLog(`Referrer link found: ${refLink ? 'Yes' : 'No'}`);
111
+ verboseLog(`Company code found: ${companyCodeFromStorage ? 'Yes' : 'No'}`);
93
112
  if (uId && refLink) {
94
113
  setUserId(uId);
95
114
  setReferrerLink(refLink);
115
+ verboseLog('User ID and referrer link restored from storage');
116
+ }
117
+ if (companyCodeFromStorage) {
118
+ setCompanyCode(companyCodeFromStorage);
119
+ verboseLog('Company code restored from storage');
96
120
  }
97
121
  }
98
122
  catch (error) {
99
123
  errorLog(`ERROR ~ fetchAsyncEssentials: ${error}`);
124
+ verboseLog(`Error loading from AsyncStorage: ${error}`);
100
125
  }
101
126
  });
102
127
  fetchAsyncEssentials();
103
128
  }, []);
104
129
  function generateThenSetUserID() {
105
130
  return __awaiter(this, void 0, void 0, function* () {
131
+ verboseLog('Getting or generating user ID...');
106
132
  let userId = yield getValueFromAsync(ASYNC_KEYS.USER_ID);
107
133
  if (!userId) {
134
+ verboseLog('No existing user ID found, generating new one...');
108
135
  userId = generateUserID();
109
136
  setUserId(userId);
110
137
  yield saveValueInAsync(ASYNC_KEYS.USER_ID, userId);
138
+ verboseLog(`Generated and saved new user ID: ${userId}`);
111
139
  }
112
140
  else {
141
+ verboseLog(`Found existing user ID: ${userId}`);
113
142
  setUserId(userId);
114
143
  }
115
144
  return userId;
@@ -140,6 +169,29 @@ const DeepLinkIapProvider = ({ children, }) => {
140
169
  const clearAsyncStorage = () => __awaiter(void 0, void 0, void 0, function* () {
141
170
  yield async_storage_1.default.clear();
142
171
  });
172
+ // Helper function to get company code from state or storage
173
+ const getActiveCompanyCode = () => __awaiter(void 0, void 0, void 0, function* () {
174
+ verboseLog('Getting active company code...');
175
+ let activeCompanyCode = companyCode;
176
+ verboseLog(`Company code in React state: ${activeCompanyCode || 'empty'}`);
177
+ if (!activeCompanyCode || (activeCompanyCode.trim() === '' && activeCompanyCode !== null)) {
178
+ verboseLog('Company code not in state, checking AsyncStorage...');
179
+ activeCompanyCode = yield getValueFromAsync(ASYNC_KEYS.COMPANY_CODE);
180
+ verboseLog(`Company code in AsyncStorage: ${activeCompanyCode || 'empty'}`);
181
+ if (activeCompanyCode) {
182
+ // Update state for future use
183
+ setCompanyCode(activeCompanyCode);
184
+ verboseLog('Updated React state with company code from storage');
185
+ }
186
+ }
187
+ return activeCompanyCode;
188
+ });
189
+ // Helper function for verbose logging
190
+ const verboseLog = (message) => {
191
+ if (verboseLogging) {
192
+ console.log(`[Insert Affiliate] [VERBOSE] ${message}`);
193
+ }
194
+ };
143
195
  // Helper function to log errors
144
196
  const errorLog = (message, type) => {
145
197
  switch (type) {
@@ -158,7 +210,7 @@ const DeepLinkIapProvider = ({ children, }) => {
158
210
  const isShortCode = (referringLink) => {
159
211
  // Short codes are less than 10 characters
160
212
  const isValidCharacters = /^[a-zA-Z0-9]+$/.test(referringLink);
161
- return isValidCharacters && referringLink.length < 10;
213
+ return isValidCharacters && referringLink.length < 25 && referringLink.length > 3;
162
214
  };
163
215
  function setShortCode(shortCode) {
164
216
  return __awaiter(this, void 0, void 0, function* () {
@@ -207,12 +259,32 @@ const DeepLinkIapProvider = ({ children, }) => {
207
259
  ;
208
260
  });
209
261
  // MARK: Return Insert Affiliate Identifier
262
+ // Instead of just reading React state
210
263
  const returnInsertAffiliateIdentifier = () => __awaiter(void 0, void 0, void 0, function* () {
211
264
  try {
212
- return `${referrerLink}-${userId}`;
265
+ verboseLog('Getting insert affiliate identifier...');
266
+ verboseLog(`React state - referrerLink: ${referrerLink || 'empty'}, userId: ${userId || 'empty'}`);
267
+ // Try React state first
268
+ if (referrerLink && userId) {
269
+ const identifier = `${referrerLink}-${userId}`;
270
+ verboseLog(`Found identifier in React state: ${identifier}`);
271
+ return identifier;
272
+ }
273
+ verboseLog('React state empty, checking AsyncStorage...');
274
+ // Fallback to async storage if React state is empty
275
+ const storedLink = yield getValueFromAsync(ASYNC_KEYS.REFERRER_LINK);
276
+ const storedUserId = yield getValueFromAsync(ASYNC_KEYS.USER_ID);
277
+ verboseLog(`AsyncStorage - storedLink: ${storedLink || 'empty'}, storedUserId: ${storedUserId || 'empty'}`);
278
+ if (storedLink && storedUserId) {
279
+ const identifier = `${storedLink}-${storedUserId}`;
280
+ verboseLog(`Found identifier in AsyncStorage: ${identifier}`);
281
+ return identifier;
282
+ }
283
+ verboseLog('No affiliate identifier found in state or storage');
284
+ return null;
213
285
  }
214
286
  catch (error) {
215
- errorLog(`ERROR ~ returnInsertAffiliateIdentifier: ${error}`);
287
+ verboseLog(`Error getting affiliate identifier: ${error}`);
216
288
  return null;
217
289
  }
218
290
  });
@@ -220,64 +292,77 @@ const DeepLinkIapProvider = ({ children, }) => {
220
292
  function setInsertAffiliateIdentifier(referringLink) {
221
293
  return __awaiter(this, void 0, void 0, function* () {
222
294
  console.log('[Insert Affiliate] Setting affiliate identifier.');
295
+ verboseLog(`Input referringLink: ${referringLink}`);
223
296
  try {
297
+ verboseLog('Generating or retrieving user ID...');
224
298
  const customerID = yield generateThenSetUserID();
225
299
  console.log('[Insert Affiliate] Completed generateThenSetUserID within setInsertAffiliateIdentifier.');
300
+ verboseLog(`Customer ID: ${customerID}`);
226
301
  if (!referringLink) {
227
302
  console.warn('[Insert Affiliate] Referring link is invalid.');
228
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
303
+ verboseLog('Referring link is empty or invalid, storing as-is');
229
304
  yield storeInsertAffiliateIdentifier({ link: referringLink });
230
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
305
+ return `${referringLink}-${customerID}`;
231
306
  }
232
- if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
233
- let companyCodeFromStorage = yield getValueFromAsync(ASYNC_KEYS.COMPANY_CODE);
234
- if (companyCodeFromStorage !== null) {
235
- setCompanyCode(companyCodeFromStorage);
236
- }
237
- else {
238
- console.error('[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.');
239
- return;
240
- }
307
+ // Get company code from state or storage
308
+ verboseLog('Getting company code...');
309
+ const activeCompanyCode = yield getActiveCompanyCode();
310
+ verboseLog(`Active company code: ${activeCompanyCode || 'Not found'}`);
311
+ if (!activeCompanyCode) {
312
+ console.error('[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.');
313
+ verboseLog('Company code missing, cannot proceed with API call');
314
+ return;
241
315
  }
242
316
  // Check if referring link is already a short code, if so save it and stop here.
317
+ verboseLog('Checking if referring link is already a short code...');
243
318
  if (isShortCode(referringLink)) {
244
319
  console.log('[Insert Affiliate] Referring link is already a short code.');
245
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
320
+ verboseLog('Link is already a short code, storing directly');
246
321
  yield storeInsertAffiliateIdentifier({ link: referringLink });
247
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
322
+ return `${referringLink}-${customerID}`;
248
323
  }
324
+ verboseLog('Link is not a short code, will convert via API');
249
325
  // If the code is not already a short code, encode it raedy to send to our endpoint to return the short code. Save it before making the call in case something goes wrong
250
326
  // Encode the referring link
327
+ verboseLog('Encoding referring link for API call...');
251
328
  const encodedAffiliateLink = encodeURIComponent(referringLink);
252
329
  if (!encodedAffiliateLink) {
253
330
  console.error('[Insert Affiliate] Failed to encode affiliate link.');
254
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
331
+ verboseLog('Failed to encode link, storing original');
255
332
  yield storeInsertAffiliateIdentifier({ link: referringLink });
256
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
333
+ return `${referringLink}-${customerID}`;
257
334
  }
258
335
  // Create the request URL
259
- const urlString = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${companyCode}&deepLinkUrl=${encodedAffiliateLink}`;
336
+ const urlString = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${activeCompanyCode}&deepLinkUrl=${encodedAffiliateLink}`;
260
337
  console.log('[Insert Affiliate] urlString .', urlString);
338
+ verboseLog('Making API request to convert deep link to short code...');
261
339
  const response = yield axios_1.default.get(urlString, {
262
340
  headers: {
263
341
  'Content-Type': 'application/json',
264
342
  },
265
343
  });
344
+ verboseLog(`API response status: ${response.status}`);
266
345
  // Call to the backend for the short code and save the resolse in valid
267
346
  if (response.status === 200 && response.data.shortLink) {
268
347
  const shortLink = response.data.shortLink;
269
348
  console.log('[Insert Affiliate] Short link received:', shortLink);
349
+ verboseLog(`Successfully converted to short link: ${shortLink}`);
350
+ verboseLog('Storing short link to AsyncStorage...');
351
+ yield storeInsertAffiliateIdentifier({ link: shortLink });
352
+ verboseLog('Short link stored successfully');
270
353
  return `${shortLink}-${customerID}`;
271
354
  }
272
355
  else {
273
356
  console.warn('[Insert Affiliate] Unexpected response format.');
274
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
357
+ verboseLog(`Unexpected API response. Status: ${response.status}, Data: ${JSON.stringify(response.data)}`);
358
+ verboseLog('Storing original link as fallback');
275
359
  yield storeInsertAffiliateIdentifier({ link: referringLink });
276
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
360
+ return `${referringLink}-${customerID}`;
277
361
  }
278
362
  }
279
363
  catch (error) {
280
364
  console.error('[Insert Affiliate] Error:', error);
365
+ verboseLog(`Error in setInsertAffiliateIdentifier: ${error}`);
281
366
  }
282
367
  });
283
368
  }
@@ -285,8 +370,11 @@ const DeepLinkIapProvider = ({ children, }) => {
285
370
  function storeInsertAffiliateIdentifier(_a) {
286
371
  return __awaiter(this, arguments, void 0, function* ({ link }) {
287
372
  console.log(`[Insert Affiliate] Storing affiliate identifier: ${link}`);
373
+ verboseLog(`Updating React state with referrer link: ${link}`);
288
374
  setReferrerLink(link);
375
+ verboseLog(`Saving referrer link to AsyncStorage...`);
289
376
  yield saveValueInAsync(ASYNC_KEYS.REFERRER_LINK, link);
377
+ verboseLog(`Referrer link saved to AsyncStorage successfully`);
290
378
  });
291
379
  }
292
380
  const validatePurchaseWithIapticAPI = (jsonIapPurchase, iapticAppId, iapticAppName, iapticPublicKey) => __awaiter(void 0, void 0, void 0, function* () {
@@ -350,23 +438,29 @@ const DeepLinkIapProvider = ({ children, }) => {
350
438
  }
351
439
  });
352
440
  const storeExpectedStoreTransaction = (purchaseToken) => __awaiter(void 0, void 0, void 0, function* () {
353
- if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
441
+ verboseLog(`Storing expected store transaction with token: ${purchaseToken}`);
442
+ const activeCompanyCode = yield getActiveCompanyCode();
443
+ if (!activeCompanyCode) {
354
444
  console.error("[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.");
445
+ verboseLog("Cannot store transaction: no company code available");
355
446
  return;
356
447
  }
357
448
  const shortCode = yield returnInsertAffiliateIdentifier();
358
449
  if (!shortCode) {
359
450
  console.error("[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.");
451
+ verboseLog("Cannot store transaction: no affiliate identifier available");
360
452
  return;
361
453
  }
454
+ verboseLog(`Company code: ${activeCompanyCode}, Short code: ${shortCode}`);
362
455
  // Build JSON payload
363
456
  const payload = {
364
457
  UUID: purchaseToken,
365
- companyCode,
458
+ companyCode: activeCompanyCode,
366
459
  shortCode,
367
460
  storedDate: new Date().toISOString(), // ISO8601 format
368
461
  };
369
462
  console.log("[Insert Affiliate] Storing expected transaction: ", payload);
463
+ verboseLog("Making API call to store expected transaction...");
370
464
  try {
371
465
  const response = yield fetch("https://api.insertaffiliate.com/v1/api/app-store-webhook/create-expected-transaction", {
372
466
  method: "POST",
@@ -375,47 +469,63 @@ const DeepLinkIapProvider = ({ children, }) => {
375
469
  },
376
470
  body: JSON.stringify(payload),
377
471
  });
472
+ verboseLog(`API response status: ${response.status}`);
378
473
  if (response.ok) {
379
474
  console.info("[Insert Affiliate] Expected transaction stored successfully.");
475
+ verboseLog("Expected transaction stored successfully on server");
380
476
  }
381
477
  else {
382
478
  const errorText = yield response.text();
383
479
  console.error(`[Insert Affiliate] Failed to store expected transaction with status code: ${response.status}. Response: ${errorText}`);
480
+ verboseLog(`API error response: ${errorText}`);
384
481
  }
385
482
  }
386
483
  catch (error) {
387
484
  console.error(`[Insert Affiliate] Error storing expected transaction: ${error}`);
485
+ verboseLog(`Network error storing transaction: ${error}`);
388
486
  }
389
487
  });
390
488
  // MARK: Track Event
391
489
  const trackEvent = (eventName) => __awaiter(void 0, void 0, void 0, function* () {
392
490
  try {
393
- if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
491
+ verboseLog(`Tracking event: ${eventName}`);
492
+ const activeCompanyCode = yield getActiveCompanyCode();
493
+ if (!activeCompanyCode) {
394
494
  console.error("[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.");
495
+ verboseLog("Cannot track event: no company code available");
395
496
  return Promise.resolve();
396
497
  }
397
- console.log("track event called with - companyCode: ", companyCode);
498
+ console.log("track event called with - companyCode: ", activeCompanyCode);
398
499
  if (!referrerLink || !userId) {
399
500
  console.warn('[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.');
501
+ verboseLog("Cannot track event: no affiliate identifier available");
400
502
  return Promise.resolve();
401
503
  }
504
+ const deepLinkParam = `${referrerLink}-${userId}`;
505
+ verboseLog(`Deep link param: ${deepLinkParam}`);
402
506
  const payload = {
403
507
  eventName,
404
- deepLinkParam: `${referrerLink}-${userId}`,
405
- companyId: companyCode,
508
+ deepLinkParam: deepLinkParam,
509
+ companyId: activeCompanyCode,
406
510
  };
511
+ verboseLog(`Track event payload: ${JSON.stringify(payload)}`);
512
+ verboseLog("Making API call to track event...");
407
513
  const response = yield axios_1.default.post('https://api.insertaffiliate.com/v1/trackEvent', payload, {
408
514
  headers: { 'Content-Type': 'application/json' },
409
515
  });
516
+ verboseLog(`Track event API response status: ${response.status}`);
410
517
  if (response.status === 200) {
411
518
  console.log('[Insert Affiliate] Event tracked successfully');
519
+ verboseLog("Event tracked successfully on server");
412
520
  }
413
521
  else {
414
522
  console.error(`[Insert Affiliate] Failed to track event with status code: ${response.status}`);
523
+ verboseLog(`Track event API error: status ${response.status}, response: ${JSON.stringify(response.data)}`);
415
524
  }
416
525
  }
417
526
  catch (error) {
418
527
  console.error('[Insert Affiliate] Error tracking event:', error);
528
+ verboseLog(`Network error tracking event: ${error}`);
419
529
  return Promise.reject(error);
420
530
  }
421
531
  });
@@ -10,7 +10,7 @@ declare const useDeepLinkIapProvider: () => {
10
10
  trackEvent: (eventName: string) => Promise<void>;
11
11
  setShortCode: (shortCode: string) => Promise<void>;
12
12
  setInsertAffiliateIdentifier: (referringLink: string) => Promise<void | string>;
13
- initialize: (code: string | null) => Promise<void>;
13
+ initialize: (code: string | null, verboseLogging?: boolean) => Promise<void>;
14
14
  isInitialized: boolean;
15
15
  };
16
16
  export default useDeepLinkIapProvider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "insert-affiliate-react-native-sdk",
3
- "version": "1.4.9",
3
+ "version": "1.5.1",
4
4
  "description": "A package for connecting with the Insert Affiliate Platform to add app based affiliate marketing.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/readme.md CHANGED
@@ -15,9 +15,9 @@ The **InsertAffiliateReactNative SDK** is designed for React Native applications
15
15
  To get started with the InsertAffiliateReactNative SDK:
16
16
 
17
17
  1. [Install the SDK](#installation)
18
- 2. [Initialise the SDK in App.tsx](#basic-usage)
18
+ 2. [Set up the provider in Index.js and initialize the SDK in App.tsx](#basic-usage)
19
19
  3. [Set up in-app purchases (Required)](#in-app-purchase-setup-required)
20
- 4. [Set up deep linking (Required)](#deep-link-setup-required)
20
+ 4. [Set up deep linking in Index.js (Required)](#deep-link-setup-required)
21
21
 
22
22
  ## Installation
23
23
 
@@ -28,45 +28,109 @@ To integrate the InsertAffiliateReactNative SDK into your app:
28
28
  npm install insert-affiliate-react-native-sdk
29
29
  ```
30
30
 
31
+ ## Architecture Overview
32
+
33
+ The SDK uses a clean, two-file architecture:
34
+
35
+ - **`index.js`** (Entry Point): Provider wrapper and deep link handling
36
+ - **`App.tsx`** (UI Logic): SDK initialization and your app components
37
+
38
+ This separation ensures clean code organization and proper initialization timing.
39
+
31
40
  ## Basic Usage
32
41
 
33
42
  Follow the steps below to install the SDK.
34
43
 
35
- #### Step 1: Initialisation in `App.tsx`
44
+ ### Step 1: Entry Point in `Index.js`
45
+ ```javascript
46
+ import React from 'react';
47
+ import {AppRegistry} from 'react-native';
48
+ import App from './App';
49
+ import {name as appName} from './app.json';
50
+ import {DeepLinkIapProvider} from 'insert-affiliate-react-native-sdk';
51
+
52
+ const RootComponent = () => {
53
+ return (
54
+ <DeepLinkIapProvider>
55
+ <App />
56
+ </DeepLinkIapProvider>
57
+ );
58
+ };
59
+
60
+ AppRegistry.registerComponent(appName, () => RootComponent);
61
+ ```
62
+
63
+ #### Step 2: SDK initialization in `App.tsx`
36
64
 
37
65
  First, wrap your with our provider and call the `initialize` method early in your app's lifecycle:
38
66
 
39
67
  ```javascript
40
68
  const Child = () => {
41
- const {
42
- referrerLink,
43
- subscriptions,
44
- iapLoading,
45
- validatePurchaseWithIapticAPI,
46
- userId,
47
- userPurchase,
48
- trackEvent,
49
- initialize,
50
- isInitialized,
51
- } = useDeepLinkIapProvider();
69
+ const { initialize, isInitialized } = useDeepLinkIapProvider();
52
70
 
53
71
  useEffect(() => {
54
- initialize("{{ your-company-code }}");
72
+ if (!isInitialized) {
73
+ initialize("{{ your-company-code }}");
74
+ }
55
75
  }, [initialize, isInitialized]);
56
-
57
- // ...
58
76
  }
59
77
 
60
78
  const App = () => {
61
- return (
62
- <DeepLinkIapProvider>
63
- <Child />
64
- </DeepLinkIapProvider>
65
- );
79
+ return <Child />;
66
80
  };
67
81
  ```
68
82
  - Replace `{{ your_company_code }}` with the unique company code associated with your Insert Affiliate account. You can find this code in your dashboard under [Settings](http://app.insertaffiliate.com/settings).
69
83
 
84
+ ### Verbose Logging (Optional)
85
+
86
+ For debugging and troubleshooting, you can enable verbose logging to get detailed insights into the SDK's operations:
87
+
88
+ ```javascript
89
+ const Child = () => {
90
+ const { initialize, isInitialized } = useDeepLinkIapProvider();
91
+
92
+ useEffect(() => {
93
+ if (!isInitialized) {
94
+ // Enable verbose logging (second parameter)
95
+ initialize("{{ your-company-code }}", true);
96
+ }
97
+ }, [initialize, isInitialized]);
98
+ }
99
+ ```
100
+
101
+ **When verbose logging is enabled, you'll see detailed logs with the `[Insert Affiliate] [VERBOSE]` prefix that show:**
102
+
103
+ - **Initialization Process**: SDK startup, company code validation, AsyncStorage operations
104
+ - **Data Management**: User ID generation, referrer link storage, company code state management
105
+ - **Deep Link Processing**: Input validation, short code detection, API conversion process
106
+ - **API Communication**: Request/response details for all server calls
107
+ - **Event Tracking**: Event parameters, payload construction, success/failure status
108
+ - **Purchase Operations**: Transaction storage, token validation, webhook processing
109
+
110
+ **Example verbose output:**
111
+ ```
112
+ [Insert Affiliate] [VERBOSE] Starting SDK initialization...
113
+ [Insert Affiliate] [VERBOSE] Company code provided: Yes
114
+ [Insert Affiliate] [VERBOSE] Verbose logging enabled
115
+ [Insert Affiliate] SDK initialized with company code: your-company-code
116
+ [Insert Affiliate] [VERBOSE] Company code saved to AsyncStorage
117
+ [Insert Affiliate] [VERBOSE] SDK marked as initialized
118
+ [Insert Affiliate] [VERBOSE] Loading stored data from AsyncStorage...
119
+ [Insert Affiliate] [VERBOSE] User ID found: Yes
120
+ [Insert Affiliate] [VERBOSE] Referrer link found: Yes
121
+ [Insert Affiliate] [VERBOSE] Company code found: Yes
122
+ ```
123
+
124
+ **Benefits of verbose logging:**
125
+ - **Debug Deep Linking Issues**: See exactly what links are being processed and how they're converted
126
+ - **Monitor API Communication**: Track all server requests, responses, and error details
127
+ - **Identify Storage Problems**: Understand AsyncStorage read/write operations and state sync
128
+ - **Performance Insights**: Monitor async operation timing and identify bottlenecks
129
+ - **Integration Troubleshooting**: Quickly identify configuration or setup issues
130
+
131
+ ⚠️ **Important**: Disable verbose logging in production builds to avoid exposing sensitive debugging information and to optimize performance.
132
+
133
+
70
134
  ## In-App Purchase Setup [Required]
71
135
  Insert Affiliate requires a Receipt Verification platform to validate in-app purchases. You must choose **one** of our supported partners:
72
136
  - [RevenueCat](https://www.revenuecat.com/)
@@ -79,10 +143,12 @@ Insert Affiliate requires a Receipt Verification platform to validate in-app pur
79
143
  First, complete the [RevenueCat SDK installation](https://www.revenuecat.com/docs/getting-started/installation/reactnative). Then modify your `App.tsx`:
80
144
 
81
145
  ```javascript
82
- import {
83
- DeepLinkIapProvider,
84
- useDeepLinkIapProvider,
85
- } from 'insert-affiliate-react-native-sdk';
146
+ import React, {useEffect} from 'react';
147
+ import {AppRegistry} from 'react-native';
148
+ import branch from 'react-native-branch';
149
+ import App from './App';
150
+ import {name as appName} from './app.json';
151
+ import {useDeepLinkIapProvider, DeepLinkIapProvider} from 'insert-affiliate-react-native-sdk';
86
152
 
87
153
  // ... //
88
154
  const {
@@ -131,6 +197,7 @@ React.useEffect(() => {
131
197
 
132
198
 
133
199
  ### Option 2: Iaptic Integration
200
+ #### 1. Code Setup
134
201
  First, complete the [Iaptic account setup](https://www.iaptic.com/signup) and code integration.
135
202
 
136
203
  Then after setting up the in app purchase (IAP) with Iaptic, call Insert Affiliate's ```validatePurchaseWithIapticAPI``` on purchase.
@@ -194,10 +261,7 @@ const Child = () => {
194
261
 
195
262
  const App = () => {
196
263
  return (
197
- // Wrapped application code from the previous step...
198
- <DeepLinkIapProvider>
199
- <Child />
200
- </DeepLinkIapProvider>
264
+ <Child />
201
265
  );
202
266
  };
203
267
 
@@ -208,6 +272,18 @@ export default App;
208
272
  - Replace `{{ your_iaptic_public_key }}` with your **Iaptic Public Key**. You can find this [here](https://www.iaptic.com/settings).
209
273
  - Replace `{{ your_company_code }}` with the unique company code associated with your Insert Affiliate account. You can find this code in your dashboard under [Settings](http://app.insertaffiliate.com/settings).
210
274
 
275
+ #### 2. Webhook Setup
276
+ 1. Open the [Insert Affiliate settings](https://app.insertaffiliate.com/settings):
277
+ - Navigate to the Verification Settings section
278
+ - Set the In-App Purchase Verification method to `Iaptic`
279
+ - Copy the `Iaptic Webhook URL` and the `Iaptic Webhook Sandbox URL`- you'll need it in the next step.
280
+ 2. Go to the [Iaptic Settings](https://www.iaptic.com/settings)
281
+ - Paste the copied `Iaptic Webhook URL` into the `Webhook URL` field
282
+ - Paste the copied `Iaptic Webhook Sandbox URL` into the `Sandbox Webhook URL` field
283
+ - Click **Save Settings**.
284
+ 3. Check that you have completed the [Iaptic setup for the App Store Server Notifications](https://www.iaptic.com/documentation/setup/ios-subscription-status-url)
285
+ 4. Check that you have completed the [Iaptic setup for the Google Play Notifications URL](https://www.iaptic.com/documentation/setup/connect-with-google-publisher-api)
286
+
211
287
  ### Option 3: App Store Direct Integration
212
288
 
213
289
  Our direct App Store integration is currently in beta and currently supports subscriptions only. **Consumables and one-off purchases are not yet supported** due to App Store server-to-server notification limitations.
@@ -225,7 +301,7 @@ Ensure you import the necessary dependencies, including `Platform` and `useDeepL
225
301
 
226
302
  ```javascript
227
303
  import { Platform } from 'react-native';
228
- import { DeepLinkIapProvider, useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
304
+ import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
229
305
  import { requestSubscription } from 'react-native-iap';
230
306
 
231
307
  const { returnUserAccountTokenAndStoreExpectedTransaction } = useDeepLinkIapProvider();
@@ -309,38 +385,33 @@ To set up deep linking with Branch.io, follow these steps:
309
385
 
310
386
  1. Create a deep link in Branch and pass it to our dashboard when an affiliate signs up.
311
387
  - Example: [Create Affiliate](https://docs.insertaffiliate.com/create-affiliate).
312
- 2. Modify Your Deep Link Handling in `App.tsx`
313
- - After setting up your Branch integration, add the following code to initialise our SDK in your app:
388
+ 2. Modify Your Deep Link Handling in `Index.js`
389
+ - After setting up your Branch integration, add the following code to your app:
314
390
 
315
391
 
316
392
  #### Example with RevenueCat
317
393
  ```javascript
318
- import { DeepLinkIapProvider, useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
319
- import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
394
+ import {useDeepLinkIapProvider, DeepLinkIapProvider} from 'insert-affiliate-react-native-sdk';
320
395
 
321
396
  //...
397
+ const DeepLinkHandler = () => {
322
398
  const {setInsertAffiliateIdentifier} = useDeepLinkIapProvider();
323
399
 
324
400
  useEffect(() => {
325
- if (!isInitialized) return;
326
-
327
401
  const branchSubscription = branch.subscribe(async ({error, params}) => {
328
402
  if (error) {
329
403
  console.error('Error from Branch:', error);
330
404
  return;
331
405
  }
332
406
 
333
- if (!params) {
334
- return
335
- }
336
407
  if (params['+clicked_branch_link']) {
337
408
  const referringLink = params['~referring_link'];
338
409
  if (referringLink) {
339
410
  try {
340
- let insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
411
+ let insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
341
412
 
342
413
  if (insertAffiliateIdentifier) {
343
- await Purchases.setAttributes({"insert_affiliate" : affiliateIdentifier});
414
+ await Purchases.setAttributes({"insert_affiliate" : insertAffiliateIdentifier});
344
415
  }
345
416
 
346
417
  } catch (err) {
@@ -350,35 +421,68 @@ import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
350
421
  }
351
422
  });
352
423
 
353
- // Cleanup the subscription on component unmount
354
424
  return () => {
355
425
  branchSubscription();
356
426
  };
357
- }, [setInsertAffiliateIdentifier, isInitialized]);
427
+ }, [setInsertAffiliateIdentifier]);
428
+
429
+ return <App />;
430
+ };
431
+
432
+ const RootComponent = () => {
433
+ return (
434
+ <DeepLinkIapProvider>
435
+ <DeepLinkHandler />
436
+ </DeepLinkIapProvider>
437
+ );
438
+ };
439
+
440
+ AppRegistry.registerComponent(appName, () => RootComponent);
441
+
358
442
  //...
359
443
  ```
360
444
 
361
445
  #### Example with Iaptic / App Store Direct Integration / Google Play Direct Integration
362
446
  ```javascript
363
447
  import branch from 'react-native-branch';
364
- import { DeepLinkIapProvider, useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
365
- const {setInsertAffiliateIdentifier} = useDeepLinkIapProvider();
448
+ import {useDeepLinkIapProvider, DeepLinkIapProvider} from 'insert-affiliate-react-native-sdk';
366
449
 
367
- branch.subscribe(async ({ error, params }) => {
368
- if (error) {
369
- console.error('Error from Branch: ' + error);
370
- return;
371
- }
372
-
373
- if (params['+clicked_branch_link']) {
374
- if (params["~referring_link"]) {
375
- setInsertAffiliateIdentifier(params["~referring_link"], (shortLink) => {
376
- console.log("Insert Affiliate - setInsertAffiliateIdentifier: ", params["~referring_link"], " - Stored shortLink ", shortLink);
377
- });
450
+ const DeepLinkHandler = () => {
451
+ const {setInsertAffiliateIdentifier} = useDeepLinkIapProvider();
452
+
453
+ React.useEffect(() => {
454
+ const branchSubscription = branch.subscribe(async ({error, params}) => {
455
+ if (error) {
456
+ console.error('Error from Branch:', error);
457
+ return;
458
+ }
459
+
460
+ if (params['+clicked_branch_link']) {
461
+ const referringLink = params['~referring_link'];
462
+ if (referringLink) {
463
+ try {
464
+ await setInsertAffiliateIdentifier(referringLink);
465
+ console.log('Affiliate identifier set successfully.');
466
+ } catch (err) {
467
+ console.error('Error setting affiliate identifier:', err);
468
+ }
378
469
  }
379
- }
380
- });
470
+ }
471
+ });
472
+
473
+ return () => branchSubscription();
474
+ }, [setInsertAffiliateIdentifier]);
381
475
 
476
+ return <App />;
477
+ };
478
+
479
+ const RootComponent = () => {
480
+ return (
481
+ <DeepLinkIapProvider>
482
+ <DeepLinkHandler />
483
+ </DeepLinkIapProvider>
484
+ );
485
+ };
382
486
  ```
383
487
 
384
488
  ## Additional Features
@@ -31,7 +31,7 @@ type T_DEEPLINK_IAP_CONTEXT = {
31
31
  setInsertAffiliateIdentifier: (
32
32
  referringLink: string
33
33
  ) => Promise<void | string>;
34
- initialize: (code: string | null) => Promise<void>;
34
+ initialize: (code: string | null, verboseLogging?: boolean) => Promise<void>;
35
35
  isInitialized: boolean;
36
36
  };
37
37
 
@@ -75,7 +75,7 @@ export const DeepLinkIapContext = createContext<T_DEEPLINK_IAP_CONTEXT>({
75
75
  trackEvent: async (eventName: string) => {},
76
76
  setShortCode: async (shortCode: string) => {},
77
77
  setInsertAffiliateIdentifier: async (referringLink: string) => {},
78
- initialize: async (code: string | null) => {},
78
+ initialize: async (code: string | null, verboseLogging?: boolean) => {},
79
79
  isInitialized: false,
80
80
  });
81
81
 
@@ -86,9 +86,18 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
86
86
  const [userId, setUserId] = useState<string>('');
87
87
  const [companyCode, setCompanyCode] = useState<string | null>(null);
88
88
  const [isInitialized, setIsInitialized] = useState<boolean>(false);
89
+ const [verboseLogging, setVerboseLogging] = useState<boolean>(false);
89
90
 
90
91
  // MARK: Initialize the SDK
91
- const initialize = async (companyCode: string | null): Promise<void> => {
92
+ const initialize = async (companyCode: string | null, verboseLogging: boolean = false): Promise<void> => {
93
+ setVerboseLogging(verboseLogging);
94
+
95
+ if (verboseLogging) {
96
+ console.log('[Insert Affiliate] [VERBOSE] Starting SDK initialization...');
97
+ console.log('[Insert Affiliate] [VERBOSE] Company code provided:', companyCode ? 'Yes' : 'No');
98
+ console.log('[Insert Affiliate] [VERBOSE] Verbose logging enabled');
99
+ }
100
+
92
101
  if (isInitialized) {
93
102
  console.error('[Insert Affiliate] SDK is already initialized.');
94
103
  return;
@@ -101,11 +110,18 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
101
110
  console.log(
102
111
  `[Insert Affiliate] SDK initialized with company code: ${companyCode}`
103
112
  );
113
+ if (verboseLogging) {
114
+ console.log('[Insert Affiliate] [VERBOSE] Company code saved to AsyncStorage');
115
+ console.log('[Insert Affiliate] [VERBOSE] SDK marked as initialized');
116
+ }
104
117
  } else {
105
118
  console.warn(
106
119
  '[Insert Affiliate] SDK initialized without a company code.'
107
120
  );
108
121
  setIsInitialized(true);
122
+ if (verboseLogging) {
123
+ console.log('[Insert Affiliate] [VERBOSE] No company code provided, SDK initialized in limited mode');
124
+ }
109
125
  }
110
126
  };
111
127
 
@@ -114,15 +130,28 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
114
130
  useEffect(() => {
115
131
  const fetchAsyncEssentials = async () => {
116
132
  try {
133
+ verboseLog('Loading stored data from AsyncStorage...');
117
134
  const uId = await getValueFromAsync(ASYNC_KEYS.USER_ID);
118
135
  const refLink = await getValueFromAsync(ASYNC_KEYS.REFERRER_LINK);
136
+ const companyCodeFromStorage = await getValueFromAsync(ASYNC_KEYS.COMPANY_CODE);
137
+
138
+ verboseLog(`User ID found: ${uId ? 'Yes' : 'No'}`);
139
+ verboseLog(`Referrer link found: ${refLink ? 'Yes' : 'No'}`);
140
+ verboseLog(`Company code found: ${companyCodeFromStorage ? 'Yes' : 'No'}`);
119
141
 
120
142
  if (uId && refLink) {
121
143
  setUserId(uId);
122
144
  setReferrerLink(refLink);
145
+ verboseLog('User ID and referrer link restored from storage');
146
+ }
147
+
148
+ if (companyCodeFromStorage) {
149
+ setCompanyCode(companyCodeFromStorage);
150
+ verboseLog('Company code restored from storage');
123
151
  }
124
152
  } catch (error) {
125
153
  errorLog(`ERROR ~ fetchAsyncEssentials: ${error}`);
154
+ verboseLog(`Error loading from AsyncStorage: ${error}`);
126
155
  }
127
156
  };
128
157
 
@@ -130,12 +159,17 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
130
159
  }, []);
131
160
 
132
161
  async function generateThenSetUserID() {
162
+ verboseLog('Getting or generating user ID...');
133
163
  let userId = await getValueFromAsync(ASYNC_KEYS.USER_ID);
164
+
134
165
  if (!userId) {
166
+ verboseLog('No existing user ID found, generating new one...');
135
167
  userId = generateUserID();
136
168
  setUserId(userId);
137
169
  await saveValueInAsync(ASYNC_KEYS.USER_ID, userId);
170
+ verboseLog(`Generated and saved new user ID: ${userId}`);
138
171
  } else {
172
+ verboseLog(`Found existing user ID: ${userId}`);
139
173
  setUserId(userId);
140
174
  }
141
175
 
@@ -173,6 +207,33 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
173
207
  await AsyncStorage.clear();
174
208
  };
175
209
 
210
+ // Helper function to get company code from state or storage
211
+ const getActiveCompanyCode = async (): Promise<string | null> => {
212
+ verboseLog('Getting active company code...');
213
+ let activeCompanyCode = companyCode;
214
+ verboseLog(`Company code in React state: ${activeCompanyCode || 'empty'}`);
215
+
216
+ if (!activeCompanyCode || (activeCompanyCode.trim() === '' && activeCompanyCode !== null)) {
217
+ verboseLog('Company code not in state, checking AsyncStorage...');
218
+ activeCompanyCode = await getValueFromAsync(ASYNC_KEYS.COMPANY_CODE);
219
+ verboseLog(`Company code in AsyncStorage: ${activeCompanyCode || 'empty'}`);
220
+
221
+ if (activeCompanyCode) {
222
+ // Update state for future use
223
+ setCompanyCode(activeCompanyCode);
224
+ verboseLog('Updated React state with company code from storage');
225
+ }
226
+ }
227
+ return activeCompanyCode;
228
+ };
229
+
230
+ // Helper function for verbose logging
231
+ const verboseLog = (message: string) => {
232
+ if (verboseLogging) {
233
+ console.log(`[Insert Affiliate] [VERBOSE] ${message}`);
234
+ }
235
+ };
236
+
176
237
  // Helper function to log errors
177
238
  const errorLog = (message: string, type?: 'error' | 'warn' | 'log') => {
178
239
  switch (type) {
@@ -192,7 +253,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
192
253
  const isShortCode = (referringLink: string): boolean => {
193
254
  // Short codes are less than 10 characters
194
255
  const isValidCharacters = /^[a-zA-Z0-9]+$/.test(referringLink);
195
- return isValidCharacters && referringLink.length < 10;
256
+ return isValidCharacters && referringLink.length < 25 && referringLink.length > 3;
196
257
  };
197
258
 
198
259
  async function setShortCode(shortCode: string): Promise<void> {
@@ -243,11 +304,37 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
243
304
  };
244
305
 
245
306
  // MARK: Return Insert Affiliate Identifier
307
+ // Instead of just reading React state
246
308
  const returnInsertAffiliateIdentifier = async (): Promise<string | null> => {
247
309
  try {
248
- return `${referrerLink}-${userId}`;
310
+ verboseLog('Getting insert affiliate identifier...');
311
+ verboseLog(`React state - referrerLink: ${referrerLink || 'empty'}, userId: ${userId || 'empty'}`);
312
+
313
+ // Try React state first
314
+ if (referrerLink && userId) {
315
+ const identifier = `${referrerLink}-${userId}`;
316
+ verboseLog(`Found identifier in React state: ${identifier}`);
317
+ return identifier;
318
+ }
319
+
320
+ verboseLog('React state empty, checking AsyncStorage...');
321
+
322
+ // Fallback to async storage if React state is empty
323
+ const storedLink = await getValueFromAsync(ASYNC_KEYS.REFERRER_LINK);
324
+ const storedUserId = await getValueFromAsync(ASYNC_KEYS.USER_ID);
325
+
326
+ verboseLog(`AsyncStorage - storedLink: ${storedLink || 'empty'}, storedUserId: ${storedUserId || 'empty'}`);
327
+
328
+ if (storedLink && storedUserId) {
329
+ const identifier = `${storedLink}-${storedUserId}`;
330
+ verboseLog(`Found identifier in AsyncStorage: ${identifier}`);
331
+ return identifier;
332
+ }
333
+
334
+ verboseLog('No affiliate identifier found in state or storage');
335
+ return null;
249
336
  } catch (error) {
250
- errorLog(`ERROR ~ returnInsertAffiliateIdentifier: ${error}`);
337
+ verboseLog(`Error getting affiliate identifier: ${error}`);
251
338
  return null;
252
339
  }
253
340
  };
@@ -258,85 +345,102 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
258
345
  referringLink: string
259
346
  ): Promise<void | string> {
260
347
  console.log('[Insert Affiliate] Setting affiliate identifier.');
348
+ verboseLog(`Input referringLink: ${referringLink}`);
261
349
 
262
350
  try {
351
+ verboseLog('Generating or retrieving user ID...');
263
352
  const customerID = await generateThenSetUserID();
264
353
  console.log(
265
354
  '[Insert Affiliate] Completed generateThenSetUserID within setInsertAffiliateIdentifier.'
266
355
  );
356
+ verboseLog(`Customer ID: ${customerID}`);
267
357
 
268
358
  if (!referringLink) {
269
359
  console.warn('[Insert Affiliate] Referring link is invalid.');
270
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
360
+ verboseLog('Referring link is empty or invalid, storing as-is');
271
361
  await storeInsertAffiliateIdentifier({ link: referringLink });
272
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
362
+ return `${referringLink}-${customerID}`;
273
363
  }
274
364
 
275
- if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
276
- let companyCodeFromStorage = await getValueFromAsync(
277
- ASYNC_KEYS.COMPANY_CODE
365
+ // Get company code from state or storage
366
+ verboseLog('Getting company code...');
367
+ const activeCompanyCode = await getActiveCompanyCode();
368
+ verboseLog(`Active company code: ${activeCompanyCode || 'Not found'}`);
369
+
370
+ if (!activeCompanyCode) {
371
+ console.error(
372
+ '[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.'
278
373
  );
279
-
280
- if (companyCodeFromStorage !== null) {
281
- setCompanyCode(companyCodeFromStorage);
282
- } else {
283
- console.error(
284
- '[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.'
285
- );
286
- return;
287
- }
374
+ verboseLog('Company code missing, cannot proceed with API call');
375
+ return;
288
376
  }
289
377
 
290
378
  // Check if referring link is already a short code, if so save it and stop here.
379
+ verboseLog('Checking if referring link is already a short code...');
291
380
  if (isShortCode(referringLink)) {
292
381
  console.log(
293
382
  '[Insert Affiliate] Referring link is already a short code.'
294
383
  );
295
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
384
+ verboseLog('Link is already a short code, storing directly');
296
385
  await storeInsertAffiliateIdentifier({ link: referringLink });
297
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
386
+ return `${referringLink}-${customerID}`;
298
387
  }
299
388
 
389
+ verboseLog('Link is not a short code, will convert via API');
390
+
300
391
  // If the code is not already a short code, encode it raedy to send to our endpoint to return the short code. Save it before making the call in case something goes wrong
301
392
  // Encode the referring link
393
+ verboseLog('Encoding referring link for API call...');
302
394
  const encodedAffiliateLink = encodeURIComponent(referringLink);
303
395
  if (!encodedAffiliateLink) {
304
396
  console.error('[Insert Affiliate] Failed to encode affiliate link.');
305
-
306
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
397
+ verboseLog('Failed to encode link, storing original');
307
398
  await storeInsertAffiliateIdentifier({ link: referringLink });
308
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
399
+ return `${referringLink}-${customerID}`;
309
400
  }
310
401
 
311
402
  // Create the request URL
312
- const urlString = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${companyCode}&deepLinkUrl=${encodedAffiliateLink}`;
403
+ const urlString = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${activeCompanyCode}&deepLinkUrl=${encodedAffiliateLink}`;
313
404
  console.log('[Insert Affiliate] urlString .', urlString);
405
+ verboseLog('Making API request to convert deep link to short code...');
406
+
314
407
  const response = await axios.get(urlString, {
315
408
  headers: {
316
409
  'Content-Type': 'application/json',
317
410
  },
318
411
  });
412
+
413
+ verboseLog(`API response status: ${response.status}`);
319
414
 
320
415
  // Call to the backend for the short code and save the resolse in valid
321
416
  if (response.status === 200 && response.data.shortLink) {
322
417
  const shortLink = response.data.shortLink;
323
418
  console.log('[Insert Affiliate] Short link received:', shortLink);
419
+ verboseLog(`Successfully converted to short link: ${shortLink}`);
420
+ verboseLog('Storing short link to AsyncStorage...');
421
+ await storeInsertAffiliateIdentifier({ link: shortLink });
422
+ verboseLog('Short link stored successfully');
324
423
  return `${shortLink}-${customerID}`;
325
424
  } else {
326
425
  console.warn('[Insert Affiliate] Unexpected response format.');
327
- let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
426
+ verboseLog(`Unexpected API response. Status: ${response.status}, Data: ${JSON.stringify(response.data)}`);
427
+ verboseLog('Storing original link as fallback');
328
428
  await storeInsertAffiliateIdentifier({ link: referringLink });
329
- return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
429
+ return `${referringLink}-${customerID}`;
330
430
  }
331
431
  } catch (error) {
332
432
  console.error('[Insert Affiliate] Error:', error);
433
+ verboseLog(`Error in setInsertAffiliateIdentifier: ${error}`);
333
434
  }
334
435
  };
335
436
 
336
437
  async function storeInsertAffiliateIdentifier({ link }: { link: string }) {
337
438
  console.log(`[Insert Affiliate] Storing affiliate identifier: ${link}`);
439
+ verboseLog(`Updating React state with referrer link: ${link}`);
338
440
  setReferrerLink(link);
441
+ verboseLog(`Saving referrer link to AsyncStorage...`);
339
442
  await saveValueInAsync(ASYNC_KEYS.REFERRER_LINK, link);
443
+ verboseLog(`Referrer link saved to AsyncStorage successfully`);
340
444
  }
341
445
 
342
446
  const validatePurchaseWithIapticAPI = async (
@@ -419,26 +523,34 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
419
523
  };
420
524
 
421
525
  const storeExpectedStoreTransaction = async (purchaseToken: string): Promise<void> => {
422
- if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
526
+ verboseLog(`Storing expected store transaction with token: ${purchaseToken}`);
527
+
528
+ const activeCompanyCode = await getActiveCompanyCode();
529
+ if (!activeCompanyCode) {
423
530
  console.error("[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.");
531
+ verboseLog("Cannot store transaction: no company code available");
424
532
  return;
425
533
  }
426
534
 
427
535
  const shortCode = await returnInsertAffiliateIdentifier();
428
536
  if (!shortCode) {
429
537
  console.error("[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.");
538
+ verboseLog("Cannot store transaction: no affiliate identifier available");
430
539
  return;
431
540
  }
432
541
 
542
+ verboseLog(`Company code: ${activeCompanyCode}, Short code: ${shortCode}`);
543
+
433
544
  // Build JSON payload
434
545
  const payload = {
435
546
  UUID: purchaseToken,
436
- companyCode,
547
+ companyCode: activeCompanyCode,
437
548
  shortCode,
438
549
  storedDate: new Date().toISOString(), // ISO8601 format
439
550
  };
440
551
 
441
552
  console.log("[Insert Affiliate] Storing expected transaction: ", payload);
553
+ verboseLog("Making API call to store expected transaction...");
442
554
 
443
555
  try {
444
556
  const response = await fetch("https://api.insertaffiliate.com/v1/api/app-store-webhook/create-expected-transaction", {
@@ -449,40 +561,57 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
449
561
  body: JSON.stringify(payload),
450
562
  });
451
563
 
564
+ verboseLog(`API response status: ${response.status}`);
565
+
452
566
  if (response.ok) {
453
567
  console.info("[Insert Affiliate] Expected transaction stored successfully.");
568
+ verboseLog("Expected transaction stored successfully on server");
454
569
  } else {
455
570
  const errorText = await response.text();
456
571
  console.error(`[Insert Affiliate] Failed to store expected transaction with status code: ${response.status}. Response: ${errorText}`);
572
+ verboseLog(`API error response: ${errorText}`);
457
573
  }
458
574
  } catch (error) {
459
575
  console.error(`[Insert Affiliate] Error storing expected transaction: ${error}`);
576
+ verboseLog(`Network error storing transaction: ${error}`);
460
577
  }
461
578
  };
462
579
 
463
580
  // MARK: Track Event
464
581
  const trackEvent = async (eventName: string): Promise<void> => {
465
582
  try {
466
- if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
583
+ verboseLog(`Tracking event: ${eventName}`);
584
+
585
+ const activeCompanyCode = await getActiveCompanyCode();
586
+ if (!activeCompanyCode) {
467
587
  console.error("[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.");
588
+ verboseLog("Cannot track event: no company code available");
468
589
  return Promise.resolve();
469
590
  }
470
591
 
471
- console.log("track event called with - companyCode: ", companyCode);
592
+ console.log("track event called with - companyCode: ", activeCompanyCode);
472
593
 
473
594
  if (!referrerLink || !userId) {
474
595
  console.warn(
475
596
  '[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.'
476
597
  );
598
+ verboseLog("Cannot track event: no affiliate identifier available");
477
599
  return Promise.resolve();
478
600
  }
479
601
 
602
+ const deepLinkParam = `${referrerLink}-${userId}`;
603
+ verboseLog(`Deep link param: ${deepLinkParam}`);
604
+
480
605
  const payload = {
481
606
  eventName,
482
- deepLinkParam: `${referrerLink}-${userId}`,
483
- companyId: companyCode,
607
+ deepLinkParam: deepLinkParam,
608
+ companyId: activeCompanyCode,
484
609
  };
485
610
 
611
+ verboseLog(`Track event payload: ${JSON.stringify(payload)}`);
612
+
613
+ verboseLog("Making API call to track event...");
614
+
486
615
  const response = await axios.post(
487
616
  'https://api.insertaffiliate.com/v1/trackEvent',
488
617
  payload,
@@ -491,15 +620,20 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
491
620
  }
492
621
  );
493
622
 
623
+ verboseLog(`Track event API response status: ${response.status}`);
624
+
494
625
  if (response.status === 200) {
495
626
  console.log('[Insert Affiliate] Event tracked successfully');
627
+ verboseLog("Event tracked successfully on server");
496
628
  } else {
497
629
  console.error(
498
630
  `[Insert Affiliate] Failed to track event with status code: ${response.status}`
499
631
  );
632
+ verboseLog(`Track event API error: status ${response.status}, response: ${JSON.stringify(response.data)}`);
500
633
  }
501
634
  } catch (error) {
502
635
  console.error('[Insert Affiliate] Error tracking event:', error);
636
+ verboseLog(`Network error tracking event: ${error}`);
503
637
  return Promise.reject(error);
504
638
  }
505
639
  };