insert-affiliate-react-native-sdk 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DeepLinkIapProvider.d.ts +7 -1
- package/dist/DeepLinkIapProvider.js +93 -3
- package/dist/index.d.ts +1 -1
- package/dist/useDeepLinkIapProvider.d.ts +2 -1
- package/dist/useDeepLinkIapProvider.js +2 -1
- package/package.json +1 -1
- package/readme.md +100 -1
- package/src/DeepLinkIapProvider.tsx +111 -5
- package/src/index.ts +1 -1
- package/src/useDeepLinkIapProvider.tsx +2 -0
|
@@ -3,6 +3,11 @@ type T_DEEPLINK_IAP_PROVIDER = {
|
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
};
|
|
5
5
|
export type InsertAffiliateIdentifierChangeCallback = (identifier: string | null) => void;
|
|
6
|
+
export type AffiliateDetails = {
|
|
7
|
+
affiliateName: string;
|
|
8
|
+
affiliateShortCode: string;
|
|
9
|
+
deeplinkurl: string;
|
|
10
|
+
} | null;
|
|
6
11
|
type CustomPurchase = {
|
|
7
12
|
[key: string]: any;
|
|
8
13
|
};
|
|
@@ -17,7 +22,8 @@ type T_DEEPLINK_IAP_CONTEXT = {
|
|
|
17
22
|
returnUserAccountTokenAndStoreExpectedTransaction: () => Promise<string | null>;
|
|
18
23
|
storeExpectedStoreTransaction: (purchaseToken: string) => Promise<void>;
|
|
19
24
|
trackEvent: (eventName: string) => Promise<void>;
|
|
20
|
-
setShortCode: (shortCode: string) => Promise<
|
|
25
|
+
setShortCode: (shortCode: string) => Promise<boolean>;
|
|
26
|
+
getAffiliateDetails: (affiliateCode: string) => Promise<AffiliateDetails>;
|
|
21
27
|
setInsertAffiliateIdentifier: (referringLink: string) => Promise<void | string>;
|
|
22
28
|
setInsertAffiliateIdentifierChangeCallback: (callback: InsertAffiliateIdentifierChangeCallback | null) => void;
|
|
23
29
|
handleInsertLinks: (url: string) => Promise<boolean>;
|
|
@@ -67,7 +67,8 @@ exports.DeepLinkIapContext = (0, react_1.createContext)({
|
|
|
67
67
|
returnUserAccountTokenAndStoreExpectedTransaction: () => __awaiter(void 0, void 0, void 0, function* () { return ''; }),
|
|
68
68
|
storeExpectedStoreTransaction: (purchaseToken) => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
69
69
|
trackEvent: (eventName) => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
70
|
-
setShortCode: (shortCode) => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
70
|
+
setShortCode: (shortCode) => __awaiter(void 0, void 0, void 0, function* () { return false; }),
|
|
71
|
+
getAffiliateDetails: (affiliateCode) => __awaiter(void 0, void 0, void 0, function* () { return null; }),
|
|
71
72
|
setInsertAffiliateIdentifier: (referringLink) => __awaiter(void 0, void 0, void 0, function* () { }),
|
|
72
73
|
setInsertAffiliateIdentifierChangeCallback: (callback) => { },
|
|
73
74
|
handleInsertLinks: (url) => __awaiter(void 0, void 0, void 0, function* () { return false; }),
|
|
@@ -1019,6 +1020,84 @@ const DeepLinkIapProvider = ({ children, }) => {
|
|
|
1019
1020
|
const isValidCharacters = /^[a-zA-Z0-9_]+$/.test(referringLink);
|
|
1020
1021
|
return isValidCharacters && referringLink.length >= 3 && referringLink.length <= 25;
|
|
1021
1022
|
};
|
|
1023
|
+
const checkAffiliateExists = (affiliateCode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1024
|
+
try {
|
|
1025
|
+
const activeCompanyCode = yield getActiveCompanyCode();
|
|
1026
|
+
if (!activeCompanyCode) {
|
|
1027
|
+
verboseLog('Cannot check affiliate: no company code available');
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
const url = 'https://api.insertaffiliate.com/V1/checkAffiliateExists';
|
|
1031
|
+
const payload = {
|
|
1032
|
+
companyId: activeCompanyCode,
|
|
1033
|
+
affiliateCode: affiliateCode
|
|
1034
|
+
};
|
|
1035
|
+
verboseLog(`Checking if affiliate exists: ${affiliateCode}`);
|
|
1036
|
+
const response = yield axios_1.default.post(url, payload, {
|
|
1037
|
+
headers: {
|
|
1038
|
+
'Content-Type': 'application/json',
|
|
1039
|
+
},
|
|
1040
|
+
});
|
|
1041
|
+
verboseLog(`Affiliate check response: ${JSON.stringify(response.data)}`);
|
|
1042
|
+
if (response.status === 200 && response.data) {
|
|
1043
|
+
const exists = response.data.exists === true;
|
|
1044
|
+
if (exists) {
|
|
1045
|
+
verboseLog(`Affiliate ${affiliateCode} exists and is valid`);
|
|
1046
|
+
}
|
|
1047
|
+
else {
|
|
1048
|
+
verboseLog(`Affiliate ${affiliateCode} does not exist`);
|
|
1049
|
+
}
|
|
1050
|
+
return exists;
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
verboseLog(`Unexpected response checking affiliate: status ${response.status}`);
|
|
1054
|
+
return false;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
catch (error) {
|
|
1058
|
+
verboseLog(`Error checking affiliate exists: ${error}`);
|
|
1059
|
+
return false;
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1062
|
+
const getAffiliateDetails = (affiliateCode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
1063
|
+
try {
|
|
1064
|
+
const activeCompanyCode = yield getActiveCompanyCode();
|
|
1065
|
+
if (!activeCompanyCode) {
|
|
1066
|
+
verboseLog('Cannot get affiliate details: no company code available');
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
1069
|
+
const url = 'https://api.insertaffiliate.com/V1/checkAffiliateExists';
|
|
1070
|
+
const payload = {
|
|
1071
|
+
companyId: activeCompanyCode,
|
|
1072
|
+
affiliateCode: affiliateCode
|
|
1073
|
+
};
|
|
1074
|
+
verboseLog(`Getting affiliate details for: ${affiliateCode}`);
|
|
1075
|
+
const response = yield axios_1.default.post(url, payload, {
|
|
1076
|
+
headers: {
|
|
1077
|
+
'Content-Type': 'application/json',
|
|
1078
|
+
},
|
|
1079
|
+
});
|
|
1080
|
+
verboseLog(`Affiliate details response: ${JSON.stringify(response.data)}`);
|
|
1081
|
+
if (response.status === 200 && response.data && response.data.exists === true) {
|
|
1082
|
+
const affiliate = response.data.affiliate;
|
|
1083
|
+
if (affiliate) {
|
|
1084
|
+
verboseLog(`Retrieved affiliate details: ${JSON.stringify(affiliate)}`);
|
|
1085
|
+
return {
|
|
1086
|
+
affiliateName: affiliate.affiliateName || '',
|
|
1087
|
+
affiliateShortCode: affiliate.affiliateShortCode || '',
|
|
1088
|
+
deeplinkurl: affiliate.deeplinkurl || ''
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
verboseLog(`Affiliate ${affiliateCode} not found or invalid response`);
|
|
1093
|
+
return null;
|
|
1094
|
+
}
|
|
1095
|
+
catch (error) {
|
|
1096
|
+
verboseLog(`Error getting affiliate details: ${error}`);
|
|
1097
|
+
console.error('[Insert Affiliate] Error getting affiliate details:', error);
|
|
1098
|
+
return null;
|
|
1099
|
+
}
|
|
1100
|
+
});
|
|
1022
1101
|
function setShortCode(shortCode) {
|
|
1023
1102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1024
1103
|
console.log('[Insert Affiliate] Setting short code.');
|
|
@@ -1026,8 +1105,18 @@ const DeepLinkIapProvider = ({ children, }) => {
|
|
|
1026
1105
|
// Validate it is a short code
|
|
1027
1106
|
const capitalisedShortCode = shortCode.toUpperCase();
|
|
1028
1107
|
isShortCode(capitalisedShortCode);
|
|
1029
|
-
//
|
|
1030
|
-
yield
|
|
1108
|
+
// Check if the affiliate exists before storing
|
|
1109
|
+
const exists = yield checkAffiliateExists(capitalisedShortCode);
|
|
1110
|
+
if (exists) {
|
|
1111
|
+
// If affiliate exists, set the Insert Affiliate Identifier
|
|
1112
|
+
yield storeInsertAffiliateIdentifier({ link: capitalisedShortCode });
|
|
1113
|
+
console.log(`[Insert Affiliate] Short code ${capitalisedShortCode} validated and stored successfully.`);
|
|
1114
|
+
return true;
|
|
1115
|
+
}
|
|
1116
|
+
else {
|
|
1117
|
+
console.warn(`[Insert Affiliate] Short code ${capitalisedShortCode} does not exist. Not storing.`);
|
|
1118
|
+
return false;
|
|
1119
|
+
}
|
|
1031
1120
|
});
|
|
1032
1121
|
}
|
|
1033
1122
|
function getOrCreateUserAccountToken() {
|
|
@@ -1529,6 +1618,7 @@ const DeepLinkIapProvider = ({ children, }) => {
|
|
|
1529
1618
|
userId,
|
|
1530
1619
|
OfferCode,
|
|
1531
1620
|
setShortCode,
|
|
1621
|
+
getAffiliateDetails,
|
|
1532
1622
|
returnInsertAffiliateIdentifier,
|
|
1533
1623
|
isAffiliateAttributionValid,
|
|
1534
1624
|
getAffiliateStoredDate,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import DeepLinkIapProvider from "./DeepLinkIapProvider";
|
|
2
2
|
import useDeepLinkIapProvider from "./useDeepLinkIapProvider";
|
|
3
3
|
export { DeepLinkIapProvider, useDeepLinkIapProvider };
|
|
4
|
-
export type { InsertAffiliateIdentifierChangeCallback } from "./DeepLinkIapProvider";
|
|
4
|
+
export type { InsertAffiliateIdentifierChangeCallback, AffiliateDetails } from "./DeepLinkIapProvider";
|
|
@@ -10,7 +10,8 @@ declare const useDeepLinkIapProvider: () => {
|
|
|
10
10
|
isAffiliateAttributionValid: () => Promise<boolean>;
|
|
11
11
|
getAffiliateStoredDate: () => Promise<Date | null>;
|
|
12
12
|
trackEvent: (eventName: string) => Promise<void>;
|
|
13
|
-
setShortCode: (shortCode: string) => Promise<
|
|
13
|
+
setShortCode: (shortCode: string) => Promise<boolean>;
|
|
14
|
+
getAffiliateDetails: (affiliateCode: string) => Promise<import("./DeepLinkIapProvider").AffiliateDetails>;
|
|
14
15
|
setInsertAffiliateIdentifier: (referringLink: string) => Promise<void | string>;
|
|
15
16
|
setInsertAffiliateIdentifierChangeCallback: (callback: import("./DeepLinkIapProvider").InsertAffiliateIdentifierChangeCallback | null) => void;
|
|
16
17
|
handleInsertLinks: (url: string) => Promise<boolean>;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const react_1 = require("react");
|
|
4
4
|
const DeepLinkIapProvider_1 = require("./DeepLinkIapProvider");
|
|
5
5
|
const useDeepLinkIapProvider = () => {
|
|
6
|
-
const { referrerLink, userId, validatePurchaseWithIapticAPI, storeExpectedStoreTransaction, returnUserAccountTokenAndStoreExpectedTransaction, returnInsertAffiliateIdentifier, isAffiliateAttributionValid, getAffiliateStoredDate, trackEvent, setShortCode, setInsertAffiliateIdentifier, setInsertAffiliateIdentifierChangeCallback, handleInsertLinks, initialize, isInitialized, OfferCode, } = (0, react_1.useContext)(DeepLinkIapProvider_1.DeepLinkIapContext);
|
|
6
|
+
const { referrerLink, userId, validatePurchaseWithIapticAPI, storeExpectedStoreTransaction, returnUserAccountTokenAndStoreExpectedTransaction, returnInsertAffiliateIdentifier, isAffiliateAttributionValid, getAffiliateStoredDate, trackEvent, setShortCode, getAffiliateDetails, setInsertAffiliateIdentifier, setInsertAffiliateIdentifierChangeCallback, handleInsertLinks, initialize, isInitialized, OfferCode, } = (0, react_1.useContext)(DeepLinkIapProvider_1.DeepLinkIapContext);
|
|
7
7
|
return {
|
|
8
8
|
referrerLink,
|
|
9
9
|
userId,
|
|
@@ -15,6 +15,7 @@ const useDeepLinkIapProvider = () => {
|
|
|
15
15
|
getAffiliateStoredDate,
|
|
16
16
|
trackEvent,
|
|
17
17
|
setShortCode,
|
|
18
|
+
getAffiliateDetails,
|
|
18
19
|
setInsertAffiliateIdentifier,
|
|
19
20
|
setInsertAffiliateIdentifierChangeCallback,
|
|
20
21
|
handleInsertLinks,
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -763,6 +763,7 @@ const DeepLinkHandler = () => {
|
|
|
763
763
|
// Listen for both deep link types
|
|
764
764
|
appsFlyer.onDeepLink(handleDeepLink);
|
|
765
765
|
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
766
|
+
appsFlyer.onInstallConversionData(handleDeepLink);
|
|
766
767
|
|
|
767
768
|
initAppsFlyer();
|
|
768
769
|
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
@@ -828,6 +829,7 @@ const DeepLinkHandler = () => {
|
|
|
828
829
|
// Listen for both deep link types
|
|
829
830
|
appsFlyer.onDeepLink(handleDeepLink);
|
|
830
831
|
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
832
|
+
appsFlyer.onInstallConversionData(handleDeepLink);
|
|
831
833
|
|
|
832
834
|
initAppsFlyer();
|
|
833
835
|
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
@@ -1214,6 +1216,12 @@ Short codes must meet the following criteria:
|
|
|
1214
1216
|
- Contain only **letters, numbers, and underscores** (alphanumeric characters and underscores).
|
|
1215
1217
|
- Replace {{ user_entered_short_code }} with the short code the user enters through your chosen input method, i.e. an input field / pop up element
|
|
1216
1218
|
|
|
1219
|
+
**Return Value**: `setShortCode` returns a `Promise<boolean>`:
|
|
1220
|
+
- Returns `true` if the short code exists and was successfully validated and stored
|
|
1221
|
+
- Returns `false` if the short code does not exist or validation failed
|
|
1222
|
+
|
|
1223
|
+
This allows you to provide immediate feedback to users about whether their entered code is valid.
|
|
1224
|
+
|
|
1217
1225
|
```javascript
|
|
1218
1226
|
import {
|
|
1219
1227
|
DeepLinkIapProvider,
|
|
@@ -1223,12 +1231,30 @@ Short codes must meet the following criteria:
|
|
|
1223
1231
|
setShortCode,
|
|
1224
1232
|
} = useDeepLinkIapProvider();
|
|
1225
1233
|
|
|
1234
|
+
// Basic usage (without validation feedback)
|
|
1226
1235
|
<Button
|
|
1227
1236
|
title={'Set Short Code'}
|
|
1228
1237
|
onPress={() => setShortCode('JOIN_123')}
|
|
1229
1238
|
/>
|
|
1239
|
+
|
|
1240
|
+
// Recommended usage with validation feedback
|
|
1241
|
+
<Button
|
|
1242
|
+
title={'Set Short Code'}
|
|
1243
|
+
onPress={async () => {
|
|
1244
|
+
const isValid = await setShortCode('JOIN_123');
|
|
1245
|
+
if (isValid) {
|
|
1246
|
+
// Show success message to user
|
|
1247
|
+
Alert.alert('Success', 'Affiliate code applied successfully!');
|
|
1248
|
+
} else {
|
|
1249
|
+
// Show error message to user
|
|
1250
|
+
Alert.alert('Error', 'Invalid affiliate code. Please check and try again.');
|
|
1251
|
+
}
|
|
1252
|
+
}}
|
|
1253
|
+
/>
|
|
1230
1254
|
```
|
|
1231
1255
|
|
|
1256
|
+
**Important**: The SDK will automatically validate the short code with the Insert Affiliate backend before storing it. Only valid short codes that exist in your company's affiliate list will be stored. Invalid codes will be rejected and not associated with the user.
|
|
1257
|
+
|
|
1232
1258
|
### Attribution Timeout
|
|
1233
1259
|
|
|
1234
1260
|
You can configure how long an affiliate link attribution remains active after being clicked. This allows you to control the attribution window for commissions.
|
|
@@ -1308,4 +1334,77 @@ const storedDate = await getAffiliateStoredDate();
|
|
|
1308
1334
|
3. **Expired Attribution**: If the attribution has expired, the method returns `null` instead of the affiliate identifier
|
|
1309
1335
|
4. **Bypass Option**: You can bypass the timeout check by passing `true` to `returnInsertAffiliateIdentifier(true)`
|
|
1310
1336
|
|
|
1311
|
-
This ensures that affiliates are only credited for purchases made within the specified attribution window, providing fair and accurate commission tracking.
|
|
1337
|
+
This ensures that affiliates are only credited for purchases made within the specified attribution window, providing fair and accurate commission tracking.
|
|
1338
|
+
|
|
1339
|
+
### Getting Affiliate Details
|
|
1340
|
+
|
|
1341
|
+
You can retrieve detailed information about an affiliate by their short code or deep link using the `getAffiliateDetails` method. This is useful for displaying affiliate information to users or showing personalized content based on the referrer.
|
|
1342
|
+
|
|
1343
|
+
#### Method Signature
|
|
1344
|
+
|
|
1345
|
+
```typescript
|
|
1346
|
+
getAffiliateDetails(affiliateCode: string): Promise<AffiliateDetails>
|
|
1347
|
+
|
|
1348
|
+
type AffiliateDetails = {
|
|
1349
|
+
affiliateName: string;
|
|
1350
|
+
affiliateShortCode: string;
|
|
1351
|
+
deeplinkurl: string;
|
|
1352
|
+
} | null;
|
|
1353
|
+
```
|
|
1354
|
+
|
|
1355
|
+
#### Usage Example
|
|
1356
|
+
|
|
1357
|
+
```javascript
|
|
1358
|
+
import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
1359
|
+
import type { AffiliateDetails } from 'insert-affiliate-react-native-sdk';
|
|
1360
|
+
|
|
1361
|
+
const MyComponent = () => {
|
|
1362
|
+
const { getAffiliateDetails } = useDeepLinkIapProvider();
|
|
1363
|
+
|
|
1364
|
+
const handleGetAffiliateInfo = async (code: string) => {
|
|
1365
|
+
const details = await getAffiliateDetails(code);
|
|
1366
|
+
|
|
1367
|
+
if (details) {
|
|
1368
|
+
console.log('Affiliate Name:', details.affiliateName);
|
|
1369
|
+
console.log('Short Code:', details.affiliateShortCode);
|
|
1370
|
+
console.log('Deep Link:', details.deeplinkurl);
|
|
1371
|
+
|
|
1372
|
+
// Example: Show affiliate name in UI
|
|
1373
|
+
Alert.alert(
|
|
1374
|
+
'Affiliate Found',
|
|
1375
|
+
`This code belongs to ${details.affiliateName}`
|
|
1376
|
+
);
|
|
1377
|
+
} else {
|
|
1378
|
+
console.log('Affiliate not found');
|
|
1379
|
+
Alert.alert('Error', 'Invalid affiliate code');
|
|
1380
|
+
}
|
|
1381
|
+
};
|
|
1382
|
+
|
|
1383
|
+
return (
|
|
1384
|
+
<View>
|
|
1385
|
+
<Button
|
|
1386
|
+
title="Get Affiliate Info"
|
|
1387
|
+
onPress={() => handleGetAffiliateInfo('JOIN_123')}
|
|
1388
|
+
/>
|
|
1389
|
+
</View>
|
|
1390
|
+
);
|
|
1391
|
+
};
|
|
1392
|
+
```
|
|
1393
|
+
|
|
1394
|
+
#### Return Value
|
|
1395
|
+
|
|
1396
|
+
- Returns an object with affiliate details if the code exists:
|
|
1397
|
+
- `affiliateName`: The name of the affiliate
|
|
1398
|
+
- `affiliateShortCode`: The affiliate's short code
|
|
1399
|
+
- `deeplinkurl`: The affiliate's deep link URL
|
|
1400
|
+
- Returns `null` if:
|
|
1401
|
+
- The affiliate code doesn't exist
|
|
1402
|
+
- The company code is not initialized
|
|
1403
|
+
- There's a network error or API issue
|
|
1404
|
+
|
|
1405
|
+
#### Important Notes
|
|
1406
|
+
|
|
1407
|
+
- This method does **not** store or set the affiliate identifier - it only retrieves information
|
|
1408
|
+
- Use `setShortCode()` to actually associate an affiliate with a user
|
|
1409
|
+
- The method automatically strips UUIDs from codes (e.g., "ABC123-uuid" becomes "ABC123")
|
|
1410
|
+
- Works with both short codes and deep link URLs
|
|
@@ -17,6 +17,12 @@ type T_DEEPLINK_IAP_PROVIDER = {
|
|
|
17
17
|
|
|
18
18
|
export type InsertAffiliateIdentifierChangeCallback = (identifier: string | null) => void;
|
|
19
19
|
|
|
20
|
+
export type AffiliateDetails = {
|
|
21
|
+
affiliateName: string;
|
|
22
|
+
affiliateShortCode: string;
|
|
23
|
+
deeplinkurl: string;
|
|
24
|
+
} | null;
|
|
25
|
+
|
|
20
26
|
type CustomPurchase = {
|
|
21
27
|
[key: string]: any; // Accept any fields to allow it to work wtih multiple IAP libraries
|
|
22
28
|
};
|
|
@@ -39,7 +45,8 @@ type T_DEEPLINK_IAP_CONTEXT = {
|
|
|
39
45
|
purchaseToken: string
|
|
40
46
|
) => Promise<void>;
|
|
41
47
|
trackEvent: (eventName: string) => Promise<void>;
|
|
42
|
-
setShortCode: (shortCode: string) => Promise<
|
|
48
|
+
setShortCode: (shortCode: string) => Promise<boolean>;
|
|
49
|
+
getAffiliateDetails: (affiliateCode: string) => Promise<AffiliateDetails>;
|
|
43
50
|
setInsertAffiliateIdentifier: (
|
|
44
51
|
referringLink: string
|
|
45
52
|
) => Promise<void | string>;
|
|
@@ -92,7 +99,8 @@ export const DeepLinkIapContext = createContext<T_DEEPLINK_IAP_CONTEXT>({
|
|
|
92
99
|
returnUserAccountTokenAndStoreExpectedTransaction: async () => '',
|
|
93
100
|
storeExpectedStoreTransaction: async (purchaseToken: string) => {},
|
|
94
101
|
trackEvent: async (eventName: string) => {},
|
|
95
|
-
setShortCode: async (shortCode: string) =>
|
|
102
|
+
setShortCode: async (shortCode: string) => false,
|
|
103
|
+
getAffiliateDetails: async (affiliateCode: string) => null,
|
|
96
104
|
setInsertAffiliateIdentifier: async (referringLink: string) => {},
|
|
97
105
|
setInsertAffiliateIdentifierChangeCallback: (callback: InsertAffiliateIdentifierChangeCallback | null) => {},
|
|
98
106
|
handleInsertLinks: async (url: string) => false,
|
|
@@ -1174,7 +1182,94 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1174
1182
|
return isValidCharacters && referringLink.length >= 3 && referringLink.length <= 25;
|
|
1175
1183
|
};
|
|
1176
1184
|
|
|
1177
|
-
async
|
|
1185
|
+
const checkAffiliateExists = async (affiliateCode: string): Promise<boolean> => {
|
|
1186
|
+
try {
|
|
1187
|
+
const activeCompanyCode = await getActiveCompanyCode();
|
|
1188
|
+
if (!activeCompanyCode) {
|
|
1189
|
+
verboseLog('Cannot check affiliate: no company code available');
|
|
1190
|
+
return false;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
const url = 'https://api.insertaffiliate.com/V1/checkAffiliateExists';
|
|
1194
|
+
const payload = {
|
|
1195
|
+
companyId: activeCompanyCode,
|
|
1196
|
+
affiliateCode: affiliateCode
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
verboseLog(`Checking if affiliate exists: ${affiliateCode}`);
|
|
1200
|
+
|
|
1201
|
+
const response = await axios.post(url, payload, {
|
|
1202
|
+
headers: {
|
|
1203
|
+
'Content-Type': 'application/json',
|
|
1204
|
+
},
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1207
|
+
verboseLog(`Affiliate check response: ${JSON.stringify(response.data)}`);
|
|
1208
|
+
|
|
1209
|
+
if (response.status === 200 && response.data) {
|
|
1210
|
+
const exists = response.data.exists === true;
|
|
1211
|
+
if (exists) {
|
|
1212
|
+
verboseLog(`Affiliate ${affiliateCode} exists and is valid`);
|
|
1213
|
+
} else {
|
|
1214
|
+
verboseLog(`Affiliate ${affiliateCode} does not exist`);
|
|
1215
|
+
}
|
|
1216
|
+
return exists;
|
|
1217
|
+
} else {
|
|
1218
|
+
verboseLog(`Unexpected response checking affiliate: status ${response.status}`);
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
} catch (error) {
|
|
1222
|
+
verboseLog(`Error checking affiliate exists: ${error}`);
|
|
1223
|
+
return false;
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
const getAffiliateDetails = async (affiliateCode: string): Promise<AffiliateDetails> => {
|
|
1228
|
+
try {
|
|
1229
|
+
const activeCompanyCode = await getActiveCompanyCode();
|
|
1230
|
+
if (!activeCompanyCode) {
|
|
1231
|
+
verboseLog('Cannot get affiliate details: no company code available');
|
|
1232
|
+
return null;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
const url = 'https://api.insertaffiliate.com/V1/checkAffiliateExists';
|
|
1236
|
+
const payload = {
|
|
1237
|
+
companyId: activeCompanyCode,
|
|
1238
|
+
affiliateCode: affiliateCode
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
verboseLog(`Getting affiliate details for: ${affiliateCode}`);
|
|
1242
|
+
|
|
1243
|
+
const response = await axios.post(url, payload, {
|
|
1244
|
+
headers: {
|
|
1245
|
+
'Content-Type': 'application/json',
|
|
1246
|
+
},
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
verboseLog(`Affiliate details response: ${JSON.stringify(response.data)}`);
|
|
1250
|
+
|
|
1251
|
+
if (response.status === 200 && response.data && response.data.exists === true) {
|
|
1252
|
+
const affiliate = response.data.affiliate;
|
|
1253
|
+
if (affiliate) {
|
|
1254
|
+
verboseLog(`Retrieved affiliate details: ${JSON.stringify(affiliate)}`);
|
|
1255
|
+
return {
|
|
1256
|
+
affiliateName: affiliate.affiliateName || '',
|
|
1257
|
+
affiliateShortCode: affiliate.affiliateShortCode || '',
|
|
1258
|
+
deeplinkurl: affiliate.deeplinkurl || ''
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
verboseLog(`Affiliate ${affiliateCode} not found or invalid response`);
|
|
1264
|
+
return null;
|
|
1265
|
+
} catch (error) {
|
|
1266
|
+
verboseLog(`Error getting affiliate details: ${error}`);
|
|
1267
|
+
console.error('[Insert Affiliate] Error getting affiliate details:', error);
|
|
1268
|
+
return null;
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
|
|
1272
|
+
async function setShortCode(shortCode: string): Promise<boolean> {
|
|
1178
1273
|
console.log('[Insert Affiliate] Setting short code.');
|
|
1179
1274
|
await generateThenSetUserID();
|
|
1180
1275
|
|
|
@@ -1182,8 +1277,18 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1182
1277
|
const capitalisedShortCode = shortCode.toUpperCase();
|
|
1183
1278
|
isShortCode(capitalisedShortCode);
|
|
1184
1279
|
|
|
1185
|
-
//
|
|
1186
|
-
await
|
|
1280
|
+
// Check if the affiliate exists before storing
|
|
1281
|
+
const exists = await checkAffiliateExists(capitalisedShortCode);
|
|
1282
|
+
|
|
1283
|
+
if (exists) {
|
|
1284
|
+
// If affiliate exists, set the Insert Affiliate Identifier
|
|
1285
|
+
await storeInsertAffiliateIdentifier({ link: capitalisedShortCode });
|
|
1286
|
+
console.log(`[Insert Affiliate] Short code ${capitalisedShortCode} validated and stored successfully.`);
|
|
1287
|
+
return true;
|
|
1288
|
+
} else {
|
|
1289
|
+
console.warn(`[Insert Affiliate] Short code ${capitalisedShortCode} does not exist. Not storing.`);
|
|
1290
|
+
return false;
|
|
1291
|
+
}
|
|
1187
1292
|
}
|
|
1188
1293
|
|
|
1189
1294
|
async function getOrCreateUserAccountToken(): Promise<string> {
|
|
@@ -1779,6 +1884,7 @@ const DeepLinkIapProvider: React.FC<T_DEEPLINK_IAP_PROVIDER> = ({
|
|
|
1779
1884
|
userId,
|
|
1780
1885
|
OfferCode,
|
|
1781
1886
|
setShortCode,
|
|
1887
|
+
getAffiliateDetails,
|
|
1782
1888
|
returnInsertAffiliateIdentifier,
|
|
1783
1889
|
isAffiliateAttributionValid,
|
|
1784
1890
|
getAffiliateStoredDate,
|
package/src/index.ts
CHANGED
|
@@ -4,4 +4,4 @@ import useDeepLinkIapProvider from "./useDeepLinkIapProvider";
|
|
|
4
4
|
export { DeepLinkIapProvider, useDeepLinkIapProvider };
|
|
5
5
|
|
|
6
6
|
// Export types
|
|
7
|
-
export type { InsertAffiliateIdentifierChangeCallback } from "./DeepLinkIapProvider";
|
|
7
|
+
export type { InsertAffiliateIdentifierChangeCallback, AffiliateDetails } from "./DeepLinkIapProvider";
|
|
@@ -13,6 +13,7 @@ const useDeepLinkIapProvider = () => {
|
|
|
13
13
|
getAffiliateStoredDate,
|
|
14
14
|
trackEvent,
|
|
15
15
|
setShortCode,
|
|
16
|
+
getAffiliateDetails,
|
|
16
17
|
setInsertAffiliateIdentifier,
|
|
17
18
|
setInsertAffiliateIdentifierChangeCallback,
|
|
18
19
|
handleInsertLinks,
|
|
@@ -32,6 +33,7 @@ const useDeepLinkIapProvider = () => {
|
|
|
32
33
|
getAffiliateStoredDate,
|
|
33
34
|
trackEvent,
|
|
34
35
|
setShortCode,
|
|
36
|
+
getAffiliateDetails,
|
|
35
37
|
setInsertAffiliateIdentifier,
|
|
36
38
|
setInsertAffiliateIdentifierChangeCallback,
|
|
37
39
|
handleInsertLinks,
|