expo-iap 2.8.4 → 2.8.6

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/src/index.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  Product,
21
21
  Purchase,
22
22
  PurchaseError,
23
+ ErrorCode,
23
24
  PurchaseResult,
24
25
  RequestSubscriptionProps,
25
26
  RequestPurchaseProps,
@@ -131,7 +132,7 @@ export const getProducts = async (skus: string[]): Promise<Product[]> => {
131
132
 
132
133
  return Platform.select({
133
134
  ios: async () => {
134
- const rawItems = await ExpoIapModule.getItems(skus);
135
+ const rawItems = await ExpoIapModule.requestProducts(skus);
135
136
  return rawItems.filter((item: unknown) => {
136
137
  if (!isProductIOS(item)) return false;
137
138
  return (
@@ -144,7 +145,7 @@ export const getProducts = async (skus: string[]): Promise<Product[]> => {
144
145
  }) as Product[];
145
146
  },
146
147
  android: async () => {
147
- const products = await ExpoIapModule.getItemsByType('inapp', skus);
148
+ const products = await ExpoIapModule.requestProducts('inapp', skus);
148
149
  return products.filter((product: unknown) =>
149
150
  isProductAndroid<Product>(product),
150
151
  );
@@ -165,7 +166,7 @@ export const getSubscriptions = async (
165
166
 
166
167
  return Platform.select({
167
168
  ios: async () => {
168
- const rawItems = await ExpoIapModule.getItems(skus);
169
+ const rawItems = await ExpoIapModule.requestProducts(skus);
169
170
  return rawItems.filter((item: unknown) => {
170
171
  if (!isProductIOS(item)) return false;
171
172
  return (
@@ -178,7 +179,7 @@ export const getSubscriptions = async (
178
179
  }) as SubscriptionProduct[];
179
180
  },
180
181
  android: async () => {
181
- const rawItems = await ExpoIapModule.getItemsByType('subs', skus);
182
+ const rawItems = await ExpoIapModule.requestProducts('subs', skus);
182
183
  return rawItems.filter((item: unknown) => {
183
184
  if (!isProductAndroid(item)) return false;
184
185
  return (
@@ -232,7 +233,7 @@ export const requestProducts = async ({
232
233
  }
233
234
 
234
235
  if (Platform.OS === 'ios') {
235
- const rawItems = await ExpoIapModule.getItems(skus);
236
+ const rawItems = await ExpoIapModule.requestProducts(skus);
236
237
  const filteredItems = rawItems.filter((item: unknown) => {
237
238
  if (!isProductIOS(item)) return false;
238
239
  return (
@@ -250,7 +251,7 @@ export const requestProducts = async ({
250
251
  }
251
252
 
252
253
  if (Platform.OS === 'android') {
253
- const items = await ExpoIapModule.getItemsByType(type, skus);
254
+ const items = await ExpoIapModule.requestProducts(type, skus);
254
255
  const filteredItems = items.filter((item: unknown) => {
255
256
  if (!isProductAndroid(item)) return false;
256
257
  return (
@@ -276,32 +277,51 @@ export const requestProducts = async ({
276
277
  export const getPurchaseHistory = ({
277
278
  alsoPublishToEventListener = false,
278
279
  onlyIncludeActiveItems = false,
280
+ alsoPublishToEventListenerIOS,
281
+ onlyIncludeActiveItemsIOS,
279
282
  }: {
283
+ /** @deprecated Use alsoPublishToEventListenerIOS instead */
280
284
  alsoPublishToEventListener?: boolean;
285
+ /** @deprecated Use onlyIncludeActiveItemsIOS instead */
281
286
  onlyIncludeActiveItems?: boolean;
287
+ alsoPublishToEventListenerIOS?: boolean;
288
+ onlyIncludeActiveItemsIOS?: boolean;
282
289
  } = {}): Promise<Purchase[]> => {
283
290
  console.warn(
284
291
  '`getPurchaseHistory` is deprecated. Use `getPurchaseHistories` instead. This function will be removed in version 3.0.0.',
285
292
  );
286
293
  return getPurchaseHistories({
287
- alsoPublishToEventListener,
288
- onlyIncludeActiveItems,
294
+ alsoPublishToEventListenerIOS:
295
+ alsoPublishToEventListenerIOS ?? alsoPublishToEventListener,
296
+ onlyIncludeActiveItemsIOS:
297
+ onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems,
289
298
  });
290
299
  };
291
300
 
301
+ /**
302
+ * @deprecated Use getAvailablePurchases instead. This function is just calling getAvailablePurchases internally on iOS
303
+ * and returns an empty array on Android (Google Play Billing v8 removed purchase history API).
304
+ * Will be removed in v2.9.0
305
+ */
292
306
  export const getPurchaseHistories = ({
293
307
  alsoPublishToEventListener = false,
294
308
  onlyIncludeActiveItems = false,
309
+ alsoPublishToEventListenerIOS,
310
+ onlyIncludeActiveItemsIOS,
295
311
  }: {
312
+ /** @deprecated Use alsoPublishToEventListenerIOS instead */
296
313
  alsoPublishToEventListener?: boolean;
314
+ /** @deprecated Use onlyIncludeActiveItemsIOS instead */
297
315
  onlyIncludeActiveItems?: boolean;
316
+ alsoPublishToEventListenerIOS?: boolean;
317
+ onlyIncludeActiveItemsIOS?: boolean;
298
318
  } = {}): Promise<Purchase[]> =>
299
319
  (
300
320
  Platform.select({
301
321
  ios: async () => {
302
322
  return ExpoIapModule.getAvailableItems(
303
- alsoPublishToEventListener,
304
- onlyIncludeActiveItems,
323
+ alsoPublishToEventListenerIOS ?? alsoPublishToEventListener,
324
+ onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems,
305
325
  );
306
326
  },
307
327
  android: async () => {
@@ -318,16 +338,22 @@ export const getPurchaseHistories = ({
318
338
  export const getAvailablePurchases = ({
319
339
  alsoPublishToEventListener = false,
320
340
  onlyIncludeActiveItems = true,
341
+ alsoPublishToEventListenerIOS,
342
+ onlyIncludeActiveItemsIOS,
321
343
  }: {
344
+ /** @deprecated Use alsoPublishToEventListenerIOS instead */
322
345
  alsoPublishToEventListener?: boolean;
346
+ /** @deprecated Use onlyIncludeActiveItemsIOS instead */
323
347
  onlyIncludeActiveItems?: boolean;
348
+ alsoPublishToEventListenerIOS?: boolean;
349
+ onlyIncludeActiveItemsIOS?: boolean;
324
350
  } = {}): Promise<Purchase[]> =>
325
351
  (
326
352
  Platform.select({
327
353
  ios: () =>
328
354
  ExpoIapModule.getAvailableItems(
329
- alsoPublishToEventListener,
330
- onlyIncludeActiveItems,
355
+ alsoPublishToEventListenerIOS ?? alsoPublishToEventListener,
356
+ onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems,
331
357
  ),
332
358
  android: async () => {
333
359
  const products = await ExpoIapModule.getAvailableItemsByType('inapp');
@@ -429,7 +455,7 @@ export const requestPurchase = (
429
455
 
430
456
  return (async () => {
431
457
  const offer = offerToRecordIOS(withOffer);
432
- const purchase = await ExpoIapModule.buyProduct(
458
+ const purchase = await ExpoIapModule.requestPurchase(
433
459
  sku,
434
460
  andDangerouslyFinishTransactionAutomatically,
435
461
  appAccountToken,
@@ -459,7 +485,7 @@ export const requestPurchase = (
459
485
  } = normalizedRequest;
460
486
 
461
487
  return (async () => {
462
- return ExpoIapModule.buyItemByType({
488
+ return ExpoIapModule.requestPurchase({
463
489
  type: 'inapp',
464
490
  skuArr: skus,
465
491
  purchaseToken: undefined,
@@ -485,7 +511,7 @@ export const requestPurchase = (
485
511
  } = normalizedRequest;
486
512
 
487
513
  return (async () => {
488
- return ExpoIapModule.buyItemByType({
514
+ return ExpoIapModule.requestPurchase({
489
515
  type: 'subs',
490
516
  skuArr: skus,
491
517
  purchaseToken: purchaseTokenAndroid || purchaseToken,
@@ -566,11 +592,29 @@ export const finishTransaction = ({
566
592
  android: async () => {
567
593
  const androidPurchase = purchase as PurchaseAndroid;
568
594
 
595
+ // Use purchaseToken if available, fallback to purchaseTokenAndroid for backward compatibility
596
+ const token =
597
+ androidPurchase.purchaseToken || androidPurchase.purchaseTokenAndroid;
598
+
599
+ if (!token) {
600
+ return Promise.reject(
601
+ new PurchaseError(
602
+ '[expo-iap]: PurchaseError',
603
+ 'Purchase token is required to finish transaction',
604
+ undefined,
605
+ undefined,
606
+ 'E_DEVELOPER_ERROR' as ErrorCode,
607
+ androidPurchase.productId,
608
+ 'android',
609
+ ),
610
+ );
611
+ }
612
+
569
613
  if (isConsumable) {
570
- return ExpoIapModule.consumeProduct(androidPurchase.purchaseToken);
614
+ return ExpoIapModule.consumeProductAndroid(token);
571
615
  }
572
616
 
573
- return ExpoIapModule.acknowledgePurchase(androidPurchase.purchaseToken);
617
+ return ExpoIapModule.acknowledgePurchaseAndroid(token);
574
618
  },
575
619
  }) || (() => Promise.reject(new Error('Unsupported Platform')))
576
620
  )();
@@ -113,7 +113,7 @@ export const acknowledgePurchaseAndroid = ({
113
113
  }: {
114
114
  token: string;
115
115
  }): Promise<PurchaseResult | boolean | void> => {
116
- return ExpoIapModule.acknowledgePurchase(token);
116
+ return ExpoIapModule.acknowledgePurchaseAndroid(token);
117
117
  };
118
118
 
119
119
  /**
@@ -5,7 +5,7 @@ import {purchaseUpdatedListener} from '..';
5
5
  import ExpoIapModule from '../ExpoIapModule';
6
6
 
7
7
  // Types
8
- import {Purchase, PurchaseError} from '../ExpoIap.types';
8
+ import {Product, Purchase, PurchaseError} from '../ExpoIap.types';
9
9
  import type {
10
10
  ProductStatusIOS,
11
11
  AppTransactionIOS,
@@ -91,7 +91,7 @@ export function isProductIOS<T extends {platform?: string}>(
91
91
  * @platform iOS
92
92
  */
93
93
  export const syncIOS = (): Promise<null> => {
94
- return ExpoIapModule.sync();
94
+ return ExpoIapModule.syncIOS();
95
95
  };
96
96
 
97
97
  /**
@@ -106,7 +106,7 @@ export const syncIOS = (): Promise<null> => {
106
106
  export const isEligibleForIntroOfferIOS = (
107
107
  groupId: string,
108
108
  ): Promise<boolean> => {
109
- return ExpoIapModule.isEligibleForIntroOffer(groupId);
109
+ return ExpoIapModule.isEligibleForIntroOfferIOS(groupId);
110
110
  };
111
111
 
112
112
  /**
@@ -121,7 +121,7 @@ export const isEligibleForIntroOfferIOS = (
121
121
  export const subscriptionStatusIOS = (
122
122
  sku: string,
123
123
  ): Promise<ProductStatusIOS[]> => {
124
- return ExpoIapModule.subscriptionStatus(sku);
124
+ return ExpoIapModule.subscriptionStatusIOS(sku);
125
125
  };
126
126
 
127
127
  /**
@@ -134,7 +134,7 @@ export const subscriptionStatusIOS = (
134
134
  * @platform iOS
135
135
  */
136
136
  export const currentEntitlementIOS = (sku: string): Promise<Purchase> => {
137
- return ExpoIapModule.currentEntitlement(sku);
137
+ return ExpoIapModule.currentEntitlementIOS(sku);
138
138
  };
139
139
 
140
140
  /**
@@ -147,7 +147,7 @@ export const currentEntitlementIOS = (sku: string): Promise<Purchase> => {
147
147
  * @platform iOS
148
148
  */
149
149
  export const latestTransactionIOS = (sku: string): Promise<Purchase> => {
150
- return ExpoIapModule.latestTransaction(sku);
150
+ return ExpoIapModule.latestTransactionIOS(sku);
151
151
  };
152
152
 
153
153
  /**
@@ -163,7 +163,7 @@ type RefundRequestStatus = 'success' | 'userCancelled';
163
163
  export const beginRefundRequestIOS = (
164
164
  sku: string,
165
165
  ): Promise<RefundRequestStatus> => {
166
- return ExpoIapModule.beginRefundRequest(sku);
166
+ return ExpoIapModule.beginRefundRequestIOS(sku);
167
167
  };
168
168
 
169
169
  /**
@@ -177,7 +177,7 @@ export const beginRefundRequestIOS = (
177
177
  * @platform iOS
178
178
  */
179
179
  export const showManageSubscriptionsIOS = (): Promise<null> => {
180
- return ExpoIapModule.showManageSubscriptions();
180
+ return ExpoIapModule.showManageSubscriptionsIOS();
181
181
  };
182
182
 
183
183
  /**
@@ -191,7 +191,7 @@ export const showManageSubscriptionsIOS = (): Promise<null> => {
191
191
  * @returns {Promise<string>} Base64 encoded receipt data
192
192
  */
193
193
  export const getReceiptIOS = (): Promise<string> => {
194
- return ExpoIapModule.getReceiptData();
194
+ return ExpoIapModule.getReceiptDataIOS();
195
195
  };
196
196
 
197
197
  /**
@@ -205,7 +205,7 @@ export const getReceiptIOS = (): Promise<string> => {
205
205
  * @platform iOS
206
206
  */
207
207
  export const isTransactionVerifiedIOS = (sku: string): Promise<boolean> => {
208
- return ExpoIapModule.isTransactionVerified(sku);
208
+ return ExpoIapModule.isTransactionVerifiedIOS(sku);
209
209
  };
210
210
 
211
211
  /**
@@ -219,7 +219,7 @@ export const isTransactionVerifiedIOS = (sku: string): Promise<boolean> => {
219
219
  * @platform iOS
220
220
  */
221
221
  export const getTransactionJwsIOS = (sku: string): Promise<string> => {
222
- return ExpoIapModule.getTransactionJws(sku);
222
+ return ExpoIapModule.getTransactionJwsIOS(sku);
223
223
  };
224
224
 
225
225
  /**
@@ -261,7 +261,7 @@ export const validateReceiptIOS = async (
261
261
  * @platform iOS
262
262
  */
263
263
  export const presentCodeRedemptionSheetIOS = (): Promise<boolean> => {
264
- return ExpoIapModule.presentCodeRedemptionSheet();
264
+ return ExpoIapModule.presentCodeRedemptionSheetIOS();
265
265
  };
266
266
 
267
267
  /**
@@ -279,20 +279,21 @@ export const presentCodeRedemptionSheetIOS = (): Promise<boolean> => {
279
279
  * @since iOS 16.0
280
280
  */
281
281
  export const getAppTransactionIOS = (): Promise<AppTransactionIOS | null> => {
282
- return ExpoIapModule.getAppTransaction();
282
+ return ExpoIapModule.getAppTransactionIOS();
283
283
  };
284
284
 
285
285
  /**
286
- * Get the promoted product details (iOS only).
286
+ * Get information about a promoted product if one is available (iOS only).
287
+ * Promoted products are products that the App Store promotes on your behalf.
287
288
  * This is called after a promoted product event is received from the App Store.
288
289
  *
289
- * @returns Promise resolving to the promoted product details or null if none available
290
+ * @returns Promise resolving to the promoted product information or null if none available
290
291
  * @throws Error if called on non-iOS platform
291
292
  *
292
293
  * @platform iOS
293
294
  */
294
- export const getPromotedProductIOS = (): Promise<any | null> => {
295
- return ExpoIapModule.getPromotedProduct();
295
+ export const getPromotedProductIOS = (): Promise<Product | null> => {
296
+ return ExpoIapModule.getPromotedProductIOS();
296
297
  };
297
298
 
298
299
  /**
@@ -304,8 +305,35 @@ export const getPromotedProductIOS = (): Promise<any | null> => {
304
305
  *
305
306
  * @platform iOS
306
307
  */
308
+ export const requestPurchaseOnPromotedProductIOS = (): Promise<void> => {
309
+ return ExpoIapModule.requestPurchaseOnPromotedProductIOS();
310
+ };
311
+
312
+ /**
313
+ * @deprecated Use requestPurchaseOnPromotedProductIOS instead. Will be removed in v2.9.0
314
+ */
307
315
  export const buyPromotedProductIOS = (): Promise<void> => {
308
- return ExpoIapModule.buyPromotedProduct();
316
+ return requestPurchaseOnPromotedProductIOS();
317
+ };
318
+
319
+ /**
320
+ * Get pending transactions that haven't been finished yet (iOS only).
321
+ *
322
+ * @returns Promise resolving to array of pending transactions
323
+ * @platform iOS
324
+ */
325
+ export const getPendingTransactionsIOS = (): Promise<any[]> => {
326
+ return ExpoIapModule.getPendingTransactionsIOS();
327
+ };
328
+
329
+ /**
330
+ * Clear a specific transaction (iOS only).
331
+ *
332
+ * @returns Promise resolving when transaction is cleared
333
+ * @platform iOS
334
+ */
335
+ export const clearTransactionIOS = (): Promise<void> => {
336
+ return ExpoIapModule.clearTransactionIOS();
309
337
  };
310
338
 
311
339
  /**
package/src/useIAP.ts CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  import {
24
24
  syncIOS,
25
25
  getPromotedProductIOS,
26
- buyPromotedProductIOS,
26
+ requestPurchaseOnPromotedProductIOS,
27
27
  } from './modules/ios';
28
28
 
29
29
  // Types
@@ -87,8 +87,10 @@ type UseIap = {
87
87
  isSub?: boolean;
88
88
  },
89
89
  ) => Promise<any>;
90
- restorePurchases: () => Promise<void>; // 구매 복원 함수 추가
91
- getPromotedProductIOS: () => Promise<any | null>;
90
+ restorePurchases: () => Promise<void>;
91
+ getPromotedProductIOS: () => Promise<Product | null>;
92
+ requestPurchaseOnPromotedProductIOS: () => Promise<void>;
93
+ /** @deprecated Use requestPurchaseOnPromotedProductIOS instead */
92
94
  buyPromotedProductIOS: () => Promise<void>;
93
95
  getActiveSubscriptions: (
94
96
  subscriptionIds?: string[],
@@ -276,6 +278,10 @@ export function useIAP(options?: UseIAPOptions): UseIap {
276
278
  [],
277
279
  );
278
280
 
281
+ /**
282
+ * @deprecated Use getAvailablePurchases instead. This function is just calling getAvailablePurchases internally.
283
+ * Will be removed in v2.9.0
284
+ */
279
285
  const getPurchaseHistoriesInternal = useCallback(async (): Promise<void> => {
280
286
  setPurchaseHistories(await getPurchaseHistories());
281
287
  }, []);
@@ -455,7 +461,8 @@ export function useIAP(options?: UseIAPOptions): UseIap {
455
461
  getProducts: getProductsInternal,
456
462
  getSubscriptions: getSubscriptionsInternal,
457
463
  getPromotedProductIOS,
458
- buyPromotedProductIOS,
464
+ requestPurchaseOnPromotedProductIOS,
465
+ buyPromotedProductIOS: requestPurchaseOnPromotedProductIOS, // deprecated alias
459
466
  getActiveSubscriptions: getActiveSubscriptionsInternal,
460
467
  hasActiveSubscriptions: hasActiveSubscriptionsInternal,
461
468
  };