insert-affiliate-js-sdk 1.0.2 → 1.2.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/index.d.ts CHANGED
@@ -1,13 +1,62 @@
1
1
  interface IapticIOSReceipt {
2
2
  transactionReceipt: string;
3
3
  }
4
+ interface AffiliateDetails {
5
+ affiliateName: string;
6
+ affiliateShortCode: string;
7
+ deeplinkUrl: string;
8
+ }
9
+ type InsertAffiliateIdentifierChangeCallback = (identifier: string | null) => void;
4
10
  declare class InsertAffiliate {
5
11
  private static isInitialized;
6
12
  private static companyCode;
7
- static initialize(code: string | null): Promise<void>;
8
- static returnInsertAffiliateIdentifier(): Promise<string | null>;
13
+ private static verboseLogging;
14
+ private static insertAffiliateIdentifierChangeCallback;
15
+ private static affiliateAttributionActiveTime;
16
+ private static offerCode;
17
+ private static verboseLog;
18
+ static initialize(code: string | null, verboseLogging?: boolean, affiliateAttributionActiveTime?: number): Promise<void>;
19
+ private static checkForInsertAffiliateParam;
20
+ static returnInsertAffiliateIdentifier(ignoreTimeout?: boolean): Promise<string | null>;
9
21
  static setInsertAffiliateIdentifier(referringLink: string): Promise<string | null>;
10
- static setShortCode(shortCode: string): Promise<void>;
22
+ /**
23
+ * Validates and sets a short code for affiliate tracking
24
+ * Validates the short code against the API before storing
25
+ * @param shortCode The short code to validate and set
26
+ * @returns true if the code exists and was successfully validated and stored, false otherwise
27
+ */
28
+ static setShortCode(shortCode: string): Promise<boolean>;
29
+ static setInsertAffiliateIdentifierChangeCallback(callback: InsertAffiliateIdentifierChangeCallback | null): void;
30
+ static isAffiliateAttributionValid(): Promise<boolean>;
31
+ static getAffiliateStoredDate(): Promise<string | null>;
32
+ /**
33
+ * Retrieve detailed information about an affiliate by their short code or deep link
34
+ * This method queries the API and does not store or set the affiliate identifier
35
+ * @param affiliateCode The short code or deep link to look up
36
+ * @returns AffiliateDetails if found, null otherwise
37
+ */
38
+ static getAffiliateDetails(affiliateCode: string): Promise<AffiliateDetails | null>;
39
+ static returnCompanyId(): Promise<string | null>;
40
+ /**
41
+ * Get the offer code for the current affiliate
42
+ * @param platformType Optional platform type: 'stripe' (default for web), 'ios', or 'android'
43
+ * @returns The offer code for the specified platform, or null if not found
44
+ */
45
+ static getOfferCode(platformType?: 'ios' | 'android' | 'stripe'): Promise<string | null>;
46
+ /**
47
+ * Get the Stripe coupon/promo code for the current affiliate
48
+ * Convenience method that calls getOfferCode with platformType='stripe'
49
+ * @returns The Stripe coupon/promo code, or null if not found
50
+ */
51
+ static getStripeCouponCode(): Promise<string | null>;
52
+ /**
53
+ * Fetch offer code for a specific platform
54
+ * @param shortCode The affiliate short code
55
+ * @param platformType The platform type: 'ios', 'android', or 'stripe'
56
+ * @returns The offer code for the specified platform, or null if not found
57
+ */
58
+ private static fetchOfferCodeForPlatform;
59
+ private static fetchAndStoreOfferCode;
11
60
  static trackEvent(eventName: string): Promise<void>;
12
61
  static returnUserAccountTokenAndStoreExpectedTransaction(): Promise<string | null>;
13
62
  static storeExpectedStoreTransaction(userAccountToken: string): Promise<void>;
@@ -19,4 +68,4 @@ declare class InsertAffiliate {
19
68
  private static fetchShortLink;
20
69
  }
21
70
 
22
- export { InsertAffiliate };
71
+ export { type AffiliateDetails, InsertAffiliate, type InsertAffiliateIdentifierChangeCallback };
package/dist/index.js CHANGED
@@ -75,78 +75,408 @@ if (!String.prototype.hasOwnProperty("hashCode")) {
75
75
 
76
76
  // src/sdk/InsertAffiliate.ts
77
77
  var InsertAffiliate = class {
78
- static async initialize(code) {
78
+ static verboseLog(message) {
79
+ if (this.verboseLogging) {
80
+ console.log(`[Insert Affiliate] [VERBOSE] ${message}`);
81
+ }
82
+ }
83
+ static async initialize(code, verboseLogging = false, affiliateAttributionActiveTime) {
84
+ this.verboseLogging = verboseLogging;
85
+ if (verboseLogging) {
86
+ this.verboseLog("Starting SDK initialization...");
87
+ this.verboseLog(`Company code provided: ${code ? "Yes" : "No"}`);
88
+ this.verboseLog("Verbose logging enabled");
89
+ }
79
90
  if (this.isInitialized) {
80
- console.warn("[Insert Affiliate] SDK already initialized.");
91
+ this.verboseLog("SDK already initialized, skipping");
81
92
  return;
82
93
  }
83
94
  this.companyCode = code;
84
95
  await saveValue("companyCode", code || "");
96
+ if (affiliateAttributionActiveTime !== void 0) {
97
+ this.affiliateAttributionActiveTime = affiliateAttributionActiveTime;
98
+ await saveValue("affiliateAttributionActiveTime", affiliateAttributionActiveTime.toString());
99
+ this.verboseLog(`Attribution timeout set to: ${affiliateAttributionActiveTime}ms`);
100
+ }
85
101
  this.isInitialized = true;
86
- console.log(`[Insert Affiliate] SDK initialized ${code ? `with company code: ${code}` : "without a company code."}`);
102
+ this.verboseLog(`SDK initialized ${code ? `with company code: ${code}` : "without a company code."}`);
103
+ this.verboseLog("Company code saved to storage");
104
+ this.verboseLog("SDK marked as initialized");
105
+ await this.checkForInsertAffiliateParam();
106
+ }
107
+ static async checkForInsertAffiliateParam() {
108
+ this.verboseLog("Checking for insertAffiliate URL parameter...");
109
+ try {
110
+ if (typeof window === "undefined" || !window.location) {
111
+ this.verboseLog("Not in browser environment, skipping URL parameter check");
112
+ return;
113
+ }
114
+ this.verboseLog(`Current URL: ${window.location.href}`);
115
+ const urlParams = new URLSearchParams(window.location.search);
116
+ const insertAffiliateParam = urlParams.get("insertAffiliate");
117
+ if (insertAffiliateParam) {
118
+ this.verboseLog(`Found insertAffiliate URL parameter: ${insertAffiliateParam}`);
119
+ await this.setShortCode(insertAffiliateParam);
120
+ this.verboseLog("Successfully processed insertAffiliate URL parameter");
121
+ } else {
122
+ this.verboseLog("No insertAffiliate URL parameter found");
123
+ }
124
+ } catch (error) {
125
+ this.verboseLog(`Error checking for insertAffiliate URL parameter: ${error}`);
126
+ }
87
127
  }
88
- static async returnInsertAffiliateIdentifier() {
128
+ static async returnInsertAffiliateIdentifier(ignoreTimeout = false) {
129
+ this.verboseLog("Getting insert affiliate identifier...");
89
130
  const userId = await this.getOrCreateUserID();
90
131
  const referrerLink = await getValue("referrerLink");
91
- if (!referrerLink) return null;
92
- return `${referrerLink}-${userId}`;
132
+ this.verboseLog(`User ID: ${userId || "empty"}, Referrer link: ${referrerLink || "empty"}`);
133
+ if (!referrerLink) {
134
+ this.verboseLog("No referrer link found, returning null");
135
+ return null;
136
+ }
137
+ if (!ignoreTimeout) {
138
+ const isValid = await this.isAffiliateAttributionValid();
139
+ if (!isValid) {
140
+ this.verboseLog("Attribution has expired, returning null");
141
+ return null;
142
+ }
143
+ } else {
144
+ this.verboseLog("Ignoring attribution timeout");
145
+ }
146
+ const identifier = `${referrerLink}-${userId}`;
147
+ this.verboseLog(`Returning affiliate identifier: ${identifier}`);
148
+ return identifier;
93
149
  }
94
150
  static async setInsertAffiliateIdentifier(referringLink) {
151
+ this.verboseLog(`Setting affiliate identifier. Input referringLink: ${referringLink}`);
95
152
  const userId = await this.getOrCreateUserID();
96
- const shortCode = /^[a-zA-Z0-9]{3,25}$/.test(referringLink) ? referringLink : await this.fetchShortLink(referringLink);
97
- if (!shortCode) return null;
153
+ this.verboseLog(`User ID: ${userId}`);
154
+ const isShortCode = /^[a-zA-Z0-9]{3,25}$/.test(referringLink);
155
+ this.verboseLog(`Is short code: ${isShortCode}`);
156
+ const shortCode = isShortCode ? referringLink : await this.fetchShortLink(referringLink);
157
+ if (!shortCode) {
158
+ this.verboseLog("No short code found or generated, returning null");
159
+ return null;
160
+ }
161
+ const existingShortCode = await getValue("referrerLink");
162
+ if (existingShortCode === shortCode) {
163
+ this.verboseLog(`Short code ${shortCode} is already set, not updating attribution date`);
164
+ const identifier2 = `${shortCode}-${userId}`;
165
+ this.verboseLog(`Returning existing identifier: ${identifier2}`);
166
+ return identifier2;
167
+ }
168
+ this.verboseLog(`Saving short code to storage: ${shortCode}`);
98
169
  await saveValue("referrerLink", shortCode);
99
- return `${shortCode}-${userId}`;
170
+ const storedDate = (/* @__PURE__ */ new Date()).toISOString();
171
+ await saveValue("affiliateStoredDate", storedDate);
172
+ this.verboseLog(`Short code saved successfully with stored date: ${storedDate}`);
173
+ const identifier = `${shortCode}-${userId}`;
174
+ this.verboseLog(`Returning identifier: ${identifier}`);
175
+ await this.fetchAndStoreOfferCode(shortCode);
176
+ if (this.insertAffiliateIdentifierChangeCallback) {
177
+ this.verboseLog(`Triggering callback with identifier: ${identifier}`);
178
+ this.insertAffiliateIdentifierChangeCallback(identifier);
179
+ }
180
+ return identifier;
100
181
  }
182
+ /**
183
+ * Validates and sets a short code for affiliate tracking
184
+ * Validates the short code against the API before storing
185
+ * @param shortCode The short code to validate and set
186
+ * @returns true if the code exists and was successfully validated and stored, false otherwise
187
+ */
101
188
  static async setShortCode(shortCode) {
189
+ this.verboseLog(`Setting short code. Input: ${shortCode}`);
102
190
  const valid = /^[a-zA-Z0-9]{3,25}$/.test(shortCode);
191
+ this.verboseLog(`Short code validation: ${valid ? "Valid" : "Invalid"}`);
103
192
  if (!valid) {
104
- console.warn("[Insert Affiliate] Invalid short code.");
105
- return;
193
+ this.verboseLog("Invalid short code format, aborting");
194
+ return false;
195
+ }
196
+ const affiliateDetails = await this.getAffiliateDetails(shortCode);
197
+ if (!affiliateDetails) {
198
+ this.verboseLog(`Short code '${shortCode}' does not exist or validation failed`);
199
+ console.error(`[Insert Affiliate] Error: Short code '${shortCode}' does not exist or validation failed.`);
200
+ return false;
106
201
  }
202
+ this.verboseLog(`Short code validated successfully for affiliate: ${affiliateDetails.affiliateName}`);
203
+ console.log(`[Insert Affiliate] Short code validated successfully for affiliate: ${affiliateDetails.affiliateName}`);
204
+ this.verboseLog("Calling setInsertAffiliateIdentifier with short code");
107
205
  await this.setInsertAffiliateIdentifier(shortCode);
206
+ return true;
207
+ }
208
+ static setInsertAffiliateIdentifierChangeCallback(callback) {
209
+ this.verboseLog(`Setting affiliate identifier change callback: ${callback ? "callback provided" : "callback cleared"}`);
210
+ this.insertAffiliateIdentifierChangeCallback = callback;
211
+ }
212
+ static async isAffiliateAttributionValid() {
213
+ this.verboseLog("Checking if affiliate attribution is valid...");
214
+ const storedDateStr = await getValue("affiliateStoredDate");
215
+ if (!storedDateStr) {
216
+ this.verboseLog("No stored date found, attribution invalid");
217
+ return false;
218
+ }
219
+ let timeoutMs = this.affiliateAttributionActiveTime;
220
+ if (timeoutMs === null) {
221
+ const storedTimeout = await getValue("affiliateAttributionActiveTime");
222
+ timeoutMs = storedTimeout ? parseInt(storedTimeout, 10) : null;
223
+ }
224
+ if (timeoutMs === null) {
225
+ this.verboseLog("No attribution timeout configured, attribution is valid");
226
+ return true;
227
+ }
228
+ const storedDate = new Date(storedDateStr);
229
+ const currentDate = /* @__PURE__ */ new Date();
230
+ const elapsedMs = currentDate.getTime() - storedDate.getTime();
231
+ const isValid = elapsedMs <= timeoutMs;
232
+ this.verboseLog(`Attribution stored: ${storedDateStr}, elapsed: ${elapsedMs}ms, timeout: ${timeoutMs}ms, valid: ${isValid}`);
233
+ return isValid;
234
+ }
235
+ static async getAffiliateStoredDate() {
236
+ this.verboseLog("Getting affiliate stored date...");
237
+ const storedDate = await getValue("affiliateStoredDate");
238
+ this.verboseLog(`Stored date: ${storedDate || "none"}`);
239
+ return storedDate;
240
+ }
241
+ /**
242
+ * Retrieve detailed information about an affiliate by their short code or deep link
243
+ * This method queries the API and does not store or set the affiliate identifier
244
+ * @param affiliateCode The short code or deep link to look up
245
+ * @returns AffiliateDetails if found, null otherwise
246
+ */
247
+ static async getAffiliateDetails(affiliateCode) {
248
+ this.verboseLog(`Getting affiliate details for: ${affiliateCode}`);
249
+ const companyCode = this.companyCode || await getValue("companyCode");
250
+ if (!companyCode) {
251
+ this.verboseLog("Cannot get affiliate details: no company code available");
252
+ return null;
253
+ }
254
+ const cleanCode = affiliateCode.includes("-") ? affiliateCode.split("-")[0] : affiliateCode;
255
+ this.verboseLog(`Clean code: ${cleanCode}`);
256
+ try {
257
+ const url = "https://api.insertaffiliate.com/V1/checkAffiliateExists";
258
+ const payload = {
259
+ companyId: companyCode,
260
+ affiliateCode: cleanCode
261
+ };
262
+ this.verboseLog(`Making API call to: ${url}`);
263
+ this.verboseLog(`Payload: ${JSON.stringify(payload)}`);
264
+ const response = await fetch(url, {
265
+ method: "POST",
266
+ headers: { "Content-Type": "application/json" },
267
+ body: JSON.stringify(payload)
268
+ });
269
+ this.verboseLog(`API response status: ${response.status}`);
270
+ if (!response.ok) {
271
+ this.verboseLog(`Failed to get affiliate details, status: ${response.status}`);
272
+ return null;
273
+ }
274
+ const data = await response.json();
275
+ this.verboseLog(`API response data: ${JSON.stringify(data)}`);
276
+ if (data.exists && data.affiliate) {
277
+ const details = {
278
+ affiliateName: data.affiliate.affiliateName,
279
+ affiliateShortCode: data.affiliate.affiliateShortCode,
280
+ deeplinkUrl: data.affiliate.deeplinkurl
281
+ };
282
+ this.verboseLog(`Successfully retrieved affiliate details for: ${details.affiliateName}`);
283
+ return details;
284
+ }
285
+ this.verboseLog("Affiliate does not exist");
286
+ return null;
287
+ } catch (error) {
288
+ this.verboseLog(`Error fetching affiliate details: ${error}`);
289
+ return null;
290
+ }
291
+ }
292
+ static async returnCompanyId() {
293
+ this.verboseLog("Getting company ID...");
294
+ const companyCode = this.companyCode || await getValue("companyCode");
295
+ this.verboseLog(`Company ID: ${companyCode || "none"}`);
296
+ return companyCode;
297
+ }
298
+ /**
299
+ * Get the offer code for the current affiliate
300
+ * @param platformType Optional platform type: 'stripe' (default for web), 'ios', or 'android'
301
+ * @returns The offer code for the specified platform, or null if not found
302
+ */
303
+ static async getOfferCode(platformType = "stripe") {
304
+ this.verboseLog(`Getting offer code for platform: ${platformType}...`);
305
+ const storageKey = platformType === "stripe" ? "offerCode" : `offerCode_${platformType}`;
306
+ if (platformType === "stripe" && this.offerCode) {
307
+ this.verboseLog(`Returning cached offer code: ${this.offerCode}`);
308
+ return this.offerCode;
309
+ }
310
+ const storedOfferCode = await getValue(storageKey);
311
+ if (storedOfferCode) {
312
+ this.verboseLog(`Returning stored offer code: ${storedOfferCode}`);
313
+ if (platformType === "stripe") {
314
+ this.offerCode = storedOfferCode;
315
+ }
316
+ return storedOfferCode;
317
+ }
318
+ const shortCode = await getValue("referrerLink");
319
+ if (shortCode) {
320
+ this.verboseLog(`No stored offer code, fetching for short code: ${shortCode}`);
321
+ const fetchedCode = await this.fetchOfferCodeForPlatform(shortCode, platformType);
322
+ return fetchedCode;
323
+ }
324
+ this.verboseLog("No offer code found");
325
+ return null;
326
+ }
327
+ /**
328
+ * Get the Stripe coupon/promo code for the current affiliate
329
+ * Convenience method that calls getOfferCode with platformType='stripe'
330
+ * @returns The Stripe coupon/promo code, or null if not found
331
+ */
332
+ static async getStripeCouponCode() {
333
+ return this.getOfferCode("stripe");
334
+ }
335
+ /**
336
+ * Fetch offer code for a specific platform
337
+ * @param shortCode The affiliate short code
338
+ * @param platformType The platform type: 'ios', 'android', or 'stripe'
339
+ * @returns The offer code for the specified platform, or null if not found
340
+ */
341
+ static async fetchOfferCodeForPlatform(shortCode, platformType) {
342
+ this.verboseLog(`Fetching offer code for platform: ${platformType}, short code: ${shortCode}`);
343
+ try {
344
+ const companyCode = this.companyCode || await getValue("companyCode");
345
+ if (!companyCode) {
346
+ this.verboseLog("Cannot fetch offer code: no company code available");
347
+ return null;
348
+ }
349
+ const encoded = encodeURIComponent(shortCode);
350
+ const url = `https://api.insertaffiliate.com/v1/affiliateReturnOfferCode/${companyCode}/${encoded}?platformType=${platformType}`;
351
+ this.verboseLog(`Making API call to: ${url}`);
352
+ const response = await fetch(url);
353
+ this.verboseLog(`API response status: ${response.status}`);
354
+ if (!response.ok) {
355
+ this.verboseLog(`Failed to fetch offer code, status: ${response.status}`);
356
+ return null;
357
+ }
358
+ const offerCode = (await response.text()).replace(/[^a-zA-Z0-9]/g, "");
359
+ this.verboseLog(`Received offer code: ${offerCode}`);
360
+ const errorCodes = [
361
+ "errorofferCodeNotFound",
362
+ "errorAffiliateoffercodenotfoundinanycompany",
363
+ "errorAffiliateoffercodenotfoundinanycompanyAffiliatelinkwas",
364
+ "Routenotfound"
365
+ ];
366
+ if (errorCodes.includes(offerCode)) {
367
+ this.verboseLog("Offer code not found or invalid");
368
+ return null;
369
+ }
370
+ const storageKey = platformType === "stripe" ? "offerCode" : `offerCode_${platformType}`;
371
+ await saveValue(storageKey, offerCode);
372
+ if (platformType === "stripe") {
373
+ this.offerCode = offerCode;
374
+ }
375
+ this.verboseLog(`Offer code stored successfully with key ${storageKey}: ${offerCode}`);
376
+ return offerCode;
377
+ } catch (error) {
378
+ this.verboseLog(`Error fetching offer code: ${error}`);
379
+ return null;
380
+ }
381
+ }
382
+ static async fetchAndStoreOfferCode(shortCode) {
383
+ this.verboseLog(`Fetching offer code for short code: ${shortCode}`);
384
+ try {
385
+ const companyCode = this.companyCode || await getValue("companyCode");
386
+ if (!companyCode) {
387
+ this.verboseLog("Cannot fetch offer code: no company code available");
388
+ return;
389
+ }
390
+ const encoded = encodeURIComponent(shortCode);
391
+ const url = `https://api.insertaffiliate.com/v1/affiliateReturnOfferCode/${companyCode}/${encoded}`;
392
+ this.verboseLog(`Making API call to: ${url}`);
393
+ const response = await fetch(url);
394
+ this.verboseLog(`API response status: ${response.status}`);
395
+ if (!response.ok) {
396
+ this.verboseLog(`Failed to fetch offer code, status: ${response.status}`);
397
+ return;
398
+ }
399
+ const offerCode = (await response.text()).replace(/[^a-zA-Z0-9]/g, "");
400
+ this.verboseLog(`Received offer code: ${offerCode}`);
401
+ const errorCodes = [
402
+ "errorofferCodeNotFound",
403
+ "errorAffiliateoffercodenotfoundinanycompany",
404
+ "errorAffiliateoffercodenotfoundinanycompanyAffiliatelinkwas",
405
+ "Routenotfound"
406
+ ];
407
+ if (errorCodes.includes(offerCode)) {
408
+ this.verboseLog("Offer code not found or invalid");
409
+ return;
410
+ }
411
+ this.offerCode = offerCode;
412
+ await saveValue("offerCode", offerCode);
413
+ this.verboseLog(`Offer code stored successfully: ${offerCode}`);
414
+ } catch (error) {
415
+ this.verboseLog(`Error fetching offer code: ${error}`);
416
+ }
108
417
  }
109
418
  static async trackEvent(eventName) {
419
+ this.verboseLog(`Tracking event: ${eventName}`);
110
420
  const id = await this.returnInsertAffiliateIdentifier();
111
421
  if (!id) {
112
- console.warn("[Insert Affiliate] No affiliate identifier found.");
422
+ this.verboseLog("Cannot track event: no affiliate identifier available");
113
423
  return;
114
424
  }
115
425
  const companyCode = this.companyCode || await getValue("companyCode");
116
- if (!companyCode) return;
426
+ this.verboseLog(`Company code: ${companyCode || "empty"}`);
427
+ if (!companyCode) {
428
+ this.verboseLog("Cannot track event: no company code available");
429
+ return;
430
+ }
431
+ const payload = {
432
+ eventName,
433
+ deepLinkParam: id,
434
+ companyId: companyCode
435
+ };
436
+ this.verboseLog(`Track event payload: ${JSON.stringify(payload)}`);
437
+ this.verboseLog("Making API call to track event...");
117
438
  try {
118
- await fetch("https://api.insertaffiliate.com/v1/trackEvent", {
439
+ const response = await fetch("https://api.insertaffiliate.com/v1/trackEvent", {
119
440
  method: "POST",
120
441
  headers: { "Content-Type": "application/json" },
121
- body: JSON.stringify(
122
- {
123
- eventName,
124
- deepLinkParam: id,
125
- companyId: companyCode
126
- }
127
- )
442
+ body: JSON.stringify(payload)
128
443
  });
129
- console.log("[Insert Affiliate] Event tracked:", eventName);
444
+ this.verboseLog(`Track event API response status: ${response.status}`);
445
+ if (response.ok) {
446
+ this.verboseLog(`Event tracked successfully: ${eventName}`);
447
+ } else {
448
+ this.verboseLog(`Failed to track event with status code: ${response.status}`);
449
+ }
130
450
  } catch (err) {
131
- console.error("[Insert Affiliate] Failed to track event:", err);
451
+ this.verboseLog(`Network error tracking event: ${err}`);
132
452
  }
133
453
  }
134
454
  static async returnUserAccountTokenAndStoreExpectedTransaction() {
455
+ this.verboseLog("Getting user account token and storing expected transaction...");
135
456
  const shortCode = await this.returnInsertAffiliateIdentifier();
136
- if (!shortCode) return null;
457
+ if (!shortCode) {
458
+ this.verboseLog("No affiliate identifier found, not saving expected transaction");
459
+ return null;
460
+ }
137
461
  let token = await getValue("userAccountToken");
462
+ this.verboseLog(`Existing token: ${token || "none"}`);
138
463
  if (!token) {
464
+ this.verboseLog("Generating new user account token...");
139
465
  token = generateUUID();
140
466
  await saveValue("userAccountToken", token);
467
+ this.verboseLog(`Generated and saved new token: ${token}`);
141
468
  }
469
+ this.verboseLog(`User account token: ${token}`);
142
470
  await this.storeExpectedStoreTransaction(token);
143
471
  return token;
144
472
  }
145
473
  static async storeExpectedStoreTransaction(userAccountToken) {
474
+ this.verboseLog(`Storing expected store transaction with token: ${userAccountToken}`);
146
475
  const companyCode = this.companyCode || await getValue("companyCode");
147
476
  const shortCode = await this.returnInsertAffiliateIdentifier();
477
+ this.verboseLog(`Company code: ${companyCode || "empty"}, Short code: ${shortCode || "empty"}`);
148
478
  if (!companyCode || !shortCode) {
149
- console.error("[Insert Affiliate] Missing company code or identifier.");
479
+ this.verboseLog("Cannot store transaction: missing company code or identifier");
150
480
  return;
151
481
  }
152
482
  const payload = {
@@ -155,36 +485,43 @@ var InsertAffiliate = class {
155
485
  shortCode,
156
486
  storedDate: (/* @__PURE__ */ new Date()).toISOString()
157
487
  };
488
+ this.verboseLog(`Payload: ${JSON.stringify(payload)}`);
489
+ this.verboseLog("Making API call to store expected transaction...");
158
490
  try {
159
491
  const res = await fetch("https://api.insertaffiliate.com/v1/api/app-store-webhook/create-expected-transaction", {
160
492
  method: "POST",
161
493
  headers: { "Content-Type": "application/json" },
162
494
  body: JSON.stringify(payload)
163
495
  });
496
+ this.verboseLog(`API response status: ${res.status}`);
164
497
  if (res.status === 200) {
165
- console.log("[Insert Affiliate] Stored expected transaction");
498
+ this.verboseLog("Expected transaction stored successfully on server");
166
499
  } else {
167
- console.warn("[Insert Affiliate] Failed storing transaction:", res.status);
500
+ this.verboseLog(`Failed to store transaction with status: ${res.status}`);
168
501
  }
169
502
  } catch (error) {
170
- console.error("[Insert Affiliate] Error storing transaction:", error);
503
+ this.verboseLog(`Network error storing transaction: ${error}`);
171
504
  }
172
505
  }
173
506
  static async validatePurchaseWithIapticAPI(jsonIapPurchase, iapticAppId, iapticAppName, iapticPublicKey) {
174
507
  try {
508
+ this.verboseLog("Starting Iaptic purchase validation...");
175
509
  const isIOS = typeof window !== "undefined" && /iPad|iPhone|iPod/.test(navigator.userAgent);
510
+ this.verboseLog(`Platform detected: ${isIOS ? "iOS" : "Android"}`);
176
511
  const baseRequest = {
177
512
  id: iapticAppId,
178
513
  type: "application"
179
514
  };
180
515
  let transaction;
181
516
  if (isIOS) {
517
+ this.verboseLog("Creating iOS transaction payload");
182
518
  transaction = {
183
519
  id: iapticAppId,
184
520
  type: "ios-appstore",
185
521
  appStoreReceipt: jsonIapPurchase.transactionReceipt
186
522
  };
187
523
  } else {
524
+ this.verboseLog("Creating Android transaction payload");
188
525
  const receiptJson = JSON.parse(atob(jsonIapPurchase.transactionReceipt));
189
526
  transaction = {
190
527
  id: receiptJson.orderId,
@@ -195,10 +532,12 @@ var InsertAffiliate = class {
195
532
  };
196
533
  }
197
534
  const insertAffiliateIdentifier = await this.returnInsertAffiliateIdentifier();
535
+ this.verboseLog(`Affiliate identifier: ${insertAffiliateIdentifier || "none"}`);
198
536
  const payload = __spreadProps(__spreadValues({}, baseRequest), {
199
537
  transaction,
200
538
  additionalData: insertAffiliateIdentifier ? { applicationUsername: insertAffiliateIdentifier } : void 0
201
539
  });
540
+ this.verboseLog("Making API call to Iaptic validator...");
202
541
  const response = await fetch("https://validator.iaptic.com/v1/validate", {
203
542
  method: "POST",
204
543
  headers: {
@@ -207,17 +546,36 @@ var InsertAffiliate = class {
207
546
  },
208
547
  body: JSON.stringify(payload)
209
548
  });
210
- return response.status === 200;
549
+ this.verboseLog(`Iaptic validation response status: ${response.status}`);
550
+ if (response.status === 200) {
551
+ this.verboseLog("Purchase validated successfully");
552
+ return true;
553
+ } else {
554
+ this.verboseLog(`Validation failed with status: ${response.status}`);
555
+ return false;
556
+ }
211
557
  } catch (error) {
212
- console.error("[Insert Affiliate] Purchase validation failed:", error);
558
+ this.verboseLog(`Error during purchase validation: ${error}`);
213
559
  return false;
214
560
  }
215
561
  }
216
562
  static async fetchAndConditionallyOpenUrl(affiliateLink, offerCodeUrlId) {
563
+ this.verboseLog("Fetching offer code and opening URL...");
217
564
  const encoded = encodeURIComponent(affiliateLink);
565
+ this.verboseLog(`Encoded affiliate link: ${encoded}`);
218
566
  try {
219
- const res = await fetch(`https://api.insertaffiliate.com/v1/affiliateReturnOfferCode/${encoded}`);
567
+ const companyCode = this.companyCode || await getValue("companyCode");
568
+ if (!companyCode) {
569
+ this.verboseLog("Cannot fetch offer code: no company code available");
570
+ return;
571
+ }
572
+ this.verboseLog("Making API call to fetch offer code...");
573
+ const url = `https://api.insertaffiliate.com/v1/affiliateReturnOfferCode/${companyCode}/${encoded}`;
574
+ this.verboseLog(`API URL: ${url}`);
575
+ const res = await fetch(url);
576
+ this.verboseLog(`API response status: ${res.status}`);
220
577
  const offerCode = (await res.text()).replace(/[^a-zA-Z0-9]/g, "");
578
+ this.verboseLog(`Received offer code: ${offerCode}`);
221
579
  const errorCodes = [
222
580
  "errorofferCodeNotFound",
223
581
  "errorAffiliateoffercodenotfoundinanycompany",
@@ -225,39 +583,60 @@ var InsertAffiliate = class {
225
583
  "Routenotfound"
226
584
  ];
227
585
  if (errorCodes.includes(offerCode)) {
228
- console.warn("[Insert Affiliate] Offer Code Not Found");
586
+ this.verboseLog("Offer code not found or invalid");
229
587
  return;
230
588
  }
231
589
  const redeemUrl = `https://apps.apple.com/redeem?ctx=offercodes&id=${offerCodeUrlId}&code=${offerCode}`;
590
+ this.verboseLog(`Opening redeem URL: ${redeemUrl}`);
232
591
  window.open(redeemUrl, "_blank");
592
+ this.verboseLog("Redeem URL opened successfully");
233
593
  } catch (err) {
234
- console.error("[Insert Affiliate] Error fetching/opening offer code:", err);
594
+ this.verboseLog(`Error fetching/opening offer code: ${err}`);
235
595
  }
236
596
  }
237
597
  static async getOrCreateUserID() {
598
+ this.verboseLog("Getting or creating user ID...");
238
599
  let id = await getValue("userId");
600
+ this.verboseLog(`Existing user ID: ${id || "none"}`);
239
601
  if (!id) {
602
+ this.verboseLog("Generating new user ID...");
240
603
  id = generateShortDeviceID();
241
604
  await saveValue("userId", id);
605
+ this.verboseLog(`Generated and saved new user ID: ${id}`);
242
606
  }
243
607
  return id;
244
608
  }
245
609
  static async fetchShortLink(link) {
246
610
  try {
611
+ this.verboseLog("Converting deep link to short link...");
247
612
  const encoded = encodeURIComponent(link);
248
613
  const companyCode = this.companyCode || await getValue("companyCode");
249
- if (!companyCode) return null;
250
- const res = await fetch(`https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${companyCode}&deepLinkUrl=${encoded}`);
614
+ this.verboseLog(`Company code: ${companyCode || "empty"}`);
615
+ if (!companyCode) {
616
+ this.verboseLog("No company code available, cannot convert link");
617
+ return null;
618
+ }
619
+ const url = `https://api.insertaffiliate.com/V1/convert-deep-link-to-short-link?companyId=${companyCode}&deepLinkUrl=${encoded}`;
620
+ this.verboseLog(`Making API call to: ${url}`);
621
+ const res = await fetch(url);
622
+ this.verboseLog(`API response status: ${res.status}`);
251
623
  const data = await res.json();
252
- return (data == null ? void 0 : data.shortLink) || null;
624
+ const shortLink = (data == null ? void 0 : data.shortLink) || null;
625
+ this.verboseLog(`Short link received: ${shortLink || "none"}`);
626
+ return shortLink;
253
627
  } catch (err) {
254
- console.error("[Insert Affiliate] Failed to fetch short link:", (err == null ? void 0 : err.message) || err);
628
+ this.verboseLog(`Error fetching short link: ${(err == null ? void 0 : err.message) || err}`);
255
629
  return null;
256
630
  }
257
631
  }
258
632
  };
259
633
  InsertAffiliate.isInitialized = false;
260
634
  InsertAffiliate.companyCode = null;
635
+ InsertAffiliate.verboseLogging = false;
636
+ InsertAffiliate.insertAffiliateIdentifierChangeCallback = null;
637
+ InsertAffiliate.affiliateAttributionActiveTime = null;
638
+ // in milliseconds
639
+ InsertAffiliate.offerCode = null;
261
640
  // Annotate the CommonJS export names for ESM import in node:
262
641
  0 && (module.exports = {
263
642
  InsertAffiliate