expo-iap 2.7.14 → 2.8.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 +5 -5
- package/.cursorrules +31 -13
- package/CHANGELOG.md +53 -1
- package/CLAUDE.md +45 -4
- package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +52 -35
- package/build/ExpoIap.types.d.ts +21 -14
- package/build/ExpoIap.types.d.ts.map +1 -1
- package/build/ExpoIap.types.js +0 -1
- package/build/ExpoIap.types.js.map +1 -1
- package/build/helpers/subscription.d.ts.map +1 -1
- package/build/helpers/subscription.js +24 -17
- package/build/helpers/subscription.js.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.js +10 -10
- package/build/index.js.map +1 -1
- package/build/modules/ios.d.ts +10 -23
- package/build/modules/ios.d.ts.map +1 -1
- package/build/modules/ios.js +9 -23
- package/build/modules/ios.js.map +1 -1
- package/build/types/ExpoIapAndroid.types.d.ts +50 -15
- package/build/types/ExpoIapAndroid.types.d.ts.map +1 -1
- package/build/types/ExpoIapAndroid.types.js +11 -6
- package/build/types/ExpoIapAndroid.types.js.map +1 -1
- package/build/types/{ExpoIapIos.types.d.ts → ExpoIapIOS.types.d.ts} +68 -39
- package/build/types/ExpoIapIOS.types.d.ts.map +1 -0
- package/build/types/ExpoIapIOS.types.js +2 -0
- package/build/types/ExpoIapIOS.types.js.map +1 -0
- package/build/{useIap.d.ts → useIAP.d.ts} +2 -2
- package/build/{useIap.d.ts.map → useIAP.d.ts.map} +1 -1
- package/build/{useIap.js → useIAP.js} +7 -6
- package/build/useIAP.js.map +1 -0
- package/bun.lock +677 -61
- package/ios/ExpoIapModule.swift +133 -51
- package/jest.config.js +43 -0
- package/package.json +8 -3
- package/src/ExpoIap.types.ts +44 -29
- package/src/helpers/subscription.ts +27 -20
- package/src/index.ts +13 -13
- package/src/modules/ios.ts +13 -40
- package/src/types/ExpoIapAndroid.types.ts +62 -15
- package/src/types/{ExpoIapIos.types.ts → ExpoIapIOS.types.ts} +73 -39
- package/src/{useIap.ts → useIAP.ts} +7 -6
- package/build/types/ExpoIapIos.types.d.ts.map +0 -1
- package/build/types/ExpoIapIos.types.js +0 -2
- package/build/types/ExpoIapIos.types.js.map +0 -1
- package/build/useIap.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -5,9 +5,9 @@ import {Platform} from 'react-native';
|
|
|
5
5
|
// Internal modules
|
|
6
6
|
import ExpoIapModule from './ExpoIapModule';
|
|
7
7
|
import {
|
|
8
|
-
|
|
8
|
+
isProductIOS,
|
|
9
9
|
validateReceiptIOS,
|
|
10
|
-
|
|
10
|
+
deepLinkToSubscriptionsIOS,
|
|
11
11
|
} from './modules/ios';
|
|
12
12
|
import {
|
|
13
13
|
isProductAndroid,
|
|
@@ -28,13 +28,13 @@ import {
|
|
|
28
28
|
SubscriptionPurchase,
|
|
29
29
|
} from './ExpoIap.types';
|
|
30
30
|
import {ProductPurchaseAndroid} from './types/ExpoIapAndroid.types';
|
|
31
|
-
import {PaymentDiscount} from './types/
|
|
31
|
+
import {PaymentDiscount} from './types/ExpoIapIOS.types';
|
|
32
32
|
|
|
33
33
|
// Export all types
|
|
34
34
|
export * from './ExpoIap.types';
|
|
35
35
|
export * from './modules/android';
|
|
36
36
|
export * from './modules/ios';
|
|
37
|
-
export type {AppTransactionIOS} from './types/
|
|
37
|
+
export type {AppTransactionIOS} from './types/ExpoIapIOS.types';
|
|
38
38
|
|
|
39
39
|
// Export subscription helpers
|
|
40
40
|
export {
|
|
@@ -135,7 +135,7 @@ export const getProducts = async (skus: string[]): Promise<Product[]> => {
|
|
|
135
135
|
ios: async () => {
|
|
136
136
|
const rawItems = await ExpoIapModule.getItems(skus);
|
|
137
137
|
return rawItems.filter((item: unknown) => {
|
|
138
|
-
if (!
|
|
138
|
+
if (!isProductIOS(item)) return false;
|
|
139
139
|
return (
|
|
140
140
|
typeof item === 'object' &&
|
|
141
141
|
item !== null &&
|
|
@@ -169,7 +169,7 @@ export const getSubscriptions = async (
|
|
|
169
169
|
ios: async () => {
|
|
170
170
|
const rawItems = await ExpoIapModule.getItems(skus);
|
|
171
171
|
return rawItems.filter((item: unknown) => {
|
|
172
|
-
if (!
|
|
172
|
+
if (!isProductIOS(item)) return false;
|
|
173
173
|
return (
|
|
174
174
|
typeof item === 'object' &&
|
|
175
175
|
item !== null &&
|
|
@@ -236,7 +236,7 @@ export const requestProducts = async ({
|
|
|
236
236
|
if (Platform.OS === 'ios') {
|
|
237
237
|
const rawItems = await ExpoIapModule.getItems(skus);
|
|
238
238
|
const filteredItems = rawItems.filter((item: unknown) => {
|
|
239
|
-
if (!
|
|
239
|
+
if (!isProductIOS(item)) return false;
|
|
240
240
|
return (
|
|
241
241
|
typeof item === 'object' &&
|
|
242
242
|
item !== null &&
|
|
@@ -341,7 +341,7 @@ export const getAvailablePurchases = ({
|
|
|
341
341
|
}) || (() => Promise.resolve([]))
|
|
342
342
|
)();
|
|
343
343
|
|
|
344
|
-
const
|
|
344
|
+
const offerToRecordIOS = (
|
|
345
345
|
offer: PaymentDiscount | undefined,
|
|
346
346
|
): Record<keyof PaymentDiscount, string> | undefined => {
|
|
347
347
|
if (!offer) return undefined;
|
|
@@ -429,17 +429,17 @@ export const requestPurchase = (
|
|
|
429
429
|
|
|
430
430
|
const {
|
|
431
431
|
sku,
|
|
432
|
-
|
|
432
|
+
andDangerouslyFinishTransactionAutomatically = false,
|
|
433
433
|
appAccountToken,
|
|
434
434
|
quantity,
|
|
435
435
|
withOffer,
|
|
436
436
|
} = normalizedRequest;
|
|
437
437
|
|
|
438
438
|
return (async () => {
|
|
439
|
-
const offer =
|
|
439
|
+
const offer = offerToRecordIOS(withOffer);
|
|
440
440
|
const purchase = await ExpoIapModule.buyProduct(
|
|
441
441
|
sku,
|
|
442
|
-
|
|
442
|
+
andDangerouslyFinishTransactionAutomatically,
|
|
443
443
|
appAccountToken,
|
|
444
444
|
quantity ?? -1,
|
|
445
445
|
offer,
|
|
@@ -683,7 +683,7 @@ export const deepLinkToSubscriptions = (options: {
|
|
|
683
683
|
packageNameAndroid?: string;
|
|
684
684
|
}): Promise<void> => {
|
|
685
685
|
if (Platform.OS === 'ios') {
|
|
686
|
-
return
|
|
686
|
+
return deepLinkToSubscriptionsIOS();
|
|
687
687
|
}
|
|
688
688
|
|
|
689
689
|
if (Platform.OS === 'android') {
|
|
@@ -710,5 +710,5 @@ export const deepLinkToSubscriptions = (options: {
|
|
|
710
710
|
return Promise.reject(new Error(`Unsupported platform: ${Platform.OS}`));
|
|
711
711
|
};
|
|
712
712
|
|
|
713
|
-
export * from './
|
|
713
|
+
export * from './useIAP';
|
|
714
714
|
export * from './utils/errorMapping';
|
package/src/modules/ios.ts
CHANGED
|
@@ -12,9 +12,9 @@ import {
|
|
|
12
12
|
SubscriptionPurchase,
|
|
13
13
|
} from '../ExpoIap.types';
|
|
14
14
|
import type {
|
|
15
|
-
|
|
15
|
+
ProductStatusIOS,
|
|
16
16
|
AppTransactionIOS,
|
|
17
|
-
} from '../types/
|
|
17
|
+
} from '../types/ExpoIapIOS.types';
|
|
18
18
|
import {Linking} from 'react-native';
|
|
19
19
|
|
|
20
20
|
export type TransactionEvent = {
|
|
@@ -36,7 +36,7 @@ export type TransactionEvent = {
|
|
|
36
36
|
* // Use:
|
|
37
37
|
* // purchaseUpdatedListener((purchase) => { ... });
|
|
38
38
|
*/
|
|
39
|
-
export const
|
|
39
|
+
export const transactionUpdatedIOS = (
|
|
40
40
|
listener: (event: TransactionEvent) => void,
|
|
41
41
|
) => {
|
|
42
42
|
const isProductPurchase = (item: unknown): item is ProductPurchase => {
|
|
@@ -74,7 +74,7 @@ export const transactionUpdatedIos = (
|
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
// Type guards
|
|
77
|
-
export function
|
|
77
|
+
export function isProductIOS<T extends {platform?: string}>(
|
|
78
78
|
item: unknown,
|
|
79
79
|
): item is T & {platform: 'ios'} {
|
|
80
80
|
return (
|
|
@@ -102,16 +102,16 @@ export const syncIOS = (): Promise<null> => {
|
|
|
102
102
|
/**
|
|
103
103
|
* Check if user is eligible for introductory offer
|
|
104
104
|
*
|
|
105
|
-
* @param
|
|
105
|
+
* @param groupId The subscription group ID
|
|
106
106
|
* @returns Promise resolving to true if eligible
|
|
107
107
|
* @throws Error if called on non-iOS platform
|
|
108
108
|
*
|
|
109
109
|
* @platform iOS
|
|
110
110
|
*/
|
|
111
111
|
export const isEligibleForIntroOfferIOS = (
|
|
112
|
-
|
|
112
|
+
groupId: string,
|
|
113
113
|
): Promise<boolean> => {
|
|
114
|
-
return ExpoIapModule.isEligibleForIntroOffer(
|
|
114
|
+
return ExpoIapModule.isEligibleForIntroOffer(groupId);
|
|
115
115
|
};
|
|
116
116
|
|
|
117
117
|
/**
|
|
@@ -125,7 +125,7 @@ export const isEligibleForIntroOfferIOS = (
|
|
|
125
125
|
*/
|
|
126
126
|
export const subscriptionStatusIOS = (
|
|
127
127
|
sku: string,
|
|
128
|
-
): Promise<
|
|
128
|
+
): Promise<ProductStatusIOS[]> => {
|
|
129
129
|
return ExpoIapModule.subscriptionStatus(sku);
|
|
130
130
|
};
|
|
131
131
|
|
|
@@ -176,7 +176,7 @@ export const beginRefundRequestIOS = (
|
|
|
176
176
|
/**
|
|
177
177
|
* Shows the system UI for managing subscriptions.
|
|
178
178
|
* When the user changes subscription renewal status, the system will emit events to
|
|
179
|
-
* purchaseUpdatedListener and
|
|
179
|
+
* purchaseUpdatedListener and transactionUpdatedIOS listeners.
|
|
180
180
|
*
|
|
181
181
|
* @returns Promise resolving to null on success
|
|
182
182
|
* @throws Error if called on non-iOS platform
|
|
@@ -321,7 +321,7 @@ export const buyPromotedProductIOS = (): Promise<void> => {
|
|
|
321
321
|
*
|
|
322
322
|
* @platform iOS
|
|
323
323
|
*/
|
|
324
|
-
export const
|
|
324
|
+
export const deepLinkToSubscriptionsIOS = (): Promise<void> =>
|
|
325
325
|
Linking.openURL('https://apps.apple.com/account/subscriptions');
|
|
326
326
|
|
|
327
327
|
// ============= DEPRECATED FUNCTIONS =============
|
|
@@ -340,11 +340,11 @@ export const sync = (): Promise<null> => {
|
|
|
340
340
|
/**
|
|
341
341
|
* @deprecated Use `isEligibleForIntroOfferIOS` instead. This function will be removed in version 3.0.0.
|
|
342
342
|
*/
|
|
343
|
-
export const isEligibleForIntroOffer = (
|
|
343
|
+
export const isEligibleForIntroOffer = (groupId: string): Promise<boolean> => {
|
|
344
344
|
console.warn(
|
|
345
345
|
'`isEligibleForIntroOffer` is deprecated. Use `isEligibleForIntroOfferIOS` instead. This function will be removed in version 3.0.0.',
|
|
346
346
|
);
|
|
347
|
-
return isEligibleForIntroOfferIOS(
|
|
347
|
+
return isEligibleForIntroOfferIOS(groupId);
|
|
348
348
|
};
|
|
349
349
|
|
|
350
350
|
/**
|
|
@@ -352,7 +352,7 @@ export const isEligibleForIntroOffer = (groupID: string): Promise<boolean> => {
|
|
|
352
352
|
*/
|
|
353
353
|
export const subscriptionStatus = (
|
|
354
354
|
sku: string,
|
|
355
|
-
): Promise<
|
|
355
|
+
): Promise<ProductStatusIOS[]> => {
|
|
356
356
|
console.warn(
|
|
357
357
|
'`subscriptionStatus` is deprecated. Use `subscriptionStatusIOS` instead. This function will be removed in version 3.0.0.',
|
|
358
358
|
);
|
|
@@ -401,16 +401,6 @@ export const showManageSubscriptions = (): Promise<null> => {
|
|
|
401
401
|
return showManageSubscriptionsIOS();
|
|
402
402
|
};
|
|
403
403
|
|
|
404
|
-
/**
|
|
405
|
-
* @deprecated Use `getReceiptIOS` instead. This function will be removed in version 3.0.0.
|
|
406
|
-
*/
|
|
407
|
-
export const getReceiptIos = (): Promise<string> => {
|
|
408
|
-
console.warn(
|
|
409
|
-
'`getReceiptIos` is deprecated. Use `getReceiptIOS` instead. This function will be removed in version 3.0.0.',
|
|
410
|
-
);
|
|
411
|
-
return getReceiptIOS();
|
|
412
|
-
};
|
|
413
|
-
|
|
414
404
|
/**
|
|
415
405
|
* @deprecated Use `isTransactionVerifiedIOS` instead. This function will be removed in version 3.0.0.
|
|
416
406
|
*/
|
|
@@ -431,23 +421,6 @@ export const getTransactionJws = (sku: string): Promise<string> => {
|
|
|
431
421
|
return getTransactionJwsIOS(sku);
|
|
432
422
|
};
|
|
433
423
|
|
|
434
|
-
/**
|
|
435
|
-
* @deprecated Use `validateReceiptIOS` instead. This function will be removed in version 3.0.0.
|
|
436
|
-
*/
|
|
437
|
-
export const validateReceiptIos = async (
|
|
438
|
-
sku: string,
|
|
439
|
-
): Promise<{
|
|
440
|
-
isValid: boolean;
|
|
441
|
-
receiptData: string;
|
|
442
|
-
jwsRepresentation: string;
|
|
443
|
-
latestTransaction?: ProductPurchase;
|
|
444
|
-
}> => {
|
|
445
|
-
console.warn(
|
|
446
|
-
'`validateReceiptIos` is deprecated. Use `validateReceiptIOS` instead. This function will be removed in version 3.0.0.',
|
|
447
|
-
);
|
|
448
|
-
return validateReceiptIOS(sku);
|
|
449
|
-
};
|
|
450
|
-
|
|
451
424
|
/**
|
|
452
425
|
* @deprecated Use `presentCodeRedemptionSheetIOS` instead. This function will be removed in version 3.0.0.
|
|
453
426
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {PurchaseCommon, ProductCommon} from '../ExpoIap.types';
|
|
2
2
|
|
|
3
|
-
type
|
|
3
|
+
type ProductAndroidOneTimePurchaseOfferDetail = {
|
|
4
4
|
priceCurrencyCode: string;
|
|
5
5
|
formattedPrice: string;
|
|
6
6
|
priceAmountMicros: string;
|
|
@@ -20,21 +20,34 @@ type PricingPhasesAndroid = {
|
|
|
20
20
|
pricingPhaseList: PricingPhaseAndroid[];
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
type
|
|
23
|
+
type ProductSubscriptionAndroidOfferDetail = {
|
|
24
24
|
basePlanId: string;
|
|
25
|
-
offerId: string;
|
|
25
|
+
offerId: string | null;
|
|
26
26
|
offerToken: string;
|
|
27
27
|
offerTags: string[];
|
|
28
28
|
pricingPhases: PricingPhasesAndroid;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
export type ProductAndroid =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
export type ProductAndroid = ProductCommon & {
|
|
32
|
+
nameAndroid: string;
|
|
33
|
+
oneTimePurchaseOfferDetailsAndroid?: ProductAndroidOneTimePurchaseOfferDetail;
|
|
34
|
+
platform: 'android';
|
|
35
|
+
subscriptionOfferDetailsAndroid?: ProductSubscriptionAndroidOfferDetail[];
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Use `nameAndroid` instead. This field will be removed in v2.9.0.
|
|
38
|
+
*/
|
|
39
|
+
name?: string;
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated Use `oneTimePurchaseOfferDetailsAndroid` instead. This field will be removed in v2.9.0.
|
|
42
|
+
*/
|
|
43
|
+
oneTimePurchaseOfferDetails?: ProductAndroidOneTimePurchaseOfferDetail;
|
|
44
|
+
/**
|
|
45
|
+
* @deprecated Use `subscriptionOfferDetailsAndroid` instead. This field will be removed in v2.9.0.
|
|
46
|
+
*/
|
|
47
|
+
subscriptionOfferDetails?: ProductSubscriptionAndroidOfferDetail[];
|
|
35
48
|
};
|
|
36
49
|
|
|
37
|
-
type
|
|
50
|
+
type ProductSubscriptionAndroidOfferDetails = {
|
|
38
51
|
basePlanId: string;
|
|
39
52
|
offerId: string | null;
|
|
40
53
|
offerToken: string;
|
|
@@ -42,10 +55,17 @@ type SubscriptionOfferAndroid = {
|
|
|
42
55
|
offerTags: string[];
|
|
43
56
|
};
|
|
44
57
|
|
|
45
|
-
export type
|
|
46
|
-
|
|
58
|
+
export type ProductSubscriptionAndroid = ProductAndroid & {
|
|
59
|
+
subscriptionOfferDetailsAndroid: ProductSubscriptionAndroidOfferDetails[];
|
|
60
|
+
/**
|
|
61
|
+
* @deprecated Use `subscriptionOfferDetailsAndroid` instead. This field will be removed in v2.9.0.
|
|
62
|
+
*/
|
|
63
|
+
subscriptionOfferDetails?: ProductSubscriptionAndroidOfferDetails[];
|
|
47
64
|
};
|
|
48
65
|
|
|
66
|
+
// Legacy naming for backward compatibility
|
|
67
|
+
export type SubscriptionProductAndroid = ProductSubscriptionAndroid;
|
|
68
|
+
|
|
49
69
|
export type RequestPurchaseAndroidProps = {
|
|
50
70
|
skus: string[];
|
|
51
71
|
obfuscatedAccountIdAndroid?: string;
|
|
@@ -110,14 +130,21 @@ export enum FeatureTypeAndroid {
|
|
|
110
130
|
SUBSCRIPTIONS_UPDATE = 'SUBSCRIPTIONS_UPDATE',
|
|
111
131
|
}
|
|
112
132
|
|
|
113
|
-
export enum
|
|
133
|
+
export enum PurchaseAndroidState {
|
|
114
134
|
UNSPECIFIED_STATE = 0,
|
|
115
135
|
PURCHASED = 1,
|
|
116
136
|
PENDING = 2,
|
|
117
137
|
}
|
|
118
138
|
|
|
119
|
-
|
|
120
|
-
|
|
139
|
+
// Legacy naming for backward compatibility
|
|
140
|
+
/**
|
|
141
|
+
* @deprecated Use `PurchaseAndroidState` instead. This enum will be removed in v2.9.0.
|
|
142
|
+
*/
|
|
143
|
+
export const PurchaseStateAndroid = PurchaseAndroidState;
|
|
144
|
+
|
|
145
|
+
// Legacy naming for backward compatibility
|
|
146
|
+
export type ProductPurchaseAndroid = PurchaseCommon & {
|
|
147
|
+
platform: 'android';
|
|
121
148
|
/**
|
|
122
149
|
* @deprecated Use `purchaseToken` instead. This field will be removed in a future version.
|
|
123
150
|
*/
|
|
@@ -125,10 +152,30 @@ export type ProductPurchaseAndroid = PurchaseBase & {
|
|
|
125
152
|
dataAndroid?: string;
|
|
126
153
|
signatureAndroid?: string;
|
|
127
154
|
autoRenewingAndroid?: boolean;
|
|
128
|
-
purchaseStateAndroid?:
|
|
155
|
+
purchaseStateAndroid?: PurchaseAndroidState;
|
|
129
156
|
isAcknowledgedAndroid?: boolean;
|
|
130
157
|
packageNameAndroid?: string;
|
|
131
158
|
developerPayloadAndroid?: string;
|
|
132
159
|
obfuscatedAccountIdAndroid?: string;
|
|
133
160
|
obfuscatedProfileIdAndroid?: string;
|
|
134
161
|
};
|
|
162
|
+
|
|
163
|
+
// Preferred naming
|
|
164
|
+
export type PurchaseAndroid = ProductPurchaseAndroid;
|
|
165
|
+
|
|
166
|
+
// Legacy type aliases for backward compatibility
|
|
167
|
+
/**
|
|
168
|
+
* @deprecated Use `ProductAndroidOneTimePurchaseOfferDetail` instead. This type will be removed in v2.9.0.
|
|
169
|
+
*/
|
|
170
|
+
export type OneTimePurchaseOfferDetails =
|
|
171
|
+
ProductAndroidOneTimePurchaseOfferDetail;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @deprecated Use `ProductSubscriptionAndroidOfferDetail` instead. This type will be removed in v2.9.0.
|
|
175
|
+
*/
|
|
176
|
+
export type SubscriptionOfferDetail = ProductSubscriptionAndroidOfferDetail;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @deprecated Use `ProductSubscriptionAndroidOfferDetails` instead. This type will be removed in v2.9.0.
|
|
180
|
+
*/
|
|
181
|
+
export type SubscriptionOfferAndroid = ProductSubscriptionAndroidOfferDetails;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {PurchaseCommon, ProductCommon} from '../ExpoIap.types';
|
|
2
2
|
|
|
3
3
|
type SubscriptionIosPeriod = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR' | '';
|
|
4
4
|
type PaymentMode = '' | 'FREETRIAL' | 'PAYASYOUGO' | 'PAYUPFRONT';
|
|
@@ -19,17 +19,34 @@ type SubscriptionOffer = {
|
|
|
19
19
|
type SubscriptionInfo = {
|
|
20
20
|
introductoryOffer?: SubscriptionOffer;
|
|
21
21
|
promotionalOffers?: SubscriptionOffer[];
|
|
22
|
-
|
|
22
|
+
subscriptionGroupId: string;
|
|
23
23
|
subscriptionPeriod: {
|
|
24
24
|
unit: SubscriptionIosPeriod;
|
|
25
25
|
value: number;
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export type
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
export type ProductIOS = ProductCommon & {
|
|
30
|
+
displayNameIOS: string;
|
|
31
|
+
isFamilyShareableIOS: boolean;
|
|
32
|
+
jsonRepresentationIOS: string;
|
|
33
|
+
platform: 'ios';
|
|
34
|
+
subscriptionInfoIOS?: SubscriptionInfo;
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated Use `displayNameIOS` instead. This field will be removed in v2.9.0.
|
|
37
|
+
*/
|
|
38
|
+
displayName?: string;
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated Use `isFamilyShareableIOS` instead. This field will be removed in v2.9.0.
|
|
41
|
+
*/
|
|
42
|
+
isFamilyShareable?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated Use `jsonRepresentationIOS` instead. This field will be removed in v2.9.0.
|
|
45
|
+
*/
|
|
46
|
+
jsonRepresentation?: string;
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated Use `subscriptionInfoIOS` instead. This field will be removed in v2.9.0.
|
|
49
|
+
*/
|
|
33
50
|
subscription?: SubscriptionInfo;
|
|
34
51
|
introductoryPriceNumberOfPeriodsIOS?: string;
|
|
35
52
|
introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;
|
|
@@ -45,17 +62,29 @@ export type Discount = {
|
|
|
45
62
|
subscriptionPeriod: string;
|
|
46
63
|
};
|
|
47
64
|
|
|
48
|
-
export type
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
export type ProductSubscriptionIOS = ProductIOS & {
|
|
66
|
+
discountsIOS?: Discount[];
|
|
67
|
+
introductoryPriceIOS?: string;
|
|
51
68
|
introductoryPriceAsAmountIOS?: string;
|
|
52
69
|
introductoryPricePaymentModeIOS?: PaymentMode;
|
|
53
70
|
introductoryPriceNumberOfPeriodsIOS?: string;
|
|
54
71
|
introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;
|
|
72
|
+
platform: 'ios';
|
|
55
73
|
subscriptionPeriodNumberIOS?: string;
|
|
56
74
|
subscriptionPeriodUnitIOS?: SubscriptionIosPeriod;
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated Use `discountsIOS` instead. This field will be removed in v2.9.0.
|
|
77
|
+
*/
|
|
78
|
+
discounts?: Discount[];
|
|
79
|
+
/**
|
|
80
|
+
* @deprecated Use `introductoryPriceIOS` instead. This field will be removed in v2.9.0.
|
|
81
|
+
*/
|
|
82
|
+
introductoryPrice?: string;
|
|
57
83
|
};
|
|
58
84
|
|
|
85
|
+
// Legacy naming for backward compatibility
|
|
86
|
+
export type SubscriptionProductIOS = ProductSubscriptionIOS;
|
|
87
|
+
|
|
59
88
|
export type PaymentDiscount = {
|
|
60
89
|
/**
|
|
61
90
|
* A string used to uniquely identify a discount offer for a product.
|
|
@@ -81,7 +110,7 @@ export type PaymentDiscount = {
|
|
|
81
110
|
|
|
82
111
|
export type RequestPurchaseIosProps = {
|
|
83
112
|
sku: string;
|
|
84
|
-
|
|
113
|
+
andDangerouslyFinishTransactionAutomatically?: boolean;
|
|
85
114
|
/**
|
|
86
115
|
* UUID representing user account
|
|
87
116
|
*/
|
|
@@ -90,8 +119,6 @@ export type RequestPurchaseIosProps = {
|
|
|
90
119
|
withOffer?: PaymentDiscount;
|
|
91
120
|
};
|
|
92
121
|
|
|
93
|
-
export type RequestSubscriptionIosProps = RequestPurchaseIosProps;
|
|
94
|
-
|
|
95
122
|
type SubscriptionStatus =
|
|
96
123
|
| 'expired'
|
|
97
124
|
| 'inBillingRetryPeriod'
|
|
@@ -105,50 +132,57 @@ type RenewalInfo = {
|
|
|
105
132
|
autoRenewPreference?: string;
|
|
106
133
|
};
|
|
107
134
|
|
|
108
|
-
export type
|
|
135
|
+
export type ProductStatusIOS = {
|
|
109
136
|
state: SubscriptionStatus;
|
|
110
137
|
renewalInfo?: RenewalInfo;
|
|
111
138
|
};
|
|
112
139
|
|
|
113
|
-
|
|
140
|
+
// Legacy naming for backward compatibility
|
|
141
|
+
export type ProductPurchaseIOS = PurchaseCommon & {
|
|
114
142
|
// iOS basic fields
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
143
|
+
platform: 'ios';
|
|
144
|
+
quantityIOS?: number;
|
|
145
|
+
originalTransactionDateIOS?: number;
|
|
146
|
+
originalTransactionIdentifierIOS?: string;
|
|
118
147
|
appAccountToken?: string;
|
|
119
148
|
// iOS additional fields from StoreKit 2
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
149
|
+
expirationDateIOS?: number;
|
|
150
|
+
webOrderLineItemIdIOS?: number;
|
|
151
|
+
environmentIOS?: string;
|
|
152
|
+
storefrontCountryCodeIOS?: string;
|
|
153
|
+
appBundleIdIOS?: string;
|
|
154
|
+
productTypeIOS?: string;
|
|
155
|
+
subscriptionGroupIdIOS?: string;
|
|
156
|
+
isUpgradedIOS?: boolean;
|
|
157
|
+
ownershipTypeIOS?: string;
|
|
158
|
+
reasonIOS?: string;
|
|
159
|
+
reasonStringRepresentationIOS?: string;
|
|
160
|
+
transactionReasonIOS?: 'PURCHASE' | 'RENEWAL' | string;
|
|
161
|
+
revocationDateIOS?: number;
|
|
162
|
+
revocationReasonIOS?: string;
|
|
163
|
+
offerIOS?: {
|
|
135
164
|
id: string;
|
|
136
165
|
type: string;
|
|
137
166
|
paymentMode: string;
|
|
138
167
|
};
|
|
139
|
-
|
|
140
|
-
|
|
168
|
+
// Price locale fields
|
|
169
|
+
currencyCodeIOS?: string;
|
|
170
|
+
currencySymbolIOS?: string;
|
|
171
|
+
countryCodeIOS?: string;
|
|
141
172
|
/**
|
|
142
173
|
* @deprecated Use `purchaseToken` instead. This field will be removed in a future version.
|
|
143
174
|
* iOS 15+ JWS representation is now available through the `purchaseToken` field.
|
|
144
175
|
*/
|
|
145
|
-
|
|
176
|
+
jwsRepresentationIOS?: string;
|
|
146
177
|
};
|
|
147
178
|
|
|
179
|
+
// Preferred naming
|
|
180
|
+
export type PurchaseIOS = ProductPurchaseIOS;
|
|
181
|
+
|
|
148
182
|
export type AppTransactionIOS = {
|
|
149
|
-
|
|
183
|
+
appTransactionId?: string; // Only available in iOS 18.4+
|
|
150
184
|
originalPlatform?: string; // Only available in iOS 18.4+
|
|
151
|
-
|
|
185
|
+
bundleId: string;
|
|
152
186
|
appVersion: string;
|
|
153
187
|
originalAppVersion: string;
|
|
154
188
|
originalPurchaseDate: number;
|
|
@@ -156,7 +190,7 @@ export type AppTransactionIOS = {
|
|
|
156
190
|
deviceVerificationNonce: string;
|
|
157
191
|
environment: string;
|
|
158
192
|
signedDate: number;
|
|
159
|
-
|
|
160
|
-
|
|
193
|
+
appId?: number;
|
|
194
|
+
appVersionId?: number;
|
|
161
195
|
preorderDate?: number;
|
|
162
196
|
};
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
getActiveSubscriptions,
|
|
20
20
|
hasActiveSubscriptions,
|
|
21
21
|
type ActiveSubscription,
|
|
22
|
-
} from '
|
|
22
|
+
} from '.';
|
|
23
23
|
import {
|
|
24
24
|
syncIOS,
|
|
25
25
|
getPromotedProductIOS,
|
|
@@ -158,7 +158,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
158
158
|
const subscriptionsRef = useRef<{
|
|
159
159
|
purchaseUpdate?: EventSubscription;
|
|
160
160
|
purchaseError?: EventSubscription;
|
|
161
|
-
|
|
161
|
+
promotedProductsIOS?: EventSubscription;
|
|
162
162
|
promotedProductIOS?: EventSubscription;
|
|
163
163
|
}>({});
|
|
164
164
|
|
|
@@ -260,7 +260,8 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
260
260
|
return result;
|
|
261
261
|
} catch (error) {
|
|
262
262
|
console.error('Error getting active subscriptions:', error);
|
|
263
|
-
|
|
263
|
+
// Don't clear existing activeSubscriptions on error - preserve current state
|
|
264
|
+
// This prevents the UI from showing empty state when there are temporary network issues
|
|
264
265
|
return [];
|
|
265
266
|
}
|
|
266
267
|
},
|
|
@@ -385,7 +386,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
385
386
|
setCurrentPurchaseError(undefined);
|
|
386
387
|
setCurrentPurchase(purchase);
|
|
387
388
|
|
|
388
|
-
if ('
|
|
389
|
+
if ('expirationDateIOS' in purchase) {
|
|
389
390
|
await refreshSubscriptionStatus(purchase.id);
|
|
390
391
|
}
|
|
391
392
|
|
|
@@ -408,7 +409,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
408
409
|
|
|
409
410
|
if (Platform.OS === 'ios') {
|
|
410
411
|
// iOS promoted products listener
|
|
411
|
-
subscriptionsRef.current.
|
|
412
|
+
subscriptionsRef.current.promotedProductsIOS =
|
|
412
413
|
promotedProductListenerIOS((product: Product) => {
|
|
413
414
|
setPromotedProductIOS(product);
|
|
414
415
|
|
|
@@ -427,7 +428,7 @@ export function useIAP(options?: UseIAPOptions): UseIap {
|
|
|
427
428
|
return () => {
|
|
428
429
|
currentSubscriptions.purchaseUpdate?.remove();
|
|
429
430
|
currentSubscriptions.purchaseError?.remove();
|
|
430
|
-
currentSubscriptions.
|
|
431
|
+
currentSubscriptions.promotedProductsIOS?.remove();
|
|
431
432
|
currentSubscriptions.promotedProductIOS?.remove();
|
|
432
433
|
endConnection();
|
|
433
434
|
setConnected(false);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoIapIos.types.d.ts","sourceRoot":"","sources":["../../src/types/ExpoIapIos.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoIapIos.types.js","sourceRoot":"","sources":["../../src/types/ExpoIapIos.types.ts"],"names":[],"mappings":"","sourcesContent":["import {PurchaseBase, ProductBase} from '../ExpoIap.types';\n\ntype SubscriptionIosPeriod = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR' | '';\ntype PaymentMode = '' | 'FREETRIAL' | 'PAYASYOUGO' | 'PAYUPFRONT';\n\ntype SubscriptionOffer = {\n displayPrice: string;\n id: string;\n paymentMode: PaymentMode;\n period: {\n unit: SubscriptionIosPeriod;\n value: number;\n };\n periodCount: number;\n price: number;\n type: 'introductory' | 'promotional';\n};\n\ntype SubscriptionInfo = {\n introductoryOffer?: SubscriptionOffer;\n promotionalOffers?: SubscriptionOffer[];\n subscriptionGroupID: string;\n subscriptionPeriod: {\n unit: SubscriptionIosPeriod;\n value: number;\n };\n};\n\nexport type ProductIos = ProductBase & {\n displayName: string;\n isFamilyShareable: boolean;\n jsonRepresentation: string;\n subscription?: SubscriptionInfo;\n introductoryPriceNumberOfPeriodsIOS?: string;\n introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;\n};\n\nexport type Discount = {\n identifier: string;\n type: string;\n numberOfPeriods: string;\n price: string;\n localizedPrice: string;\n paymentMode: PaymentMode;\n subscriptionPeriod: string;\n};\n\nexport type SubscriptionProductIos = ProductIos & {\n discounts?: Discount[];\n introductoryPrice?: string;\n introductoryPriceAsAmountIOS?: string;\n introductoryPricePaymentModeIOS?: PaymentMode;\n introductoryPriceNumberOfPeriodsIOS?: string;\n introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;\n subscriptionPeriodNumberIOS?: string;\n subscriptionPeriodUnitIOS?: SubscriptionIosPeriod;\n};\n\nexport type PaymentDiscount = {\n /**\n * A string used to uniquely identify a discount offer for a product.\n */\n identifier: string;\n /**\n * A string that identifies the key used to generate the signature.\n */\n keyIdentifier: string;\n /**\n * A universally unique ID (UUID) value that you define.\n */\n nonce: string;\n /**\n * A UTF-8 string representing the properties of a specific discount offer, cryptographically signed.\n */\n signature: string;\n /**\n * The date and time of the signature's creation in milliseconds, formatted in Unix epoch time.\n */\n timestamp: number;\n};\n\nexport type RequestPurchaseIosProps = {\n sku: string;\n andDangerouslyFinishTransactionAutomaticallyIOS?: boolean;\n /**\n * UUID representing user account\n */\n appAccountToken?: string;\n quantity?: number;\n withOffer?: PaymentDiscount;\n};\n\nexport type RequestSubscriptionIosProps = RequestPurchaseIosProps;\n\ntype SubscriptionStatus =\n | 'expired'\n | 'inBillingRetryPeriod'\n | 'inGracePeriod'\n | 'revoked'\n | 'subscribed';\n\ntype RenewalInfo = {\n jsonRepresentation?: string;\n willAutoRenew: boolean;\n autoRenewPreference?: string;\n};\n\nexport type ProductStatusIos = {\n state: SubscriptionStatus;\n renewalInfo?: RenewalInfo;\n};\n\nexport type ProductPurchaseIos = PurchaseBase & {\n // iOS basic fields\n quantityIos?: number;\n originalTransactionDateIos?: number;\n originalTransactionIdentifierIos?: string;\n appAccountToken?: string;\n // iOS additional fields from StoreKit 2\n expirationDateIos?: number;\n webOrderLineItemIdIos?: number;\n environmentIos?: string;\n storefrontCountryCodeIos?: string;\n appBundleIdIos?: string;\n productTypeIos?: string;\n subscriptionGroupIdIos?: string;\n isUpgradedIos?: boolean;\n ownershipTypeIos?: string;\n reasonIos?: string;\n reasonStringRepresentationIos?: string;\n transactionReasonIos?: 'PURCHASE' | 'RENEWAL' | string;\n revocationDateIos?: number;\n revocationReasonIos?: string;\n offerIos?: {\n id: string;\n type: string;\n paymentMode: string;\n };\n priceIos?: number;\n currencyIos?: string;\n /**\n * @deprecated Use `purchaseToken` instead. This field will be removed in a future version.\n * iOS 15+ JWS representation is now available through the `purchaseToken` field.\n */\n jwsRepresentationIos?: string;\n};\n\nexport type AppTransactionIOS = {\n appTransactionID?: string; // Only available in iOS 18.4+\n originalPlatform?: string; // Only available in iOS 18.4+\n bundleID: string;\n appVersion: string;\n originalAppVersion: string;\n originalPurchaseDate: number;\n deviceVerification: string;\n deviceVerificationNonce: string;\n environment: string;\n signedDate: number;\n appID?: number;\n appVersionID?: number;\n preorderDate?: number;\n};\n"]}
|