gomarketme-react-native 2.0.0 → 4.0.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/README.md +58 -12
- package/dist/index.d.ts +6 -4
- package/dist/index.js +234 -293
- package/package.json +10 -9
- package/src/index.tsx +166 -217
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gomarketme-react-native",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Affiliate Marketing for React Native-Based iOS and Android Apps.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,16 +18,17 @@
|
|
|
18
18
|
"author": "GoMarketMe",
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@react-native-async-storage/async-storage": "^
|
|
22
|
-
"axios": "^
|
|
23
|
-
"get-user-locale": "^
|
|
24
|
-
"react-native-device-info": "^14.
|
|
25
|
-
"react-native-iap": "^
|
|
21
|
+
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
22
|
+
"axios": "^1.13.2",
|
|
23
|
+
"get-user-locale": "^3.0.0",
|
|
24
|
+
"react-native-device-info": "^14.1.1",
|
|
25
|
+
"react-native-iap": "^14.4.38",
|
|
26
|
+
"react-native-nitro-modules": "^0.31.4"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@types/node": "^
|
|
29
|
-
"@types/react-native": "^0.
|
|
30
|
-
"typescript": "^
|
|
29
|
+
"@types/node": "^24.10.0",
|
|
30
|
+
"@types/react-native": "^0.73.0",
|
|
31
|
+
"typescript": "^5.9.3"
|
|
31
32
|
},
|
|
32
33
|
"peerDependencies": {
|
|
33
34
|
"react": "*",
|
package/src/index.tsx
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { Platform, Dimensions, PixelRatio } from 'react-native';
|
|
2
2
|
import DeviceInfo from 'react-native-device-info';
|
|
3
|
-
import getUserLocale from 'get-user-locale'
|
|
3
|
+
import getUserLocale from 'get-user-locale';
|
|
4
4
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
5
|
-
import * as RNIap from 'react-native-iap';
|
|
6
5
|
import axios from 'axios';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
type Purchase,
|
|
9
|
+
type PurchaseError,
|
|
10
|
+
purchaseUpdatedListener,
|
|
11
|
+
purchaseErrorListener,
|
|
12
|
+
fetchProducts,
|
|
13
|
+
ProductCommon,
|
|
14
|
+
PurchaseCommon,
|
|
15
|
+
getAvailablePurchases,
|
|
16
|
+
} from 'react-native-iap';
|
|
17
|
+
|
|
7
18
|
export class GoMarketMeAffiliateMarketingData {
|
|
8
19
|
campaign: Campaign;
|
|
9
20
|
affiliate: Affiliate;
|
|
@@ -29,11 +40,7 @@ export class GoMarketMeAffiliateMarketingData {
|
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
static fromJson(json: Record<string, any>): GoMarketMeAffiliateMarketingData | null {
|
|
32
|
-
|
|
33
|
-
if (Object.keys(json).length === 0) {
|
|
34
|
-
return null; // Return null or undefined, depending on your preference
|
|
35
|
-
}
|
|
36
|
-
|
|
43
|
+
if (!json || Object.keys(json).length === 0) return null;
|
|
37
44
|
return new GoMarketMeAffiliateMarketingData(
|
|
38
45
|
Campaign.fromJson(json.campaign),
|
|
39
46
|
Affiliate.fromJson(json.affiliate),
|
|
@@ -62,11 +69,11 @@ export class Campaign {
|
|
|
62
69
|
|
|
63
70
|
static fromJson(json: Record<string, any>): Campaign {
|
|
64
71
|
return new Campaign(
|
|
65
|
-
json
|
|
66
|
-
json
|
|
67
|
-
json
|
|
68
|
-
json
|
|
69
|
-
json
|
|
72
|
+
json?.id || '',
|
|
73
|
+
json?.name || '',
|
|
74
|
+
json?.status || '',
|
|
75
|
+
json?.type || '',
|
|
76
|
+
json?.public_link_url
|
|
70
77
|
);
|
|
71
78
|
}
|
|
72
79
|
}
|
|
@@ -100,13 +107,13 @@ export class Affiliate {
|
|
|
100
107
|
|
|
101
108
|
static fromJson(json: Record<string, any>): Affiliate {
|
|
102
109
|
return new Affiliate(
|
|
103
|
-
json
|
|
104
|
-
json
|
|
105
|
-
json
|
|
106
|
-
json
|
|
107
|
-
json
|
|
108
|
-
json
|
|
109
|
-
json
|
|
110
|
+
json?.id || '',
|
|
111
|
+
json?.first_name || '',
|
|
112
|
+
json?.last_name || '',
|
|
113
|
+
json?.country_code || '',
|
|
114
|
+
json?.instagram_account || '',
|
|
115
|
+
json?.tiktok_account || '',
|
|
116
|
+
json?.x_account || ''
|
|
110
117
|
);
|
|
111
118
|
}
|
|
112
119
|
}
|
|
@@ -121,220 +128,183 @@ export class SaleDistribution {
|
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
static fromJson(json: Record<string, any>): SaleDistribution {
|
|
124
|
-
return new SaleDistribution(
|
|
125
|
-
json.platform_percentage || '',
|
|
126
|
-
json.affiliate_percentage || ''
|
|
127
|
-
);
|
|
131
|
+
return new SaleDistribution(json?.platform_percentage || '', json?.affiliate_percentage || '');
|
|
128
132
|
}
|
|
129
133
|
}
|
|
130
134
|
|
|
131
135
|
class GoMarketMe {
|
|
132
136
|
private static instance: GoMarketMe;
|
|
133
137
|
private sdkType = 'ReactNative';
|
|
134
|
-
private sdkVersion = '
|
|
138
|
+
private sdkVersion = '4.0.0';
|
|
135
139
|
private sdkInitializedKey = 'GOMARKETME_SDK_INITIALIZED';
|
|
136
|
-
private sdkInitializationUrl =
|
|
137
|
-
|
|
140
|
+
private sdkInitializationUrl =
|
|
141
|
+
'https://4v9008q1a5.execute-api.us-west-2.amazonaws.com/prod/v1/sdk-initialization';
|
|
142
|
+
private systemInfoUrl =
|
|
143
|
+
'https://4v9008q1a5.execute-api.us-west-2.amazonaws.com/prod/v1/mobile/system-info';
|
|
138
144
|
private eventUrl = 'https://4v9008q1a5.execute-api.us-west-2.amazonaws.com/prod/v1/event';
|
|
139
145
|
private _affiliateCampaignCode = '';
|
|
140
146
|
private _deviceId = '';
|
|
141
|
-
private _packageName = ''
|
|
147
|
+
private _packageName = '';
|
|
148
|
+
private _purchaseUpdateUnsub?: ReturnType<typeof purchaseUpdatedListener>;
|
|
149
|
+
private _purchaseErrorUnsub?: ReturnType<typeof purchaseErrorListener>;
|
|
142
150
|
public affiliateMarketingData?: GoMarketMeAffiliateMarketingData | null;
|
|
143
151
|
|
|
144
152
|
private constructor() { }
|
|
145
153
|
|
|
146
154
|
public static getInstance(): GoMarketMe {
|
|
147
|
-
if (!GoMarketMe.instance)
|
|
148
|
-
GoMarketMe.instance = new GoMarketMe();
|
|
149
|
-
}
|
|
155
|
+
if (!GoMarketMe.instance) GoMarketMe.instance = new GoMarketMe();
|
|
150
156
|
return GoMarketMe.instance;
|
|
151
157
|
}
|
|
152
158
|
|
|
153
159
|
public async initialize(apiKey: string): Promise<void> {
|
|
154
160
|
try {
|
|
155
161
|
const isSDKInitialized = await this._isSDKInitialized();
|
|
156
|
-
if (!isSDKInitialized)
|
|
157
|
-
await this._postSDKInitialization(apiKey);
|
|
158
|
-
}
|
|
162
|
+
if (!isSDKInitialized) await this._postSDKInitialization(apiKey);
|
|
159
163
|
this._packageName = DeviceInfo.getBundleId();
|
|
160
164
|
const systemInfo = await this._getSystemInfo();
|
|
161
165
|
this.affiliateMarketingData = await this._postSystemInfo(systemInfo, apiKey);
|
|
162
|
-
await this.
|
|
166
|
+
await this._addListeners(apiKey);
|
|
167
|
+
this._fetchExistingPurchases(apiKey).catch(e => {
|
|
168
|
+
console.log('Error in background purchase fetch:', e);
|
|
169
|
+
});
|
|
163
170
|
} catch (e) {
|
|
164
171
|
console.log('Error initializing GoMarketMe:', e);
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
174
|
|
|
168
|
-
|
|
175
|
+
public removeListeners(): void {
|
|
169
176
|
try {
|
|
170
|
-
|
|
171
|
-
|
|
177
|
+
this._purchaseUpdateUnsub?.remove?.();
|
|
178
|
+
this._purchaseErrorUnsub?.remove?.();
|
|
179
|
+
} catch (e) {
|
|
180
|
+
console.log('Error removing listeners:', e);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private async _addListeners(apiKey: string): Promise<void> {
|
|
185
|
+
if (!this._purchaseUpdateUnsub) {
|
|
186
|
+
this._purchaseUpdateUnsub = purchaseUpdatedListener(async (purchase: Purchase) => {
|
|
187
|
+
try {
|
|
188
|
+
await this._fetchConsolidatedPurchases([purchase], apiKey);
|
|
189
|
+
} catch (e) {
|
|
190
|
+
console.log('purchaseUpdated error:', e);
|
|
191
|
+
}
|
|
172
192
|
});
|
|
193
|
+
}
|
|
173
194
|
|
|
174
|
-
|
|
175
|
-
|
|
195
|
+
if (!this._purchaseErrorUnsub) {
|
|
196
|
+
this._purchaseErrorUnsub = purchaseErrorListener((error: PurchaseError) => {
|
|
197
|
+
console.log('purchaseErrorListener:', error);
|
|
176
198
|
});
|
|
177
|
-
} catch (e) {
|
|
178
|
-
console.log('Error setting up IAP listeners:', e);
|
|
179
199
|
}
|
|
180
200
|
}
|
|
181
201
|
|
|
182
202
|
private async _getSystemInfo(): Promise<any> {
|
|
183
|
-
const deviceData =
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
203
|
+
const deviceData =
|
|
204
|
+
Platform.OS === 'ios'
|
|
205
|
+
? await this._readIosDeviceInfo()
|
|
206
|
+
: await this._readAndroidDeviceInfo();
|
|
187
207
|
|
|
188
|
-
this._deviceId = deviceData['deviceId'];
|
|
208
|
+
this._deviceId = deviceData['deviceId'] || '';
|
|
189
209
|
|
|
190
210
|
const devicePixelRatio = PixelRatio.get();
|
|
191
211
|
const dimension = Dimensions.get('window');
|
|
192
212
|
|
|
193
|
-
const windowData = {
|
|
194
|
-
devicePixelRatio: devicePixelRatio,
|
|
195
|
-
width: dimension.width * devicePixelRatio,
|
|
196
|
-
height: dimension.height * devicePixelRatio,
|
|
197
|
-
};
|
|
198
|
-
|
|
199
213
|
return {
|
|
200
214
|
device_info: deviceData,
|
|
201
|
-
window_info:
|
|
202
|
-
|
|
203
|
-
|
|
215
|
+
window_info: {
|
|
216
|
+
devicePixelRatio,
|
|
217
|
+
width: dimension.width * devicePixelRatio,
|
|
218
|
+
height: dimension.height * devicePixelRatio,
|
|
219
|
+
},
|
|
220
|
+
time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
221
|
+
language_code: getUserLocale(),
|
|
222
|
+
sdk_type: this.sdkType,
|
|
223
|
+
sdk_version: this.sdkVersion,
|
|
224
|
+
package_name: this._packageName,
|
|
225
|
+
is_production: await this._isProduction()
|
|
204
226
|
};
|
|
205
227
|
}
|
|
206
228
|
|
|
207
229
|
private async _postSDKInitialization(apiKey: string): Promise<void> {
|
|
208
230
|
try {
|
|
209
|
-
const
|
|
210
|
-
headers: {
|
|
211
|
-
'Content-Type': 'application/json',
|
|
212
|
-
'x-api-key': apiKey,
|
|
213
|
-
},
|
|
231
|
+
const res = await axios.post(this.sdkInitializationUrl, {}, {
|
|
232
|
+
headers: { 'x-api-key': apiKey },
|
|
214
233
|
});
|
|
215
|
-
if (
|
|
216
|
-
await this._markSDKAsInitialized();
|
|
217
|
-
} else {
|
|
218
|
-
console.log('Failed to mark SDK as Initialized. Status code:', response.status);
|
|
219
|
-
}
|
|
234
|
+
if (res.status === 200) await this._markSDKAsInitialized();
|
|
220
235
|
} catch (e) {
|
|
221
|
-
console.log('Error
|
|
236
|
+
console.log('Error posting SDK initialization:', e);
|
|
222
237
|
}
|
|
223
238
|
}
|
|
224
239
|
|
|
225
|
-
private async _postSystemInfo(data: any, apiKey: string)
|
|
226
|
-
let output: GoMarketMeAffiliateMarketingData | null = null;
|
|
240
|
+
private async _postSystemInfo(data: any, apiKey: string) {
|
|
227
241
|
try {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
data['package_name'] = this._packageName;
|
|
231
|
-
const response = await axios.post(this.systemInfoUrl, data, {
|
|
232
|
-
headers: {
|
|
233
|
-
'Content-Type': 'application/json',
|
|
234
|
-
'x-api-key': apiKey,
|
|
235
|
-
},
|
|
242
|
+
const res = await axios.post(this.systemInfoUrl, data, {
|
|
243
|
+
headers: { 'x-api-key': apiKey },
|
|
236
244
|
});
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
if (
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
} else {
|
|
243
|
-
console.log('Failed to send system info. Status code:', response.status);
|
|
245
|
+
if (res.status === 200) {
|
|
246
|
+
const obj = GoMarketMeAffiliateMarketingData.fromJson(res.data);
|
|
247
|
+
if (obj) this._affiliateCampaignCode = obj.affiliateCampaignCode;
|
|
248
|
+
return obj;
|
|
244
249
|
}
|
|
245
250
|
} catch (e) {
|
|
246
|
-
console.log('Error
|
|
251
|
+
console.log('Error posting system info:', e);
|
|
247
252
|
}
|
|
248
|
-
return
|
|
253
|
+
return null;
|
|
249
254
|
}
|
|
250
255
|
|
|
251
|
-
private async _readAndroidDeviceInfo()
|
|
252
|
-
|
|
253
|
-
let androidId = await DeviceInfo.getAndroidId();
|
|
254
|
-
let uniqueId = await DeviceInfo.getUniqueId();
|
|
255
|
-
let deviceId = await DeviceInfo.getDeviceId(); // model
|
|
256
|
-
let systemName = await DeviceInfo.getSystemName();
|
|
257
|
-
let systemVersion = await DeviceInfo.getSystemVersion()
|
|
258
|
-
let brand = await DeviceInfo.getBrand();
|
|
259
|
-
let model = await DeviceInfo.getModel();
|
|
260
|
-
let manufacturer = await DeviceInfo.getManufacturer();
|
|
261
|
-
let isEmulator = await DeviceInfo.isEmulator();
|
|
262
|
-
|
|
256
|
+
private async _readAndroidDeviceInfo() {
|
|
263
257
|
return {
|
|
264
|
-
deviceId:
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
model: model,
|
|
271
|
-
manufacturer: manufacturer,
|
|
272
|
-
isEmulator: isEmulator
|
|
258
|
+
deviceId: await DeviceInfo.getAndroidId(),
|
|
259
|
+
brand: await DeviceInfo.getBrand(),
|
|
260
|
+
model: await DeviceInfo.getModel(),
|
|
261
|
+
manufacturer: await DeviceInfo.getManufacturer(),
|
|
262
|
+
systemName: await DeviceInfo.getSystemName(),
|
|
263
|
+
systemVersion: await DeviceInfo.getSystemVersion(),
|
|
273
264
|
};
|
|
274
265
|
}
|
|
275
266
|
|
|
276
|
-
private async _readIosDeviceInfo()
|
|
277
|
-
|
|
278
|
-
let uniqueId = await DeviceInfo.getUniqueId();
|
|
279
|
-
let deviceId = await DeviceInfo.getDeviceId(); // model
|
|
280
|
-
let systemName = await DeviceInfo.getSystemName();
|
|
281
|
-
let systemVersion = await DeviceInfo.getSystemVersion()
|
|
282
|
-
let brand = await DeviceInfo.getBrand();
|
|
283
|
-
let model = await DeviceInfo.getModel();
|
|
284
|
-
let manufacturer = await DeviceInfo.getManufacturer();
|
|
285
|
-
let isEmulator = await DeviceInfo.isEmulator();
|
|
286
|
-
|
|
267
|
+
private async _readIosDeviceInfo() {
|
|
287
268
|
return {
|
|
288
|
-
deviceId:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
manufacturer: manufacturer,
|
|
295
|
-
isEmulator: isEmulator
|
|
269
|
+
deviceId: await DeviceInfo.getUniqueId(),
|
|
270
|
+
brand: await DeviceInfo.getBrand(),
|
|
271
|
+
model: await DeviceInfo.getModel(),
|
|
272
|
+
manufacturer: await DeviceInfo.getManufacturer(),
|
|
273
|
+
systemName: await DeviceInfo.getSystemName(),
|
|
274
|
+
systemVersion: await DeviceInfo.getSystemVersion(),
|
|
296
275
|
};
|
|
297
276
|
}
|
|
298
277
|
|
|
299
|
-
private
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (products.length > 0) {
|
|
315
|
-
for (const product0 of products) {
|
|
316
|
-
data['products'].push(this._serializeProductDetails(product0))
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
const products = await RNIap.getSubscriptions({ skus: [data.productID] });
|
|
321
|
-
if (products.length > 0) {
|
|
322
|
-
for (const product0 of products) {
|
|
323
|
-
data['products'].push(this._serializeSubscriptionDetails(product0))
|
|
324
|
-
}
|
|
278
|
+
private async _fetchConsolidatedPurchases(purchases: Purchase[], apiKey: string) {
|
|
279
|
+
for (const purchase of purchases) {
|
|
280
|
+
const receipt = purchase.purchaseToken;
|
|
281
|
+
if (!receipt) continue;
|
|
282
|
+
|
|
283
|
+
const data: any = this._serializePurchaseDetails(purchase);
|
|
284
|
+
data.products = [];
|
|
285
|
+
|
|
286
|
+
const pid = data.productID || '';
|
|
287
|
+
if (pid) {
|
|
288
|
+
try {
|
|
289
|
+
const products = await fetchProducts({ skus: [pid] });
|
|
290
|
+
if (products && products.length) {
|
|
291
|
+
for (const p of products) {
|
|
292
|
+
data.products.push(this._serializeProductDetails(p));
|
|
325
293
|
}
|
|
326
294
|
}
|
|
295
|
+
} catch (e) {
|
|
296
|
+
console.warn('Error fetching products:', e);
|
|
327
297
|
}
|
|
328
|
-
await this._sendEventToServer(JSON.stringify(data), 'purchase', apiKey);
|
|
329
298
|
}
|
|
299
|
+
|
|
300
|
+
await this._sendEventToServer(JSON.stringify(data), 'purchase_product', apiKey);
|
|
330
301
|
}
|
|
331
302
|
}
|
|
332
303
|
|
|
333
|
-
private async _sendEventToServer(body: string, eventType: string, apiKey: string)
|
|
304
|
+
private async _sendEventToServer(body: string, eventType: string, apiKey: string) {
|
|
334
305
|
try {
|
|
335
|
-
|
|
306
|
+
await axios.post(this.eventUrl, body, {
|
|
336
307
|
headers: {
|
|
337
|
-
'Content-Type': 'application/json',
|
|
338
308
|
'x-affiliate-campaign-code': this._affiliateCampaignCode,
|
|
339
309
|
'x-device-id': this._deviceId,
|
|
340
310
|
'x-event-type': eventType,
|
|
@@ -343,99 +313,78 @@ class GoMarketMe {
|
|
|
343
313
|
'x-api-key': apiKey,
|
|
344
314
|
},
|
|
345
315
|
});
|
|
346
|
-
|
|
347
|
-
console.log(`${eventType} sent successfully`);
|
|
348
|
-
} else {
|
|
349
|
-
console.log(`Failed to send ${eventType}. Status code:`, response.status);
|
|
350
|
-
}
|
|
316
|
+
console.log(`${eventType} sent successfully`);
|
|
351
317
|
} catch (e) {
|
|
352
|
-
console.log(`Error sending ${eventType}
|
|
318
|
+
console.log(`Error sending ${eventType}:`, e);
|
|
353
319
|
}
|
|
354
320
|
}
|
|
355
321
|
|
|
356
|
-
private _serializePurchaseDetails(purchase:
|
|
322
|
+
private _serializePurchaseDetails(purchase: PurchaseCommon) {
|
|
357
323
|
return {
|
|
358
324
|
packageName: this._packageName,
|
|
359
325
|
productID: purchase.productId,
|
|
360
|
-
purchaseID: purchase.
|
|
361
|
-
transactionDate: purchase.transactionDate
|
|
362
|
-
status: Platform.select({
|
|
363
|
-
ios: (purchase as any).transactionStateIOS, // Removed non-existent properties
|
|
364
|
-
android: (purchase as any).purchaseStateAndroid,
|
|
365
|
-
}),
|
|
326
|
+
purchaseID: purchase.id,
|
|
327
|
+
transactionDate: purchase.transactionDate,
|
|
366
328
|
verificationData: {
|
|
367
|
-
localVerificationData: purchase.
|
|
368
|
-
serverVerificationData: purchase.transactionReceipt,
|
|
329
|
+
localVerificationData: purchase.purchaseToken,
|
|
369
330
|
source: Platform.OS === 'android' ? 'google_play' : 'app_store',
|
|
370
331
|
},
|
|
371
|
-
pendingCompletePurchase: '',
|
|
372
|
-
error: {},
|
|
373
|
-
hashCode: '',
|
|
374
|
-
_purchase: purchase
|
|
375
332
|
};
|
|
376
333
|
}
|
|
377
334
|
|
|
378
|
-
private _serializeProductDetails(product:
|
|
335
|
+
private _serializeProductDetails(product: ProductCommon) {
|
|
379
336
|
return {
|
|
380
337
|
packageName: this._packageName,
|
|
381
|
-
productID: product.
|
|
338
|
+
productID: product.id,
|
|
382
339
|
productTitle: product.title,
|
|
383
340
|
productDescription: product.description,
|
|
384
|
-
productPrice: product.
|
|
385
|
-
productRawPrice: product.price,
|
|
386
|
-
productCurrencySymbol: product.localizedPrice.replace('product.price', ''),
|
|
341
|
+
productPrice: product.displayPrice,
|
|
342
|
+
productRawPrice: product.price || '',
|
|
387
343
|
productCurrencyCode: product.currency,
|
|
388
|
-
hashCode: '',
|
|
389
|
-
_product: product
|
|
390
344
|
};
|
|
391
345
|
}
|
|
392
346
|
|
|
393
|
-
private
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
productTitle: subscription.title,
|
|
397
|
-
productDescription: subscription.description,
|
|
398
|
-
hashCode: '',
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
if (Platform.OS === 'ios') {
|
|
402
|
-
const subscriptionIOS = subscription as RNIap.SubscriptionIOS;
|
|
403
|
-
output.productPrice = subscriptionIOS.localizedPrice;
|
|
404
|
-
output.productRawPrice = subscriptionIOS.price;
|
|
405
|
-
output.productCurrencyCode = subscriptionIOS.currency;
|
|
406
|
-
output._subscription = subscriptionIOS;
|
|
407
|
-
} else if (Platform.OS === 'android') {
|
|
408
|
-
const subscriptionAndroid = subscription as RNIap.SubscriptionAndroid;
|
|
409
|
-
if (subscriptionAndroid.subscriptionOfferDetails?.length) {
|
|
410
|
-
const offerDetails = subscriptionAndroid.subscriptionOfferDetails[0];
|
|
411
|
-
const priceAmountMicros = parseInt(offerDetails.pricingPhases.pricingPhaseList[0].priceAmountMicros, 10) || 0;
|
|
412
|
-
output.productPrice = offerDetails.pricingPhases.pricingPhaseList[0].formattedPrice;
|
|
413
|
-
output.productRawPrice = String(priceAmountMicros / 1_000_000);
|
|
414
|
-
output.productCurrencyCode = offerDetails.pricingPhases.pricingPhaseList[0].priceCurrencyCode;
|
|
415
|
-
}
|
|
416
|
-
output._subscription = subscriptionAndroid;
|
|
417
|
-
}
|
|
347
|
+
private async _markSDKAsInitialized() {
|
|
348
|
+
await AsyncStorage.setItem(this.sdkInitializedKey, 'true');
|
|
349
|
+
}
|
|
418
350
|
|
|
419
|
-
|
|
351
|
+
private async _isSDKInitialized() {
|
|
352
|
+
const val = await AsyncStorage.getItem(this.sdkInitializedKey);
|
|
353
|
+
return val === 'true';
|
|
420
354
|
}
|
|
421
355
|
|
|
422
|
-
private async
|
|
356
|
+
private async _isProduction(): Promise<boolean> {
|
|
357
|
+
if (__DEV__) return false;
|
|
358
|
+
|
|
423
359
|
try {
|
|
424
|
-
await
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
360
|
+
const installer = await DeviceInfo.getInstallerPackageName();
|
|
361
|
+
|
|
362
|
+
if (
|
|
363
|
+
installer === 'com.android.vending' ||
|
|
364
|
+
installer === 'com.amazon.venezia'
|
|
365
|
+
) {
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (installer == null && !__DEV__) {
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return false;
|
|
374
|
+
} catch (error) {
|
|
375
|
+
console.warn('Error determining production status:', error);
|
|
428
376
|
return false;
|
|
429
377
|
}
|
|
430
378
|
}
|
|
431
379
|
|
|
432
|
-
private async
|
|
380
|
+
private async _fetchExistingPurchases(apiKey: string): Promise<void> {
|
|
433
381
|
try {
|
|
434
|
-
const
|
|
435
|
-
|
|
382
|
+
const purchases = await getAvailablePurchases();
|
|
383
|
+
if (purchases && purchases.length > 0) {
|
|
384
|
+
await this._fetchConsolidatedPurchases(purchases, apiKey);
|
|
385
|
+
}
|
|
436
386
|
} catch (e) {
|
|
437
|
-
console.log('
|
|
438
|
-
return false;
|
|
387
|
+
console.log('Error fetching existing purchases on app open:', e);
|
|
439
388
|
}
|
|
440
389
|
}
|
|
441
390
|
}
|