expo-iap 2.5.4-rc.1 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.copilot-instructions.md +321 -0
- package/.cursorrules +303 -0
- package/CONTRIBUTING.md +378 -0
- package/README.md +10 -0
- package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +22 -0
- package/build/index.d.ts +27 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +40 -3
- package/build/index.js.map +1 -1
- package/build/modules/android.d.ts +8 -0
- package/build/modules/android.d.ts.map +1 -1
- package/build/modules/android.js +12 -0
- package/build/modules/android.js.map +1 -1
- package/build/modules/ios.d.ts +140 -16
- package/build/modules/ios.d.ts.map +1 -1
- package/build/modules/ios.js +220 -19
- package/build/modules/ios.js.map +1 -1
- package/build/types/ExpoIapIos.types.d.ts +8 -1
- package/build/types/ExpoIapIos.types.d.ts.map +1 -1
- package/build/types/ExpoIapIos.types.js.map +1 -1
- package/build/useIap.d.ts.map +1 -1
- package/build/useIap.js +8 -6
- package/build/useIap.js.map +1 -1
- package/codecov.yml +74 -0
- package/ios/ExpoIapModule.swift +35 -3
- package/package.json +5 -6
- package/plugin/tsconfig.tsbuildinfo +1 -1
- package/scripts/test-coverage.sh +15 -0
- package/src/index.ts +59 -5
- package/src/modules/android.ts +17 -1
- package/src/modules/ios.ts +315 -28
- package/src/types/ExpoIapIos.types.ts +9 -1
- package/src/useIap.ts +13 -8
package/src/modules/ios.ts
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
// External dependencies
|
|
1
2
|
import {Platform} from 'react-native';
|
|
3
|
+
|
|
4
|
+
// Internal modules
|
|
2
5
|
import {purchaseUpdatedListener} from '..';
|
|
6
|
+
import ExpoIapModule from '../ExpoIapModule';
|
|
7
|
+
|
|
8
|
+
// Types
|
|
3
9
|
import {
|
|
4
10
|
ProductPurchase,
|
|
5
11
|
PurchaseError,
|
|
6
12
|
Purchase,
|
|
7
13
|
SubscriptionPurchase,
|
|
8
14
|
} from '../ExpoIap.types';
|
|
9
|
-
import type {
|
|
10
|
-
|
|
15
|
+
import type {
|
|
16
|
+
ProductStatusIos,
|
|
17
|
+
AppTransactionIOS,
|
|
18
|
+
} from '../types/ExpoIapIos.types';
|
|
11
19
|
|
|
12
20
|
export type TransactionEvent = {
|
|
13
21
|
transaction?: ProductPurchase;
|
|
@@ -85,49 +93,136 @@ export function isProductIos<T extends {platform?: string}>(
|
|
|
85
93
|
/**
|
|
86
94
|
* Sync state with Appstore (iOS only)
|
|
87
95
|
* https://developer.apple.com/documentation/storekit/appstore/3791906-sync
|
|
96
|
+
*
|
|
97
|
+
* @returns Promise resolving to null on success
|
|
98
|
+
* @throws Error if called on non-iOS platform
|
|
99
|
+
*
|
|
100
|
+
* @platform iOS
|
|
88
101
|
*/
|
|
89
|
-
export const
|
|
102
|
+
export const syncIOS = (): Promise<null> => {
|
|
103
|
+
if (Platform.OS !== 'ios') {
|
|
104
|
+
throw new Error('syncIOS: This method is only available on iOS');
|
|
105
|
+
}
|
|
106
|
+
return ExpoIapModule.sync();
|
|
107
|
+
};
|
|
90
108
|
|
|
91
109
|
/**
|
|
110
|
+
* Check if user is eligible for introductory offer
|
|
111
|
+
*
|
|
112
|
+
* @param groupID The subscription group ID
|
|
113
|
+
* @returns Promise resolving to true if eligible
|
|
114
|
+
* @throws Error if called on non-iOS platform
|
|
92
115
|
*
|
|
116
|
+
* @platform iOS
|
|
93
117
|
*/
|
|
94
|
-
export const
|
|
95
|
-
|
|
118
|
+
export const isEligibleForIntroOfferIOS = (
|
|
119
|
+
groupID: string,
|
|
120
|
+
): Promise<boolean> => {
|
|
121
|
+
if (Platform.OS !== 'ios') {
|
|
122
|
+
throw new Error(
|
|
123
|
+
'isEligibleForIntroOfferIOS: This method is only available on iOS',
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return ExpoIapModule.isEligibleForIntroOffer(groupID);
|
|
127
|
+
};
|
|
96
128
|
|
|
97
129
|
/**
|
|
130
|
+
* Get subscription status for a specific SKU
|
|
131
|
+
*
|
|
132
|
+
* @param sku The product SKU
|
|
133
|
+
* @returns Promise resolving to array of subscription status
|
|
134
|
+
* @throws Error if called on non-iOS platform
|
|
98
135
|
*
|
|
136
|
+
* @platform iOS
|
|
99
137
|
*/
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
138
|
+
export const subscriptionStatusIOS = (
|
|
139
|
+
sku: string,
|
|
140
|
+
): Promise<ProductStatusIos[]> => {
|
|
141
|
+
if (Platform.OS !== 'ios') {
|
|
142
|
+
throw new Error(
|
|
143
|
+
'subscriptionStatusIOS: This method is only available on iOS',
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return ExpoIapModule.subscriptionStatus(sku);
|
|
147
|
+
};
|
|
103
148
|
|
|
104
149
|
/**
|
|
150
|
+
* Get current entitlement for a specific SKU
|
|
151
|
+
*
|
|
152
|
+
* @param sku The product SKU
|
|
153
|
+
* @returns Promise resolving to current entitlement
|
|
154
|
+
* @throws Error if called on non-iOS platform
|
|
105
155
|
*
|
|
156
|
+
* @platform iOS
|
|
106
157
|
*/
|
|
107
|
-
export const
|
|
108
|
-
|
|
158
|
+
export const currentEntitlementIOS = (
|
|
159
|
+
sku: string,
|
|
160
|
+
): Promise<ProductPurchase> => {
|
|
161
|
+
if (Platform.OS !== 'ios') {
|
|
162
|
+
throw new Error(
|
|
163
|
+
'currentEntitlementIOS: This method is only available on iOS',
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
return ExpoIapModule.currentEntitlement(sku);
|
|
167
|
+
};
|
|
109
168
|
|
|
110
169
|
/**
|
|
170
|
+
* Get latest transaction for a specific SKU
|
|
171
|
+
*
|
|
172
|
+
* @param sku The product SKU
|
|
173
|
+
* @returns Promise resolving to latest transaction
|
|
174
|
+
* @throws Error if called on non-iOS platform
|
|
111
175
|
*
|
|
176
|
+
* @platform iOS
|
|
112
177
|
*/
|
|
113
|
-
export const
|
|
114
|
-
|
|
178
|
+
export const latestTransactionIOS = (sku: string): Promise<ProductPurchase> => {
|
|
179
|
+
if (Platform.OS !== 'ios') {
|
|
180
|
+
throw new Error(
|
|
181
|
+
'latestTransactionIOS: This method is only available on iOS',
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return ExpoIapModule.latestTransaction(sku);
|
|
185
|
+
};
|
|
115
186
|
|
|
116
187
|
/**
|
|
188
|
+
* Begin refund request for a specific SKU
|
|
189
|
+
*
|
|
190
|
+
* @param sku The product SKU
|
|
191
|
+
* @returns Promise resolving to refund request status
|
|
192
|
+
* @throws Error if called on non-iOS platform
|
|
117
193
|
*
|
|
194
|
+
* @platform iOS
|
|
118
195
|
*/
|
|
119
196
|
type RefundRequestStatus = 'success' | 'userCancelled';
|
|
120
|
-
export const
|
|
121
|
-
|
|
197
|
+
export const beginRefundRequestIOS = (
|
|
198
|
+
sku: string,
|
|
199
|
+
): Promise<RefundRequestStatus> => {
|
|
200
|
+
if (Platform.OS !== 'ios') {
|
|
201
|
+
throw new Error(
|
|
202
|
+
'beginRefundRequestIOS: This method is only available on iOS',
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
return ExpoIapModule.beginRefundRequest(sku);
|
|
206
|
+
};
|
|
122
207
|
|
|
123
208
|
/**
|
|
124
209
|
* Shows the system UI for managing subscriptions.
|
|
125
210
|
* When the user changes subscription renewal status, the system will emit events to
|
|
126
211
|
* purchaseUpdatedListener and transactionUpdatedIos listeners.
|
|
127
|
-
*
|
|
212
|
+
*
|
|
213
|
+
* @returns Promise resolving to null on success
|
|
214
|
+
* @throws Error if called on non-iOS platform
|
|
215
|
+
*
|
|
216
|
+
* @platform iOS
|
|
128
217
|
*/
|
|
129
|
-
export const
|
|
130
|
-
|
|
218
|
+
export const showManageSubscriptionsIOS = (): Promise<null> => {
|
|
219
|
+
if (Platform.OS !== 'ios') {
|
|
220
|
+
throw new Error(
|
|
221
|
+
'showManageSubscriptionsIOS: This method is only available on iOS',
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
return ExpoIapModule.showManageSubscriptions();
|
|
225
|
+
};
|
|
131
226
|
|
|
132
227
|
/**
|
|
133
228
|
* Get the receipt data from the iOS device.
|
|
@@ -139,7 +234,7 @@ export const showManageSubscriptions = (): Promise<null> =>
|
|
|
139
234
|
*
|
|
140
235
|
* @returns {Promise<string>} Base64 encoded receipt data
|
|
141
236
|
*/
|
|
142
|
-
export const
|
|
237
|
+
export const getReceiptIOS = (): Promise<string> => {
|
|
143
238
|
if (Platform.OS !== 'ios') {
|
|
144
239
|
throw new Error('This method is only available on iOS');
|
|
145
240
|
}
|
|
@@ -150,12 +245,17 @@ export const getReceiptIos = (): Promise<string> => {
|
|
|
150
245
|
* Check if a transaction is verified through StoreKit 2.
|
|
151
246
|
* StoreKit 2 performs local verification of transaction JWS signatures.
|
|
152
247
|
*
|
|
153
|
-
* @param
|
|
154
|
-
* @returns
|
|
248
|
+
* @param sku The product's SKU (on iOS)
|
|
249
|
+
* @returns Promise resolving to true if the transaction is verified
|
|
250
|
+
* @throws Error if called on non-iOS platform
|
|
251
|
+
*
|
|
252
|
+
* @platform iOS
|
|
155
253
|
*/
|
|
156
|
-
export const
|
|
254
|
+
export const isTransactionVerifiedIOS = (sku: string): Promise<boolean> => {
|
|
157
255
|
if (Platform.OS !== 'ios') {
|
|
158
|
-
throw new Error(
|
|
256
|
+
throw new Error(
|
|
257
|
+
'isTransactionVerifiedIOS: This method is only available on iOS',
|
|
258
|
+
);
|
|
159
259
|
}
|
|
160
260
|
return ExpoIapModule.isTransactionVerified(sku);
|
|
161
261
|
};
|
|
@@ -164,12 +264,17 @@ export const isTransactionVerified = (sku: string): Promise<boolean> => {
|
|
|
164
264
|
* Get the JWS representation of a purchase for server-side verification.
|
|
165
265
|
* The JWS (JSON Web Signature) can be verified on your server using Apple's public keys.
|
|
166
266
|
*
|
|
167
|
-
* @param
|
|
168
|
-
* @returns
|
|
267
|
+
* @param sku The product's SKU (on iOS)
|
|
268
|
+
* @returns Promise resolving to JWS representation of the transaction
|
|
269
|
+
* @throws Error if called on non-iOS platform
|
|
270
|
+
*
|
|
271
|
+
* @platform iOS
|
|
169
272
|
*/
|
|
170
|
-
export const
|
|
273
|
+
export const getTransactionJwsIOS = (sku: string): Promise<string> => {
|
|
171
274
|
if (Platform.OS !== 'ios') {
|
|
172
|
-
throw new Error(
|
|
275
|
+
throw new Error(
|
|
276
|
+
'getTransactionJwsIOS: This method is only available on iOS',
|
|
277
|
+
);
|
|
173
278
|
}
|
|
174
279
|
return ExpoIapModule.getTransactionJws(sku);
|
|
175
280
|
};
|
|
@@ -189,7 +294,7 @@ export const getTransactionJws = (sku: string): Promise<string> => {
|
|
|
189
294
|
* latestTransaction?: ProductPurchase;
|
|
190
295
|
* }>}
|
|
191
296
|
*/
|
|
192
|
-
export const
|
|
297
|
+
export const validateReceiptIOS = async (
|
|
193
298
|
sku: string,
|
|
194
299
|
): Promise<{
|
|
195
300
|
isValid: boolean;
|
|
@@ -201,6 +306,188 @@ export const validateReceiptIos = async (
|
|
|
201
306
|
throw new Error('This method is only available on iOS');
|
|
202
307
|
}
|
|
203
308
|
|
|
204
|
-
const result = await ExpoIapModule.
|
|
309
|
+
const result = await ExpoIapModule.validateReceiptIOS(sku);
|
|
205
310
|
return result;
|
|
206
311
|
};
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Present the code redemption sheet for offer codes (iOS only).
|
|
315
|
+
* This allows users to redeem promotional codes for in-app purchases and subscriptions.
|
|
316
|
+
*
|
|
317
|
+
* Note: This only works on real devices, not simulators.
|
|
318
|
+
*
|
|
319
|
+
* @returns Promise resolving to true if the sheet was presented successfully
|
|
320
|
+
* @throws Error if called on non-iOS platform or tvOS
|
|
321
|
+
*
|
|
322
|
+
* @platform iOS
|
|
323
|
+
*/
|
|
324
|
+
export const presentCodeRedemptionSheetIOS = (): Promise<boolean> => {
|
|
325
|
+
if (Platform.OS !== 'ios') {
|
|
326
|
+
throw new Error(
|
|
327
|
+
'presentCodeRedemptionSheetIOS: This method is only available on iOS',
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
return ExpoIapModule.presentCodeRedemptionSheet();
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Get app transaction information (iOS 16.0+).
|
|
335
|
+
* AppTransaction represents the initial purchase that unlocked the app.
|
|
336
|
+
*
|
|
337
|
+
* @returns Promise resolving to the app transaction information or null if not available
|
|
338
|
+
* @throws Error if called on non-iOS platform or iOS version < 16.0
|
|
339
|
+
*
|
|
340
|
+
* @platform iOS
|
|
341
|
+
*/
|
|
342
|
+
export const getAppTransactionIOS = (): Promise<AppTransactionIOS | null> => {
|
|
343
|
+
if (Platform.OS !== 'ios') {
|
|
344
|
+
throw new Error(
|
|
345
|
+
'getAppTransactionIOS: This method is only available on iOS',
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
return ExpoIapModule.getAppTransaction();
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// ============= DEPRECATED FUNCTIONS =============
|
|
352
|
+
// These will be removed in version 3.0.0
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* @deprecated Use `syncIOS` instead. This function will be removed in version 3.0.0.
|
|
356
|
+
*/
|
|
357
|
+
export const sync = (): Promise<null> => {
|
|
358
|
+
console.warn(
|
|
359
|
+
'`sync` is deprecated. Use `syncIOS` instead. This function will be removed in version 3.0.0.',
|
|
360
|
+
);
|
|
361
|
+
return syncIOS();
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* @deprecated Use `isEligibleForIntroOfferIOS` instead. This function will be removed in version 3.0.0.
|
|
366
|
+
*/
|
|
367
|
+
export const isEligibleForIntroOffer = (groupID: string): Promise<boolean> => {
|
|
368
|
+
console.warn(
|
|
369
|
+
'`isEligibleForIntroOffer` is deprecated. Use `isEligibleForIntroOfferIOS` instead. This function will be removed in version 3.0.0.',
|
|
370
|
+
);
|
|
371
|
+
return isEligibleForIntroOfferIOS(groupID);
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @deprecated Use `subscriptionStatusIOS` instead. This function will be removed in version 3.0.0.
|
|
376
|
+
*/
|
|
377
|
+
export const subscriptionStatus = (
|
|
378
|
+
sku: string,
|
|
379
|
+
): Promise<ProductStatusIos[]> => {
|
|
380
|
+
console.warn(
|
|
381
|
+
'`subscriptionStatus` is deprecated. Use `subscriptionStatusIOS` instead. This function will be removed in version 3.0.0.',
|
|
382
|
+
);
|
|
383
|
+
return subscriptionStatusIOS(sku);
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* @deprecated Use `currentEntitlementIOS` instead. This function will be removed in version 3.0.0.
|
|
388
|
+
*/
|
|
389
|
+
export const currentEntitlement = (sku: string): Promise<ProductPurchase> => {
|
|
390
|
+
console.warn(
|
|
391
|
+
'`currentEntitlement` is deprecated. Use `currentEntitlementIOS` instead. This function will be removed in version 3.0.0.',
|
|
392
|
+
);
|
|
393
|
+
return currentEntitlementIOS(sku);
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* @deprecated Use `latestTransactionIOS` instead. This function will be removed in version 3.0.0.
|
|
398
|
+
*/
|
|
399
|
+
export const latestTransaction = (sku: string): Promise<ProductPurchase> => {
|
|
400
|
+
console.warn(
|
|
401
|
+
'`latestTransaction` is deprecated. Use `latestTransactionIOS` instead. This function will be removed in version 3.0.0.',
|
|
402
|
+
);
|
|
403
|
+
return latestTransactionIOS(sku);
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* @deprecated Use `beginRefundRequestIOS` instead. This function will be removed in version 3.0.0.
|
|
408
|
+
*/
|
|
409
|
+
export const beginRefundRequest = (
|
|
410
|
+
sku: string,
|
|
411
|
+
): Promise<RefundRequestStatus> => {
|
|
412
|
+
console.warn(
|
|
413
|
+
'`beginRefundRequest` is deprecated. Use `beginRefundRequestIOS` instead. This function will be removed in version 3.0.0.',
|
|
414
|
+
);
|
|
415
|
+
return beginRefundRequestIOS(sku);
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* @deprecated Use `showManageSubscriptionsIOS` instead. This function will be removed in version 3.0.0.
|
|
420
|
+
*/
|
|
421
|
+
export const showManageSubscriptions = (): Promise<null> => {
|
|
422
|
+
console.warn(
|
|
423
|
+
'`showManageSubscriptions` is deprecated. Use `showManageSubscriptionsIOS` instead. This function will be removed in version 3.0.0.',
|
|
424
|
+
);
|
|
425
|
+
return showManageSubscriptionsIOS();
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* @deprecated Use `getReceiptIOS` instead. This function will be removed in version 3.0.0.
|
|
430
|
+
*/
|
|
431
|
+
export const getReceiptIos = (): Promise<string> => {
|
|
432
|
+
console.warn(
|
|
433
|
+
'`getReceiptIos` is deprecated. Use `getReceiptIOS` instead. This function will be removed in version 3.0.0.',
|
|
434
|
+
);
|
|
435
|
+
return getReceiptIOS();
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* @deprecated Use `isTransactionVerifiedIOS` instead. This function will be removed in version 3.0.0.
|
|
440
|
+
*/
|
|
441
|
+
export const isTransactionVerified = (sku: string): Promise<boolean> => {
|
|
442
|
+
console.warn(
|
|
443
|
+
'`isTransactionVerified` is deprecated. Use `isTransactionVerifiedIOS` instead. This function will be removed in version 3.0.0.',
|
|
444
|
+
);
|
|
445
|
+
return isTransactionVerifiedIOS(sku);
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* @deprecated Use `getTransactionJwsIOS` instead. This function will be removed in version 3.0.0.
|
|
450
|
+
*/
|
|
451
|
+
export const getTransactionJws = (sku: string): Promise<string> => {
|
|
452
|
+
console.warn(
|
|
453
|
+
'`getTransactionJws` is deprecated. Use `getTransactionJwsIOS` instead. This function will be removed in version 3.0.0.',
|
|
454
|
+
);
|
|
455
|
+
return getTransactionJwsIOS(sku);
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* @deprecated Use `validateReceiptIOS` instead. This function will be removed in version 3.0.0.
|
|
460
|
+
*/
|
|
461
|
+
export const validateReceiptIos = async (
|
|
462
|
+
sku: string,
|
|
463
|
+
): Promise<{
|
|
464
|
+
isValid: boolean;
|
|
465
|
+
receiptData: string;
|
|
466
|
+
jwsRepresentation: string;
|
|
467
|
+
latestTransaction?: ProductPurchase;
|
|
468
|
+
}> => {
|
|
469
|
+
console.warn(
|
|
470
|
+
'`validateReceiptIos` is deprecated. Use `validateReceiptIOS` instead. This function will be removed in version 3.0.0.',
|
|
471
|
+
);
|
|
472
|
+
return validateReceiptIOS(sku);
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* @deprecated Use `presentCodeRedemptionSheetIOS` instead. This function will be removed in version 3.0.0.
|
|
477
|
+
*/
|
|
478
|
+
export const presentCodeRedemptionSheet = (): Promise<boolean> => {
|
|
479
|
+
console.warn(
|
|
480
|
+
'`presentCodeRedemptionSheet` is deprecated. Use `presentCodeRedemptionSheetIOS` instead. This function will be removed in version 3.0.0.',
|
|
481
|
+
);
|
|
482
|
+
return presentCodeRedemptionSheetIOS();
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* @deprecated Use `getAppTransactionIOS` instead. This function will be removed in version 3.0.0.
|
|
487
|
+
*/
|
|
488
|
+
export const getAppTransaction = (): Promise<AppTransactionIOS | null> => {
|
|
489
|
+
console.warn(
|
|
490
|
+
'`getAppTransaction` is deprecated. Use `getAppTransactionIOS` instead. This function will be removed in version 3.0.0.',
|
|
491
|
+
);
|
|
492
|
+
return getAppTransactionIOS();
|
|
493
|
+
};
|
|
@@ -30,7 +30,7 @@ export type ProductIos = ProductBase & {
|
|
|
30
30
|
displayName: string;
|
|
31
31
|
isFamilyShareable: boolean;
|
|
32
32
|
jsonRepresentation: string;
|
|
33
|
-
subscription
|
|
33
|
+
subscription?: SubscriptionInfo;
|
|
34
34
|
introductoryPriceNumberOfPeriodsIOS?: string;
|
|
35
35
|
introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;
|
|
36
36
|
};
|
|
@@ -140,3 +140,11 @@ export type ProductPurchaseIos = PurchaseBase & {
|
|
|
140
140
|
currencyIos?: string;
|
|
141
141
|
jwsRepresentationIos?: string;
|
|
142
142
|
};
|
|
143
|
+
|
|
144
|
+
export type AppTransactionIOS = {
|
|
145
|
+
appTransactionID: string;
|
|
146
|
+
originalAppAccountToken?: string;
|
|
147
|
+
originalPurchaseDate: number;
|
|
148
|
+
deviceVerification: string;
|
|
149
|
+
deviceVerificationNonce: string;
|
|
150
|
+
};
|
package/src/useIap.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
// External dependencies
|
|
2
|
+
import {useCallback, useEffect, useState, useRef} from 'react';
|
|
3
|
+
import {Platform} from 'react-native';
|
|
4
|
+
import {EventSubscription} from 'expo-modules-core';
|
|
5
|
+
|
|
6
|
+
// Internal modules
|
|
1
7
|
import {
|
|
2
8
|
endConnection,
|
|
3
9
|
initConnection,
|
|
@@ -5,14 +11,15 @@ import {
|
|
|
5
11
|
purchaseUpdatedListener,
|
|
6
12
|
getProducts,
|
|
7
13
|
getAvailablePurchases,
|
|
8
|
-
|
|
14
|
+
getPurchaseHistories,
|
|
9
15
|
finishTransaction as finishTransactionInternal,
|
|
10
16
|
getSubscriptions,
|
|
11
17
|
requestPurchase as requestPurchaseInternal,
|
|
12
18
|
} from './';
|
|
13
|
-
import {
|
|
19
|
+
import {syncIOS, validateReceiptIOS} from './modules/ios';
|
|
14
20
|
import {validateReceiptAndroid} from './modules/android';
|
|
15
|
-
|
|
21
|
+
|
|
22
|
+
// Types
|
|
16
23
|
import {
|
|
17
24
|
Product,
|
|
18
25
|
ProductPurchase,
|
|
@@ -22,8 +29,6 @@ import {
|
|
|
22
29
|
SubscriptionProduct,
|
|
23
30
|
SubscriptionPurchase,
|
|
24
31
|
} from './ExpoIap.types';
|
|
25
|
-
import {Platform} from 'react-native';
|
|
26
|
-
import {EventSubscription} from 'expo-modules-core';
|
|
27
32
|
|
|
28
33
|
type UseIap = {
|
|
29
34
|
connected: boolean;
|
|
@@ -182,7 +187,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
182
187
|
}, []);
|
|
183
188
|
|
|
184
189
|
const getPurchaseHistoriesInternal = useCallback(async (): Promise<void> => {
|
|
185
|
-
setPurchaseHistories(await
|
|
190
|
+
setPurchaseHistories(await getPurchaseHistories());
|
|
186
191
|
}, []);
|
|
187
192
|
|
|
188
193
|
const finishTransaction = useCallback(
|
|
@@ -248,7 +253,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
248
253
|
const restorePurchases = useCallback(async (): Promise<void> => {
|
|
249
254
|
try {
|
|
250
255
|
if (Platform.OS === 'ios') {
|
|
251
|
-
await
|
|
256
|
+
await syncIOS().catch((error) => {
|
|
252
257
|
if (optionsRef.current?.onSyncError) {
|
|
253
258
|
optionsRef.current.onSyncError(error);
|
|
254
259
|
} else {
|
|
@@ -273,7 +278,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
273
278
|
},
|
|
274
279
|
) => {
|
|
275
280
|
if (Platform.OS === 'ios') {
|
|
276
|
-
return await
|
|
281
|
+
return await validateReceiptIOS(sku);
|
|
277
282
|
} else if (Platform.OS === 'android') {
|
|
278
283
|
if (
|
|
279
284
|
!androidOptions ||
|