insert-affiliate-react-native-sdk 1.3.5 → 1.4.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.
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React from 'react';
2
2
  type T_DEEPLINK_IAP_PROVIDER = {
3
3
  children: React.ReactNode;
4
4
  };
@@ -12,7 +12,7 @@ type T_DEEPLINK_IAP_CONTEXT = {
12
12
  validatePurchaseWithIapticAPI: (jsonIapPurchase: CustomPurchase, iapticAppId: string, iapticAppName: string, iapticPublicKey: string) => Promise<boolean>;
13
13
  trackEvent: (eventName: string) => Promise<void>;
14
14
  setShortCode: (shortCode: string) => Promise<void>;
15
- setInsertAffiliateIdentifier: (referringLink: string) => Promise<void>;
15
+ setInsertAffiliateIdentifier: (referringLink: string) => Promise<void | string>;
16
16
  initialize: (code: string | null) => Promise<void>;
17
17
  isInitialized: boolean;
18
18
  };
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
36
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
37
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -41,42 +51,42 @@ const react_native_1 = require("react-native");
41
51
  const axios_1 = __importDefault(require("axios"));
42
52
  const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
43
53
  const ASYNC_KEYS = {
44
- REFERRER_LINK: "@app_referrer_link",
45
- USER_PURCHASE: "@app_user_purchase",
46
- USER_ID: "@app_user_id",
47
- COMPANY_CODE: "@app_company_code",
54
+ REFERRER_LINK: '@app_referrer_link',
55
+ USER_PURCHASE: '@app_user_purchase',
56
+ USER_ID: '@app_user_id',
57
+ COMPANY_CODE: '@app_company_code',
48
58
  };
49
59
  // STARTING CONTEXT IMPLEMENTATION
50
60
  exports.DeepLinkIapContext = (0, react_1.createContext)({
51
- referrerLink: "",
52
- userId: "",
53
- returnInsertAffiliateIdentifier: () => __awaiter(void 0, void 0, void 0, function* () { return ""; }),
61
+ referrerLink: '',
62
+ userId: '',
63
+ returnInsertAffiliateIdentifier: () => __awaiter(void 0, void 0, void 0, function* () { return ''; }),
54
64
  validatePurchaseWithIapticAPI: (jsonIapPurchase, iapticAppId, iapticAppName, iapticPublicKey) => __awaiter(void 0, void 0, void 0, function* () { return false; }),
55
65
  trackEvent: (eventName) => __awaiter(void 0, void 0, void 0, function* () { }),
56
66
  setShortCode: (shortCode) => __awaiter(void 0, void 0, void 0, function* () { }),
57
67
  setInsertAffiliateIdentifier: (referringLink) => __awaiter(void 0, void 0, void 0, function* () { }),
58
68
  initialize: (code) => __awaiter(void 0, void 0, void 0, function* () { }),
59
- isInitialized: false
69
+ isInitialized: false,
60
70
  });
61
71
  const DeepLinkIapProvider = ({ children, }) => {
62
- const [referrerLink, setReferrerLink] = (0, react_1.useState)("");
63
- const [userId, setUserId] = (0, react_1.useState)("");
72
+ const [referrerLink, setReferrerLink] = (0, react_1.useState)('');
73
+ const [userId, setUserId] = (0, react_1.useState)('');
64
74
  const [companyCode, setCompanyCode] = (0, react_1.useState)(null);
65
75
  const [isInitialized, setIsInitialized] = (0, react_1.useState)(false);
66
76
  // MARK: Initialize the SDK
67
77
  const initialize = (companyCode) => __awaiter(void 0, void 0, void 0, function* () {
68
78
  if (isInitialized) {
69
- console.error("[Insert Affiliate] SDK is already initialized.");
79
+ console.error('[Insert Affiliate] SDK is already initialized.');
70
80
  return;
71
81
  }
72
- if (companyCode && companyCode.trim() !== "") {
82
+ if (companyCode && companyCode.trim() !== '') {
73
83
  setCompanyCode(companyCode);
74
84
  yield saveValueInAsync(ASYNC_KEYS.COMPANY_CODE, companyCode);
75
85
  setIsInitialized(true);
76
86
  console.log(`[Insert Affiliate] SDK initialized with company code: ${companyCode}`);
77
87
  }
78
88
  else {
79
- console.warn("[Insert Affiliate] SDK initialized without a company code.");
89
+ console.warn('[Insert Affiliate] SDK initialized without a company code.');
80
90
  setIsInitialized(true);
81
91
  }
82
92
  });
@@ -103,14 +113,18 @@ const DeepLinkIapProvider = ({ children, }) => {
103
113
  let userId = yield getValueFromAsync(ASYNC_KEYS.USER_ID);
104
114
  if (!userId) {
105
115
  userId = generateUserID();
116
+ setUserId(userId);
106
117
  yield saveValueInAsync(ASYNC_KEYS.USER_ID, userId);
118
+ }
119
+ else {
107
120
  setUserId(userId);
108
121
  }
122
+ return userId;
109
123
  });
110
124
  }
111
125
  const generateUserID = () => {
112
- const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
113
- let uniqueId = "";
126
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
127
+ let uniqueId = '';
114
128
  for (let i = 0; i < 6; i++) {
115
129
  const randomIndex = Math.floor(Math.random() * characters.length);
116
130
  uniqueId += characters[randomIndex];
@@ -120,7 +134,7 @@ const DeepLinkIapProvider = ({ children, }) => {
120
134
  const reset = () => {
121
135
  setCompanyCode(null);
122
136
  setIsInitialized(false);
123
- console.log("[Insert Affiliate] SDK has been reset.");
137
+ console.log('[Insert Affiliate] SDK has been reset.');
124
138
  };
125
139
  // Helper funciton Storage / Retrieval
126
140
  const saveValueInAsync = (key, value) => __awaiter(void 0, void 0, void 0, function* () {
@@ -136,10 +150,10 @@ const DeepLinkIapProvider = ({ children, }) => {
136
150
  // Helper function to log errors
137
151
  const errorLog = (message, type) => {
138
152
  switch (type) {
139
- case "error":
153
+ case 'error':
140
154
  console.error(`ENCOUNTER ERROR ~ ${message}`);
141
155
  break;
142
- case "warn":
156
+ case 'warn':
143
157
  console.warn(`ENCOUNTER WARNING ~ ${message}`);
144
158
  break;
145
159
  default:
@@ -155,8 +169,8 @@ const DeepLinkIapProvider = ({ children, }) => {
155
169
  };
156
170
  function setShortCode(shortCode) {
157
171
  return __awaiter(this, void 0, void 0, function* () {
158
- console.log("[Insert Affiliate] Setting short code.");
159
- generateThenSetUserID();
172
+ console.log('[Insert Affiliate] Setting short code.');
173
+ yield generateThenSetUserID();
160
174
  // Validate it is a short code
161
175
  const capitalisedShortCode = shortCode.toUpperCase();
162
176
  isShortCode(capitalisedShortCode);
@@ -177,60 +191,65 @@ const DeepLinkIapProvider = ({ children, }) => {
177
191
  // MARK: Insert Affiliate Identifier
178
192
  function setInsertAffiliateIdentifier(referringLink) {
179
193
  return __awaiter(this, void 0, void 0, function* () {
180
- console.log("[Insert Affiliate] Setting affiliate identifier.");
194
+ console.log('[Insert Affiliate] Setting affiliate identifier.');
181
195
  try {
182
- yield generateThenSetUserID();
183
- console.log("[Insert Affiliate] Completed generateThenSetUserID within setInsertAffiliateIdentifier.");
196
+ const customerID = yield generateThenSetUserID();
197
+ console.log('[Insert Affiliate] Completed generateThenSetUserID within setInsertAffiliateIdentifier.');
184
198
  if (!referringLink) {
185
- console.warn("[Insert Affiliate] Referring link is invalid.");
199
+ console.warn('[Insert Affiliate] Referring link is invalid.');
200
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
186
201
  yield storeInsertAffiliateIdentifier({ link: referringLink });
187
- return;
202
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
188
203
  }
189
- if (!companyCode || companyCode.trim() === "" && companyCode !== null) {
204
+ if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
190
205
  let companyCodeFromStorage = yield getValueFromAsync(ASYNC_KEYS.COMPANY_CODE);
191
206
  if (companyCodeFromStorage !== null) {
192
207
  setCompanyCode(companyCodeFromStorage);
193
208
  }
194
209
  else {
195
- console.error("[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.");
210
+ console.error('[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.');
196
211
  return;
197
212
  }
198
213
  }
199
214
  // Check if referring link is already a short code, if so save it and stop here.
200
215
  if (isShortCode(referringLink)) {
201
- console.log("[Insert Affiliate] Referring link is already a short code.");
216
+ console.log('[Insert Affiliate] Referring link is already a short code.');
217
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
202
218
  yield storeInsertAffiliateIdentifier({ link: referringLink });
203
- return;
219
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
204
220
  }
205
221
  // 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
206
222
  // Encode the referring link
207
223
  const encodedAffiliateLink = encodeURIComponent(referringLink);
208
224
  if (!encodedAffiliateLink) {
209
- console.error("[Insert Affiliate] Failed to encode affiliate link.");
225
+ console.error('[Insert Affiliate] Failed to encode affiliate link.');
226
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
210
227
  yield storeInsertAffiliateIdentifier({ link: referringLink });
211
- return;
228
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
212
229
  }
213
230
  // Create the request URL
214
231
  const urlString = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${companyCode}&deepLinkUrl=${encodedAffiliateLink}`;
215
- console.log("[Insert Affiliate] urlString .", urlString);
232
+ console.log('[Insert Affiliate] urlString .', urlString);
216
233
  const response = yield axios_1.default.get(urlString, {
217
234
  headers: {
218
- "Content-Type": "application/json",
235
+ 'Content-Type': 'application/json',
219
236
  },
220
237
  });
221
238
  // Call to the backend for the short code and save the resolse in valid
222
239
  if (response.status === 200 && response.data.shortLink) {
223
240
  const shortLink = response.data.shortLink;
224
- console.log("[Insert Affiliate] Short link received:", shortLink);
225
- yield storeInsertAffiliateIdentifier({ link: shortLink });
241
+ console.log('[Insert Affiliate] Short link received:', shortLink);
242
+ return `${shortLink}-${customerID}`;
226
243
  }
227
244
  else {
228
- console.warn("[Insert Affiliate] Unexpected response format.");
245
+ console.warn('[Insert Affiliate] Unexpected response format.');
246
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
229
247
  yield storeInsertAffiliateIdentifier({ link: referringLink });
248
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
230
249
  }
231
250
  }
232
251
  catch (error) {
233
- console.error("[Insert Affiliate] Error:", error);
252
+ console.error('[Insert Affiliate] Error:', error);
234
253
  }
235
254
  });
236
255
  }
@@ -238,29 +257,29 @@ const DeepLinkIapProvider = ({ children, }) => {
238
257
  function storeInsertAffiliateIdentifier(_a) {
239
258
  return __awaiter(this, arguments, void 0, function* ({ link }) {
240
259
  console.log(`[Insert Affiliate] Storing affiliate identifier: ${link}`);
241
- yield saveValueInAsync(ASYNC_KEYS.REFERRER_LINK, link);
242
260
  setReferrerLink(link);
261
+ yield saveValueInAsync(ASYNC_KEYS.REFERRER_LINK, link);
243
262
  });
244
263
  }
245
264
  const validatePurchaseWithIapticAPI = (jsonIapPurchase, iapticAppId, iapticAppName, iapticPublicKey) => __awaiter(void 0, void 0, void 0, function* () {
246
265
  try {
247
266
  const baseRequestBody = {
248
267
  id: iapticAppId,
249
- type: "application",
268
+ type: 'application',
250
269
  };
251
270
  let transaction;
252
- if (react_native_1.Platform.OS === "ios") {
271
+ if (react_native_1.Platform.OS === 'ios') {
253
272
  transaction = {
254
273
  id: iapticAppId,
255
- type: "ios-appstore",
274
+ type: 'ios-appstore',
256
275
  appStoreReceipt: jsonIapPurchase.transactionReceipt,
257
276
  };
258
277
  }
259
278
  else {
260
- const receiptJson = JSON.parse(atob(jsonIapPurchase.transactionReceipt || ""));
279
+ const receiptJson = JSON.parse(atob(jsonIapPurchase.transactionReceipt || ''));
261
280
  transaction = {
262
281
  id: receiptJson.orderId, // Extracted orderId
263
- type: "android-playstore",
282
+ type: 'android-playstore',
264
283
  purchaseToken: receiptJson.purchaseToken, // Extracted purchase token
265
284
  receipt: jsonIapPurchase.transactionReceipt, // Full receipt (Base64)
266
285
  signature: receiptJson.signature, // Receipt signature
@@ -276,19 +295,19 @@ const DeepLinkIapProvider = ({ children, }) => {
276
295
  // Send validation request to server
277
296
  const response = yield (0, axios_1.default)({
278
297
  url: `https://validator.iaptic.com/v1/validate`,
279
- method: "POST",
298
+ method: 'POST',
280
299
  headers: {
281
300
  Authorization: `Basic ${btoa(`${iapticAppName}:${iapticPublicKey}`)}`,
282
- "Content-Type": "application/json",
301
+ 'Content-Type': 'application/json',
283
302
  },
284
303
  data: requestBody,
285
304
  });
286
305
  if (response.status === 200) {
287
- console.log("Validation successful:", response.data);
306
+ console.log('Validation successful:', response.data);
288
307
  return true;
289
308
  }
290
309
  else {
291
- console.error("Validation failed:", response.data);
310
+ console.error('Validation failed:', response.data);
292
311
  return false;
293
312
  }
294
313
  }
@@ -302,29 +321,29 @@ const DeepLinkIapProvider = ({ children, }) => {
302
321
  return false;
303
322
  }
304
323
  });
305
- // MARK: Track Event
324
+ // MARK: Track Event
306
325
  const trackEvent = (eventName) => __awaiter(void 0, void 0, void 0, function* () {
307
326
  try {
308
327
  if (!referrerLink || !userId) {
309
- console.warn("[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.");
328
+ console.warn('[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.');
310
329
  return Promise.resolve();
311
330
  }
312
331
  const payload = {
313
332
  eventName,
314
333
  deepLinkParam: `${referrerLink}/${userId}`,
315
334
  };
316
- const response = yield axios_1.default.post("https://api.insertaffiliate.com/v1/trackEvent", payload, {
317
- headers: { "Content-Type": "application/json" },
335
+ const response = yield axios_1.default.post('https://api.insertaffiliate.com/v1/trackEvent', payload, {
336
+ headers: { 'Content-Type': 'application/json' },
318
337
  });
319
338
  if (response.status === 200) {
320
- console.log("[Insert Affiliate] Event tracked successfully");
339
+ console.log('[Insert Affiliate] Event tracked successfully');
321
340
  }
322
341
  else {
323
342
  console.error(`[Insert Affiliate] Failed to track event with status code: ${response.status}`);
324
343
  }
325
344
  }
326
345
  catch (error) {
327
- console.error("[Insert Affiliate] Error tracking event:", error);
346
+ console.error('[Insert Affiliate] Error tracking event:', error);
328
347
  return Promise.reject(error);
329
348
  }
330
349
  });
@@ -337,7 +356,7 @@ const DeepLinkIapProvider = ({ children, }) => {
337
356
  trackEvent,
338
357
  setInsertAffiliateIdentifier,
339
358
  initialize,
340
- isInitialized
359
+ isInitialized,
341
360
  } }, children));
342
361
  };
343
362
  exports.default = DeepLinkIapProvider;
@@ -7,7 +7,7 @@ declare const useDeepLinkIapProvider: () => {
7
7
  returnInsertAffiliateIdentifier: () => Promise<string | null>;
8
8
  trackEvent: (eventName: string) => Promise<void>;
9
9
  setShortCode: (shortCode: string) => Promise<void>;
10
- setInsertAffiliateIdentifier: (referringLink: string) => Promise<void>;
10
+ setInsertAffiliateIdentifier: (referringLink: string) => Promise<void | string>;
11
11
  initialize: (code: string | null) => Promise<void>;
12
12
  isInitialized: boolean;
13
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "insert-affiliate-react-native-sdk",
3
- "version": "1.3.5",
3
+ "version": "1.4.0",
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
@@ -226,7 +226,7 @@ After setting up your Branch integration, add the following code to your ```App.
226
226
  import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
227
227
 
228
228
  //...
229
- const {setInsertAffiliateIdentifier, returnInsertAffiliateIdentifier} = useDeepLinkIapProvider();
229
+ const {setInsertAffiliateIdentifier} = useDeepLinkIapProvider();
230
230
 
231
231
  useEffect(() => {
232
232
  if (!isInitialized) return;
@@ -244,9 +244,8 @@ import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
244
244
  const referringLink = params['~referring_link'];
245
245
  if (referringLink) {
246
246
  try {
247
- await setInsertAffiliateIdentifier(referringLink);
247
+ let insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
248
248
 
249
- let insertAffiliateIdentifier = await returnInsertAffiliateIdentifier();
250
249
  if (insertAffiliateIdentifier) {
251
250
  const { customerInfo, created } = await Purchases.logIn(insertAffiliateIdentifier);
252
251
  }
@@ -1,7 +1,7 @@
1
- import React, { createContext, useEffect, useState } from "react";
2
- import { Platform } from "react-native";
3
- import axios from "axios";
4
- import AsyncStorage from "@react-native-async-storage/async-storage";
1
+ import React, { createContext, useEffect, useState } from 'react';
2
+ import { Platform } from 'react-native';
3
+ import axios from 'axios';
4
+ import AsyncStorage from '@react-native-async-storage/async-storage';
5
5
 
6
6
  // TYPES USED IN THIS PROVIDER
7
7
  type T_DEEPLINK_IAP_PROVIDER = {
@@ -24,7 +24,9 @@ type T_DEEPLINK_IAP_CONTEXT = {
24
24
  ) => Promise<boolean>;
25
25
  trackEvent: (eventName: string) => Promise<void>;
26
26
  setShortCode: (shortCode: string) => Promise<void>;
27
- setInsertAffiliateIdentifier: (referringLink: string) => Promise<void>;
27
+ setInsertAffiliateIdentifier: (
28
+ referringLink: string
29
+ ) => Promise<void | string>;
28
30
  initialize: (code: string | null) => Promise<void>;
29
31
  isInitialized: boolean;
30
32
  };
@@ -46,17 +48,17 @@ type RequestBody = {
46
48
  };
47
49
 
48
50
  const ASYNC_KEYS = {
49
- REFERRER_LINK: "@app_referrer_link",
50
- USER_PURCHASE: "@app_user_purchase",
51
- USER_ID: "@app_user_id",
52
- COMPANY_CODE: "@app_company_code",
51
+ REFERRER_LINK: '@app_referrer_link',
52
+ USER_PURCHASE: '@app_user_purchase',
53
+ USER_ID: '@app_user_id',
54
+ COMPANY_CODE: '@app_company_code',
53
55
  };
54
56
 
55
57
  // STARTING CONTEXT IMPLEMENTATION
56
58
  export const DeepLinkIapContext = createContext<T_DEEPLINK_IAP_CONTEXT>({
57
- referrerLink: "",
58
- userId: "",
59
- returnInsertAffiliateIdentifier: async () => "",
59
+ referrerLink: '',
60
+ userId: '',
61
+ returnInsertAffiliateIdentifier: async () => '',
60
62
  validatePurchaseWithIapticAPI: async (
61
63
  jsonIapPurchase: CustomPurchase,
62
64
  iapticAppId: string,
@@ -67,31 +69,35 @@ export const DeepLinkIapContext = createContext<T_DEEPLINK_IAP_CONTEXT>({
67
69
  setShortCode: async (shortCode: string) => {},
68
70
  setInsertAffiliateIdentifier: async (referringLink: string) => {},
69
71
  initialize: async (code: string | null) => {},
70
- isInitialized: false
72
+ isInitialized: false,
71
73
  });
72
74
 
73
75
  const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
74
76
  children,
75
77
  }) => {
76
- const [referrerLink, setReferrerLink] = useState<string>("");
77
- const [userId, setUserId] = useState<string>("");
78
+ const [referrerLink, setReferrerLink] = useState<string>('');
79
+ const [userId, setUserId] = useState<string>('');
78
80
  const [companyCode, setCompanyCode] = useState<string | null>(null);
79
81
  const [isInitialized, setIsInitialized] = useState<boolean>(false);
80
82
 
81
83
  // MARK: Initialize the SDK
82
84
  const initialize = async (companyCode: string | null): Promise<void> => {
83
85
  if (isInitialized) {
84
- console.error("[Insert Affiliate] SDK is already initialized.");
86
+ console.error('[Insert Affiliate] SDK is already initialized.');
85
87
  return;
86
88
  }
87
-
88
- if (companyCode && companyCode.trim() !== "") {
89
+
90
+ if (companyCode && companyCode.trim() !== '') {
89
91
  setCompanyCode(companyCode);
90
92
  await saveValueInAsync(ASYNC_KEYS.COMPANY_CODE, companyCode);
91
93
  setIsInitialized(true);
92
- console.log(`[Insert Affiliate] SDK initialized with company code: ${companyCode}`);
94
+ console.log(
95
+ `[Insert Affiliate] SDK initialized with company code: ${companyCode}`
96
+ );
93
97
  } else {
94
- console.warn("[Insert Affiliate] SDK initialized without a company code.");
98
+ console.warn(
99
+ '[Insert Affiliate] SDK initialized without a company code.'
100
+ );
95
101
  setIsInitialized(true);
96
102
  }
97
103
  };
@@ -120,15 +126,19 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
120
126
  let userId = await getValueFromAsync(ASYNC_KEYS.USER_ID);
121
127
  if (!userId) {
122
128
  userId = generateUserID();
129
+ setUserId(userId);
123
130
  await saveValueInAsync(ASYNC_KEYS.USER_ID, userId);
131
+ } else {
124
132
  setUserId(userId);
125
133
  }
134
+
135
+ return userId;
126
136
  }
127
137
 
128
138
  const generateUserID = () => {
129
139
  const characters =
130
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
131
- let uniqueId = "";
140
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
141
+ let uniqueId = '';
132
142
  for (let i = 0; i < 6; i++) {
133
143
  const randomIndex = Math.floor(Math.random() * characters.length);
134
144
  uniqueId += characters[randomIndex];
@@ -139,7 +149,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
139
149
  const reset = (): void => {
140
150
  setCompanyCode(null);
141
151
  setIsInitialized(false);
142
- console.log("[Insert Affiliate] SDK has been reset.");
152
+ console.log('[Insert Affiliate] SDK has been reset.');
143
153
  };
144
154
 
145
155
  // Helper funciton Storage / Retrieval
@@ -157,12 +167,12 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
157
167
  };
158
168
 
159
169
  // Helper function to log errors
160
- const errorLog = (message: string, type?: "error" | "warn" | "log") => {
170
+ const errorLog = (message: string, type?: 'error' | 'warn' | 'log') => {
161
171
  switch (type) {
162
- case "error":
172
+ case 'error':
163
173
  console.error(`ENCOUNTER ERROR ~ ${message}`);
164
174
  break;
165
- case "warn":
175
+ case 'warn':
166
176
  console.warn(`ENCOUNTER WARNING ~ ${message}`);
167
177
  break;
168
178
  default:
@@ -171,7 +181,6 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
171
181
  }
172
182
  };
173
183
 
174
-
175
184
  // MARK: Short Codes
176
185
  const isShortCode = (referringLink: string): boolean => {
177
186
  // Short codes are less than 10 characters
@@ -180,8 +189,8 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
180
189
  };
181
190
 
182
191
  async function setShortCode(shortCode: string): Promise<void> {
183
- console.log("[Insert Affiliate] Setting short code.");
184
- generateThenSetUserID();
192
+ console.log('[Insert Affiliate] Setting short code.');
193
+ await generateThenSetUserID();
185
194
 
186
195
  // Validate it is a short code
187
196
  const capitalisedShortCode = shortCode.toUpperCase();
@@ -194,85 +203,99 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
194
203
  // MARK: Return Insert Affiliate Identifier
195
204
  const returnInsertAffiliateIdentifier = async (): Promise<string | null> => {
196
205
  try {
206
+
197
207
  return `${referrerLink}-${userId}`;
198
208
  } catch (error) {
199
209
  errorLog(`ERROR ~ returnInsertAffiliateIdentifier: ${error}`);
200
210
  return null;
201
211
  }
202
- }
203
-
212
+ };
204
213
 
205
214
  // MARK: Insert Affiliate Identifier
206
215
 
207
- async function setInsertAffiliateIdentifier(referringLink: string): Promise<void> {
208
- console.log("[Insert Affiliate] Setting affiliate identifier.");
216
+ async function setInsertAffiliateIdentifier(
217
+ referringLink: string
218
+ ): Promise<void | string> {
219
+ console.log('[Insert Affiliate] Setting affiliate identifier.');
209
220
 
210
221
  try {
211
- await generateThenSetUserID();
212
- console.log("[Insert Affiliate] Completed generateThenSetUserID within setInsertAffiliateIdentifier.");
222
+ const customerID = await generateThenSetUserID();
223
+ console.log(
224
+ '[Insert Affiliate] Completed generateThenSetUserID within setInsertAffiliateIdentifier.'
225
+ );
213
226
 
214
227
  if (!referringLink) {
215
- console.warn("[Insert Affiliate] Referring link is invalid.");
228
+ console.warn('[Insert Affiliate] Referring link is invalid.');
229
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
216
230
  await storeInsertAffiliateIdentifier({ link: referringLink });
217
- return;
231
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
218
232
  }
219
-
220
- if (!companyCode || companyCode.trim() === "" && companyCode !== null) {
221
- let companyCodeFromStorage = await getValueFromAsync(ASYNC_KEYS.COMPANY_CODE);
233
+
234
+ if (!companyCode || (companyCode.trim() === '' && companyCode !== null)) {
235
+ let companyCodeFromStorage = await getValueFromAsync(
236
+ ASYNC_KEYS.COMPANY_CODE
237
+ );
222
238
 
223
239
  if (companyCodeFromStorage !== null) {
224
240
  setCompanyCode(companyCodeFromStorage);
225
241
  } else {
226
242
  console.error(
227
- "[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code."
243
+ '[Insert Affiliate] Company code is not set. Please initialize the SDK with a valid company code.'
228
244
  );
229
245
  return;
230
246
  }
231
247
  }
232
-
248
+
233
249
  // Check if referring link is already a short code, if so save it and stop here.
234
250
  if (isShortCode(referringLink)) {
235
- console.log("[Insert Affiliate] Referring link is already a short code.");
251
+ console.log(
252
+ '[Insert Affiliate] Referring link is already a short code.'
253
+ );
254
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
236
255
  await storeInsertAffiliateIdentifier({ link: referringLink });
237
- return;
256
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
238
257
  }
239
-
258
+
240
259
  // 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
241
260
  // Encode the referring link
242
261
  const encodedAffiliateLink = encodeURIComponent(referringLink);
243
262
  if (!encodedAffiliateLink) {
244
- console.error("[Insert Affiliate] Failed to encode affiliate link.");
263
+ console.error('[Insert Affiliate] Failed to encode affiliate link.');
264
+
265
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
245
266
  await storeInsertAffiliateIdentifier({ link: referringLink });
246
- return;
267
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
247
268
  }
248
-
269
+
249
270
  // Create the request URL
250
271
  const urlString = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${companyCode}&deepLinkUrl=${encodedAffiliateLink}`;
251
- console.log("[Insert Affiliate] urlString .", urlString);
272
+ console.log('[Insert Affiliate] urlString .', urlString);
252
273
  const response = await axios.get(urlString, {
253
274
  headers: {
254
- "Content-Type": "application/json",
275
+ 'Content-Type': 'application/json',
255
276
  },
256
277
  });
257
-
278
+
258
279
  // Call to the backend for the short code and save the resolse in valid
259
280
  if (response.status === 200 && response.data.shortLink) {
260
281
  const shortLink = response.data.shortLink;
261
- console.log("[Insert Affiliate] Short link received:", shortLink);
262
- await storeInsertAffiliateIdentifier({ link: shortLink });
282
+ console.log('[Insert Affiliate] Short link received:', shortLink);
283
+ return `${shortLink}-${customerID}`;
263
284
  } else {
264
- console.warn("[Insert Affiliate] Unexpected response format.");
285
+ console.warn('[Insert Affiliate] Unexpected response format.');
286
+ let heldReferrerLinkBeforeAsyncStateUpdate = referrerLink;
265
287
  await storeInsertAffiliateIdentifier({ link: referringLink });
288
+ return `${heldReferrerLinkBeforeAsyncStateUpdate}-${customerID}`;
266
289
  }
267
290
  } catch (error) {
268
- console.error("[Insert Affiliate] Error:", error);
291
+ console.error('[Insert Affiliate] Error:', error);
269
292
  }
270
293
  };
271
294
 
272
295
  async function storeInsertAffiliateIdentifier({ link }: { link: string }) {
273
296
  console.log(`[Insert Affiliate] Storing affiliate identifier: ${link}`);
274
- await saveValueInAsync(ASYNC_KEYS.REFERRER_LINK, link);
275
297
  setReferrerLink(link);
298
+ await saveValueInAsync(ASYNC_KEYS.REFERRER_LINK, link);
276
299
  }
277
300
 
278
301
  const validatePurchaseWithIapticAPI = async (
@@ -284,22 +307,24 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
284
307
  try {
285
308
  const baseRequestBody: RequestBody = {
286
309
  id: iapticAppId,
287
- type: "application",
310
+ type: 'application',
288
311
  };
289
-
312
+
290
313
  let transaction;
291
314
 
292
- if (Platform.OS === "ios") {
315
+ if (Platform.OS === 'ios') {
293
316
  transaction = {
294
317
  id: iapticAppId,
295
- type: "ios-appstore",
318
+ type: 'ios-appstore',
296
319
  appStoreReceipt: jsonIapPurchase.transactionReceipt,
297
320
  };
298
321
  } else {
299
- const receiptJson = JSON.parse(atob(jsonIapPurchase.transactionReceipt || ""));
322
+ const receiptJson = JSON.parse(
323
+ atob(jsonIapPurchase.transactionReceipt || '')
324
+ );
300
325
  transaction = {
301
326
  id: receiptJson.orderId, // Extracted orderId
302
- type: "android-playstore",
327
+ type: 'android-playstore',
303
328
  purchaseToken: receiptJson.purchaseToken, // Extracted purchase token
304
329
  receipt: jsonIapPurchase.transactionReceipt, // Full receipt (Base64)
305
330
  signature: receiptJson.signature, // Receipt signature
@@ -318,43 +343,46 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
318
343
  applicationUsername: `${insertAffiliateIdentifier}`,
319
344
  };
320
345
  }
321
-
346
+
322
347
  // Send validation request to server
323
348
  const response = await axios({
324
349
  url: `https://validator.iaptic.com/v1/validate`,
325
- method: "POST",
350
+ method: 'POST',
326
351
  headers: {
327
352
  Authorization: `Basic ${btoa(`${iapticAppName}:${iapticPublicKey}`)}`,
328
- "Content-Type": "application/json",
353
+ 'Content-Type': 'application/json',
329
354
  },
330
355
  data: requestBody,
331
356
  });
332
-
357
+
333
358
  if (response.status === 200) {
334
- console.log("Validation successful:", response.data);
359
+ console.log('Validation successful:', response.data);
335
360
  return true;
336
361
  } else {
337
- console.error("Validation failed:", response.data);
362
+ console.error('Validation failed:', response.data);
338
363
  return false;
339
364
  }
340
365
  } catch (error) {
341
366
  if (error instanceof Error) {
342
367
  console.error(`validatePurchaseWithIapticAPI Error: ${error.message}`);
343
368
  } else {
344
- console.error(`validatePurchaseWithIapticAPI Unknown Error: ${JSON.stringify(error)}`);
369
+ console.error(
370
+ `validatePurchaseWithIapticAPI Unknown Error: ${JSON.stringify(
371
+ error
372
+ )}`
373
+ );
345
374
  }
346
375
 
347
376
  return false;
348
377
  }
349
378
  };
350
-
351
379
 
352
- // MARK: Track Event
380
+ // MARK: Track Event
353
381
  const trackEvent = async (eventName: string): Promise<void> => {
354
382
  try {
355
383
  if (!referrerLink || !userId) {
356
384
  console.warn(
357
- "[Insert Affiliate] No affiliate identifier found. Please set one before tracking events."
385
+ '[Insert Affiliate] No affiliate identifier found. Please set one before tracking events.'
358
386
  );
359
387
  return Promise.resolve();
360
388
  }
@@ -365,22 +393,22 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
365
393
  };
366
394
 
367
395
  const response = await axios.post(
368
- "https://api.insertaffiliate.com/v1/trackEvent",
396
+ 'https://api.insertaffiliate.com/v1/trackEvent',
369
397
  payload,
370
398
  {
371
- headers: { "Content-Type": "application/json" },
399
+ headers: { 'Content-Type': 'application/json' },
372
400
  }
373
401
  );
374
402
 
375
403
  if (response.status === 200) {
376
- console.log("[Insert Affiliate] Event tracked successfully");
404
+ console.log('[Insert Affiliate] Event tracked successfully');
377
405
  } else {
378
406
  console.error(
379
407
  `[Insert Affiliate] Failed to track event with status code: ${response.status}`
380
408
  );
381
409
  }
382
410
  } catch (error) {
383
- console.error("[Insert Affiliate] Error tracking event:", error);
411
+ console.error('[Insert Affiliate] Error tracking event:', error);
384
412
  return Promise.reject(error);
385
413
  }
386
414
  };
@@ -396,7 +424,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
396
424
  trackEvent,
397
425
  setInsertAffiliateIdentifier,
398
426
  initialize,
399
- isInitialized
427
+ isInitialized,
400
428
  }}
401
429
  >
402
430
  {children}