expo-iap 2.8.5 → 2.8.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## [2.8.7] - 2025-09-03
4
+
5
+ ### Added
6
+
7
+ - `fetchProducts` function following OpenIAP terminology (replaces `requestProducts`)
8
+
9
+ ### Deprecated
10
+
11
+ - `requestProducts` - Use `fetchProducts` instead (will be removed in v3.0.0)
12
+
13
+ ### Changed
14
+
15
+ - Internal useIAP hook now uses `fetchProducts`
16
+ - Updated documentation and deprecation messages
17
+
18
+ ## [2.8.6]
19
+
20
+ ### Changed
21
+
22
+ - **BREAKING NAMING CONVENTION**: Added platform-specific suffixes to native functions for clarity
23
+ - iOS functions now use `IOS` suffix (e.g., `getPromotedProductIOS`, `clearTransactionIOS`)
24
+ - Android functions now use `Android` suffix (e.g., `acknowledgePurchaseAndroid`, `consumeProductAndroid`)
25
+ - Common cross-platform functions remain without suffix (`requestProducts`, `requestPurchase`)
26
+ - Renamed `buyPromotedProductIOS` to `requestPurchaseOnPromotedProductIOS` for consistency
27
+
28
+ ### Added
29
+
30
+ - Added `getPendingTransactionsIOS` function for iOS
31
+ - Added `clearTransactionIOS` function for iOS
32
+
33
+ ### Deprecated
34
+
35
+ - `getPurchaseHistories` - Use `getAvailablePurchases` instead (will be removed in v2.9.0)
36
+ - `buyPromotedProductIOS` - Use `requestPurchaseOnPromotedProductIOS` instead (will be removed in v2.9.0)
37
+ - `disable` function - No longer needed, observer management is automatic (will be removed in v2.9.0)
38
+
3
39
  ## [2.8.5] - 2025-09-03
4
40
 
5
41
  ### Fixed
package/README.md CHANGED
@@ -69,12 +69,13 @@ For detailed usage examples and error handling, see the [documentation](https://
69
69
  <img width="600" alt="courier_dot_com" src="https://static.xx.fbcdn.net/rsrc.php/y3/r/y6QsbGgc866.svg" />
70
70
  </a>
71
71
 
72
- ### <p style="color: rgb(205, 127, 50);">Bronze</p>
73
-
74
- <a href="https://www.courier.com/?utm_source=react-native-iap&utm_campaign=osssponsors">
75
- <img width="160" alt="courier_dot_com" src="https://github.com/user-attachments/assets/319d8966-6839-498d-8ead-ce8cc72c3bca" />
76
- </a>
77
-
78
72
  ## Past Supporters
79
73
 
80
- <a href="https://namiml.com" style="opacity: 50%"><img src="https://github.com/hyochan/react-native-iap/assets/27461460/89d71f61-bb73-400a-83bd-fe0f96eb726e" alt="Nami ML" width="140"/></a>
74
+ <div style="display: flex; align-items:center; gap: 10px;">
75
+ <a href="https://namiml.com" style="opacity: 50%">
76
+ <img src="https://github.com/hyochan/react-native-iap/assets/27461460/89d71f61-bb73-400a-83bd-fe0f96eb726e" alt="Nami ML" width="140"/>
77
+ </a>
78
+ <a href="https://www.courier.com/?utm_source=react-native-iap&utm_campaign=osssponsors" style="opacity: 50%;">
79
+ <img width="80" alt="courier_dot_com" src="https://github.com/user-attachments/assets/319d8966-6839-498d-8ead-ce8cc72c3bca" />
80
+ </a>
81
+ </div>
@@ -154,7 +154,120 @@ class ExpoIapModule :
154
154
  promise.resolve(true)
155
155
  }
156
156
 
157
- AsyncFunction("getItemsByType") { type: String, skuArr: Array<String>, promise: Promise ->
157
+ AsyncFunction("fetchProducts") { type: String, skuArr: Array<String>, promise: Promise ->
158
+ ensureConnection(promise) { billingClient ->
159
+ val skuList =
160
+ skuArr.map { sku ->
161
+ QueryProductDetailsParams.Product
162
+ .newBuilder()
163
+ .setProductId(sku)
164
+ .setProductType(type)
165
+ .build()
166
+ }
167
+
168
+ if (skuList.isEmpty()) {
169
+ promise.reject(IapErrorCode.E_EMPTY_SKU_LIST, "The SKU list is empty.", null)
170
+ return@ensureConnection
171
+ }
172
+
173
+ val params =
174
+ QueryProductDetailsParams
175
+ .newBuilder()
176
+ .setProductList(skuList)
177
+ .build()
178
+
179
+ billingClient.queryProductDetailsAsync(params) { billingResult: BillingResult, productDetailsResult: QueryProductDetailsResult ->
180
+ if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
181
+ promise.reject(
182
+ IapErrorCode.E_QUERY_PRODUCT,
183
+ "Error querying product details: ${billingResult.debugMessage}",
184
+ null,
185
+ )
186
+ return@queryProductDetailsAsync
187
+ }
188
+
189
+ val productDetailsList = productDetailsResult.productDetailsList ?: emptyList()
190
+
191
+ val items =
192
+ productDetailsList.map { productDetails ->
193
+ skus[productDetails.productId] = productDetails
194
+
195
+ val currency = productDetails.oneTimePurchaseOfferDetails?.priceCurrencyCode
196
+ ?: productDetails.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.priceCurrencyCode
197
+ ?: "Unknown"
198
+ val displayPrice = productDetails.oneTimePurchaseOfferDetails?.formattedPrice
199
+ ?: productDetails.subscriptionOfferDetails?.firstOrNull()?.pricingPhases?.pricingPhaseList?.firstOrNull()?.formattedPrice
200
+ ?: "N/A"
201
+
202
+ // Prepare reusable data
203
+ val oneTimePurchaseData = productDetails.oneTimePurchaseOfferDetails?.let {
204
+ mapOf(
205
+ "priceCurrencyCode" to it.priceCurrencyCode,
206
+ "formattedPrice" to it.formattedPrice,
207
+ "priceAmountMicros" to it.priceAmountMicros.toString(),
208
+ )
209
+ }
210
+
211
+ val subscriptionOfferData = productDetails.subscriptionOfferDetails?.map { subscriptionOfferDetailsItem ->
212
+ mapOf(
213
+ "basePlanId" to subscriptionOfferDetailsItem.basePlanId,
214
+ "offerId" to subscriptionOfferDetailsItem.offerId,
215
+ "offerToken" to subscriptionOfferDetailsItem.offerToken,
216
+ "offerTags" to subscriptionOfferDetailsItem.offerTags,
217
+ "pricingPhases" to
218
+ mapOf(
219
+ "pricingPhaseList" to
220
+ subscriptionOfferDetailsItem.pricingPhases.pricingPhaseList.map
221
+ { pricingPhaseItem ->
222
+ mapOf(
223
+ "formattedPrice" to pricingPhaseItem.formattedPrice,
224
+ "priceCurrencyCode" to pricingPhaseItem.priceCurrencyCode,
225
+ "billingPeriod" to pricingPhaseItem.billingPeriod,
226
+ "billingCycleCount" to pricingPhaseItem.billingCycleCount,
227
+ "priceAmountMicros" to
228
+ pricingPhaseItem.priceAmountMicros.toString(),
229
+ "recurrenceMode" to pricingPhaseItem.recurrenceMode,
230
+ )
231
+ },
232
+ ),
233
+ )
234
+ }
235
+
236
+ // Convert Android productType to our expected 'inapp' or 'subs'
237
+ val productType = if (productDetails.productType == BillingClient.ProductType.SUBS) "subs" else "inapp"
238
+
239
+ mapOf(
240
+ "id" to productDetails.productId,
241
+ "title" to productDetails.title,
242
+ "description" to productDetails.description,
243
+ "type" to productType,
244
+ // New field names with Android suffix
245
+ "nameAndroid" to productDetails.name,
246
+ "oneTimePurchaseOfferDetailsAndroid" to oneTimePurchaseData,
247
+ "subscriptionOfferDetailsAndroid" to subscriptionOfferData,
248
+ "platform" to "android",
249
+ "currency" to currency,
250
+ "displayPrice" to displayPrice,
251
+ // START: Deprecated - will be removed in v2.9.0
252
+ // Use nameAndroid instead of displayName
253
+ "displayName" to productDetails.name,
254
+ // Use nameAndroid instead of name
255
+ "name" to productDetails.name,
256
+ // Use oneTimePurchaseOfferDetailsAndroid instead of oneTimePurchaseOfferDetails
257
+ "oneTimePurchaseOfferDetails" to oneTimePurchaseData,
258
+ // Use subscriptionOfferDetailsAndroid instead of subscriptionOfferDetails
259
+ "subscriptionOfferDetails" to subscriptionOfferData,
260
+ // END: Deprecated - will be removed in v2.9.0
261
+ )
262
+ }
263
+ promise.resolve(items)
264
+ }
265
+ }
266
+ }
267
+
268
+ AsyncFunction("requestProducts") { type: String, skuArr: Array<String>, promise: Promise ->
269
+ Log.w("ExpoIap", "WARNING: requestProducts is deprecated. Use fetchProducts instead. The 'request' prefix should only be used for event-based operations. This method will be removed in version 3.0.0.")
270
+
158
271
  ensureConnection(promise) { billingClient ->
159
272
  val skuList =
160
273
  skuArr.map { sku ->
@@ -310,7 +423,7 @@ class ExpoIapModule :
310
423
  // getPurchaseHistoryByType removed in Google Play Billing Library v8
311
424
  // Use getAvailableItemsByType instead to get active purchases
312
425
 
313
- AsyncFunction("buyItemByType") { params: Map<String, Any?>, promise: Promise ->
426
+ AsyncFunction("requestPurchase") { params: Map<String, Any?>, promise: Promise ->
314
427
  val type = params["type"] as String
315
428
  val skuArr =
316
429
  (params["skuArr"] as? List<*>)?.filterIsInstance<String>()?.toTypedArray()
@@ -475,7 +588,7 @@ class ExpoIapModule :
475
588
  }
476
589
  }
477
590
 
478
- AsyncFunction("acknowledgePurchase") {
591
+ AsyncFunction("acknowledgePurchaseAndroid") {
479
592
  token: String,
480
593
  promise: Promise,
481
594
  ->
@@ -507,7 +620,7 @@ class ExpoIapModule :
507
620
  }
508
621
  }
509
622
 
510
- AsyncFunction("consumeProduct") {
623
+ AsyncFunction("consumeProductAndroid") {
511
624
  token: String,
512
625
  promise: Promise,
513
626
  ->
package/build/index.d.ts CHANGED
@@ -53,27 +53,53 @@ export declare const getProducts: (skus: string[]) => Promise<Product[]>;
53
53
  export declare const getSubscriptions: (skus: string[]) => Promise<SubscriptionProduct[]>;
54
54
  export declare function endConnection(): Promise<boolean>;
55
55
  /**
56
- * Request products with unified API (v2.7.0+)
56
+ * Fetch products with unified API (v2.7.0+)
57
57
  *
58
- * @param params - Product request configuration
58
+ * @param params - Product fetch configuration
59
59
  * @param params.skus - Array of product SKUs to fetch
60
60
  * @param params.type - Type of products: 'inapp' for regular products (default) or 'subs' for subscriptions
61
61
  *
62
62
  * @example
63
63
  * ```typescript
64
64
  * // Regular products
65
- * const products = await requestProducts({
65
+ * const products = await fetchProducts({
66
66
  * skus: ['product1', 'product2'],
67
67
  * type: 'inapp'
68
68
  * });
69
69
  *
70
70
  * // Subscriptions
71
- * const subscriptions = await requestProducts({
71
+ * const subscriptions = await fetchProducts({
72
72
  * skus: ['sub1', 'sub2'],
73
73
  * type: 'subs'
74
74
  * });
75
75
  * ```
76
76
  */
77
+ export declare const fetchProducts: ({ skus, type, }: {
78
+ skus: string[];
79
+ type?: "inapp" | "subs";
80
+ }) => Promise<Product[] | SubscriptionProduct[]>;
81
+ /**
82
+ * @deprecated Use `fetchProducts` instead. This method will be removed in version 3.0.0.
83
+ *
84
+ * The 'request' prefix should only be used for event-based operations that trigger
85
+ * purchase flows. Since this function simply fetches product information, it has been
86
+ * renamed to `fetchProducts` to follow OpenIAP terminology guidelines.
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * // Old way (deprecated)
91
+ * const products = await requestProducts({
92
+ * skus: ['com.example.product1'],
93
+ * type: 'inapp'
94
+ * });
95
+ *
96
+ * // New way (recommended)
97
+ * const products = await fetchProducts({
98
+ * skus: ['com.example.product1'],
99
+ * type: 'inapp'
100
+ * });
101
+ * ```
102
+ */
77
103
  export declare const requestProducts: ({ skus, type, }: {
78
104
  skus: string[];
79
105
  type?: "inapp" | "subs";
@@ -81,17 +107,34 @@ export declare const requestProducts: ({ skus, type, }: {
81
107
  /**
82
108
  * @deprecated Use `getPurchaseHistories` instead. This function will be removed in version 3.0.0.
83
109
  */
84
- export declare const getPurchaseHistory: ({ alsoPublishToEventListener, onlyIncludeActiveItems, }?: {
110
+ export declare const getPurchaseHistory: ({ alsoPublishToEventListener, onlyIncludeActiveItems, alsoPublishToEventListenerIOS, onlyIncludeActiveItemsIOS, }?: {
111
+ /** @deprecated Use alsoPublishToEventListenerIOS instead */
85
112
  alsoPublishToEventListener?: boolean;
113
+ /** @deprecated Use onlyIncludeActiveItemsIOS instead */
86
114
  onlyIncludeActiveItems?: boolean;
115
+ alsoPublishToEventListenerIOS?: boolean;
116
+ onlyIncludeActiveItemsIOS?: boolean;
87
117
  }) => Promise<Purchase[]>;
88
- export declare const getPurchaseHistories: ({ alsoPublishToEventListener, onlyIncludeActiveItems, }?: {
118
+ /**
119
+ * @deprecated Use getAvailablePurchases instead. This function is just calling getAvailablePurchases internally on iOS
120
+ * and returns an empty array on Android (Google Play Billing v8 removed purchase history API).
121
+ * Will be removed in v2.9.0
122
+ */
123
+ export declare const getPurchaseHistories: ({ alsoPublishToEventListener, onlyIncludeActiveItems, alsoPublishToEventListenerIOS, onlyIncludeActiveItemsIOS, }?: {
124
+ /** @deprecated Use alsoPublishToEventListenerIOS instead */
89
125
  alsoPublishToEventListener?: boolean;
126
+ /** @deprecated Use onlyIncludeActiveItemsIOS instead */
90
127
  onlyIncludeActiveItems?: boolean;
128
+ alsoPublishToEventListenerIOS?: boolean;
129
+ onlyIncludeActiveItemsIOS?: boolean;
91
130
  }) => Promise<Purchase[]>;
92
- export declare const getAvailablePurchases: ({ alsoPublishToEventListener, onlyIncludeActiveItems, }?: {
131
+ export declare const getAvailablePurchases: ({ alsoPublishToEventListener, onlyIncludeActiveItems, alsoPublishToEventListenerIOS, onlyIncludeActiveItemsIOS, }?: {
132
+ /** @deprecated Use alsoPublishToEventListenerIOS instead */
93
133
  alsoPublishToEventListener?: boolean;
134
+ /** @deprecated Use onlyIncludeActiveItemsIOS instead */
94
135
  onlyIncludeActiveItems?: boolean;
136
+ alsoPublishToEventListenerIOS?: boolean;
137
+ onlyIncludeActiveItemsIOS?: boolean;
95
138
  }) => Promise<Purchase[]>;
96
139
  type PurchaseRequest = {
97
140
  request: RequestPurchaseProps;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -67,13 +67,13 @@ export function initConnection() {
67
67
  return Promise.resolve(result);
68
68
  }
69
69
  export const getProducts = async (skus) => {
70
- console.warn("`getProducts` is deprecated. Use `requestProducts({ skus, type: 'inapp' })` instead. This function will be removed in version 3.0.0.");
70
+ console.warn("`getProducts` is deprecated. Use `fetchProducts({ skus, type: 'inapp' })` instead. This function will be removed in version 3.0.0.");
71
71
  if (!skus?.length) {
72
72
  return Promise.reject(new Error('"skus" is required'));
73
73
  }
74
74
  return Platform.select({
75
75
  ios: async () => {
76
- const rawItems = await ExpoIapModule.getItems(skus);
76
+ const rawItems = await ExpoIapModule.fetchProducts(skus);
77
77
  return rawItems.filter((item) => {
78
78
  if (!isProductIOS(item))
79
79
  return false;
@@ -85,20 +85,20 @@ export const getProducts = async (skus) => {
85
85
  });
86
86
  },
87
87
  android: async () => {
88
- const products = await ExpoIapModule.getItemsByType('inapp', skus);
88
+ const products = await ExpoIapModule.fetchProducts('inapp', skus);
89
89
  return products.filter((product) => isProductAndroid(product));
90
90
  },
91
91
  default: () => Promise.reject(new Error('Unsupported Platform')),
92
92
  })();
93
93
  };
94
94
  export const getSubscriptions = async (skus) => {
95
- console.warn("`getSubscriptions` is deprecated. Use `requestProducts({ skus, type: 'subs' })` instead. This function will be removed in version 3.0.0.");
95
+ console.warn("`getSubscriptions` is deprecated. Use `fetchProducts({ skus, type: 'subs' })` instead. This function will be removed in version 3.0.0.");
96
96
  if (!skus?.length) {
97
97
  return Promise.reject(new Error('"skus" is required'));
98
98
  }
99
99
  return Platform.select({
100
100
  ios: async () => {
101
- const rawItems = await ExpoIapModule.getItems(skus);
101
+ const rawItems = await ExpoIapModule.fetchProducts(skus);
102
102
  return rawItems.filter((item) => {
103
103
  if (!isProductIOS(item))
104
104
  return false;
@@ -110,7 +110,7 @@ export const getSubscriptions = async (skus) => {
110
110
  });
111
111
  },
112
112
  android: async () => {
113
- const rawItems = await ExpoIapModule.getItemsByType('subs', skus);
113
+ const rawItems = await ExpoIapModule.fetchProducts('subs', skus);
114
114
  return rawItems.filter((item) => {
115
115
  if (!isProductAndroid(item))
116
116
  return false;
@@ -128,33 +128,33 @@ export async function endConnection() {
128
128
  return ExpoIapModule.endConnection();
129
129
  }
130
130
  /**
131
- * Request products with unified API (v2.7.0+)
131
+ * Fetch products with unified API (v2.7.0+)
132
132
  *
133
- * @param params - Product request configuration
133
+ * @param params - Product fetch configuration
134
134
  * @param params.skus - Array of product SKUs to fetch
135
135
  * @param params.type - Type of products: 'inapp' for regular products (default) or 'subs' for subscriptions
136
136
  *
137
137
  * @example
138
138
  * ```typescript
139
139
  * // Regular products
140
- * const products = await requestProducts({
140
+ * const products = await fetchProducts({
141
141
  * skus: ['product1', 'product2'],
142
142
  * type: 'inapp'
143
143
  * });
144
144
  *
145
145
  * // Subscriptions
146
- * const subscriptions = await requestProducts({
146
+ * const subscriptions = await fetchProducts({
147
147
  * skus: ['sub1', 'sub2'],
148
148
  * type: 'subs'
149
149
  * });
150
150
  * ```
151
151
  */
152
- export const requestProducts = async ({ skus, type = 'inapp', }) => {
152
+ export const fetchProducts = async ({ skus, type = 'inapp', }) => {
153
153
  if (!skus?.length) {
154
154
  throw new Error('No SKUs provided');
155
155
  }
156
156
  if (Platform.OS === 'ios') {
157
- const rawItems = await ExpoIapModule.getItems(skus);
157
+ const rawItems = await ExpoIapModule.fetchProducts(skus);
158
158
  const filteredItems = rawItems.filter((item) => {
159
159
  if (!isProductIOS(item))
160
160
  return false;
@@ -169,7 +169,7 @@ export const requestProducts = async ({ skus, type = 'inapp', }) => {
169
169
  : filteredItems;
170
170
  }
171
171
  if (Platform.OS === 'android') {
172
- const items = await ExpoIapModule.getItemsByType(type, skus);
172
+ const items = await ExpoIapModule.fetchProducts(type, skus);
173
173
  const filteredItems = items.filter((item) => {
174
174
  if (!isProductAndroid(item))
175
175
  return false;
@@ -185,19 +185,50 @@ export const requestProducts = async ({ skus, type = 'inapp', }) => {
185
185
  }
186
186
  throw new Error('Unsupported platform');
187
187
  };
188
+ /**
189
+ * @deprecated Use `fetchProducts` instead. This method will be removed in version 3.0.0.
190
+ *
191
+ * The 'request' prefix should only be used for event-based operations that trigger
192
+ * purchase flows. Since this function simply fetches product information, it has been
193
+ * renamed to `fetchProducts` to follow OpenIAP terminology guidelines.
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * // Old way (deprecated)
198
+ * const products = await requestProducts({
199
+ * skus: ['com.example.product1'],
200
+ * type: 'inapp'
201
+ * });
202
+ *
203
+ * // New way (recommended)
204
+ * const products = await fetchProducts({
205
+ * skus: ['com.example.product1'],
206
+ * type: 'inapp'
207
+ * });
208
+ * ```
209
+ */
210
+ export const requestProducts = async ({ skus, type = 'inapp', }) => {
211
+ console.warn("`requestProducts` is deprecated. Use `fetchProducts` instead. The 'request' prefix should only be used for event-based operations. This method will be removed in version 3.0.0.");
212
+ return fetchProducts({ skus, type });
213
+ };
188
214
  /**
189
215
  * @deprecated Use `getPurchaseHistories` instead. This function will be removed in version 3.0.0.
190
216
  */
191
- export const getPurchaseHistory = ({ alsoPublishToEventListener = false, onlyIncludeActiveItems = false, } = {}) => {
217
+ export const getPurchaseHistory = ({ alsoPublishToEventListener = false, onlyIncludeActiveItems = false, alsoPublishToEventListenerIOS, onlyIncludeActiveItemsIOS, } = {}) => {
192
218
  console.warn('`getPurchaseHistory` is deprecated. Use `getPurchaseHistories` instead. This function will be removed in version 3.0.0.');
193
219
  return getPurchaseHistories({
194
- alsoPublishToEventListener,
195
- onlyIncludeActiveItems,
220
+ alsoPublishToEventListenerIOS: alsoPublishToEventListenerIOS ?? alsoPublishToEventListener,
221
+ onlyIncludeActiveItemsIOS: onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems,
196
222
  });
197
223
  };
198
- export const getPurchaseHistories = ({ alsoPublishToEventListener = false, onlyIncludeActiveItems = false, } = {}) => (Platform.select({
224
+ /**
225
+ * @deprecated Use getAvailablePurchases instead. This function is just calling getAvailablePurchases internally on iOS
226
+ * and returns an empty array on Android (Google Play Billing v8 removed purchase history API).
227
+ * Will be removed in v2.9.0
228
+ */
229
+ export const getPurchaseHistories = ({ alsoPublishToEventListener = false, onlyIncludeActiveItems = false, alsoPublishToEventListenerIOS, onlyIncludeActiveItemsIOS, } = {}) => (Platform.select({
199
230
  ios: async () => {
200
- return ExpoIapModule.getAvailableItems(alsoPublishToEventListener, onlyIncludeActiveItems);
231
+ return ExpoIapModule.getAvailableItems(alsoPublishToEventListenerIOS ?? alsoPublishToEventListener, onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems);
201
232
  },
202
233
  android: async () => {
203
234
  // getPurchaseHistoryByType was removed in Google Play Billing Library v8
@@ -206,8 +237,8 @@ export const getPurchaseHistories = ({ alsoPublishToEventListener = false, onlyI
206
237
  return [];
207
238
  },
208
239
  }) || (() => Promise.resolve([])))();
209
- export const getAvailablePurchases = ({ alsoPublishToEventListener = false, onlyIncludeActiveItems = true, } = {}) => (Platform.select({
210
- ios: () => ExpoIapModule.getAvailableItems(alsoPublishToEventListener, onlyIncludeActiveItems),
240
+ export const getAvailablePurchases = ({ alsoPublishToEventListener = false, onlyIncludeActiveItems = true, alsoPublishToEventListenerIOS, onlyIncludeActiveItemsIOS, } = {}) => (Platform.select({
241
+ ios: () => ExpoIapModule.getAvailableItems(alsoPublishToEventListenerIOS ?? alsoPublishToEventListener, onlyIncludeActiveItemsIOS ?? onlyIncludeActiveItems),
211
242
  android: async () => {
212
243
  const products = await ExpoIapModule.getAvailableItemsByType('inapp');
213
244
  const subscriptions = await ExpoIapModule.getAvailableItemsByType('subs');
@@ -273,7 +304,7 @@ export const requestPurchase = (requestObj) => {
273
304
  const { sku, andDangerouslyFinishTransactionAutomatically = false, appAccountToken, quantity, withOffer, } = normalizedRequest;
274
305
  return (async () => {
275
306
  const offer = offerToRecordIOS(withOffer);
276
- const purchase = await ExpoIapModule.buyProduct(sku, andDangerouslyFinishTransactionAutomatically, appAccountToken, quantity ?? -1, offer);
307
+ const purchase = await ExpoIapModule.requestPurchase(sku, andDangerouslyFinishTransactionAutomatically, appAccountToken, quantity ?? -1, offer);
277
308
  return type === 'inapp' ? purchase : purchase;
278
309
  })();
279
310
  }
@@ -285,7 +316,7 @@ export const requestPurchase = (requestObj) => {
285
316
  if (type === 'inapp') {
286
317
  const { skus, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, isOfferPersonalized, } = normalizedRequest;
287
318
  return (async () => {
288
- return ExpoIapModule.buyItemByType({
319
+ return ExpoIapModule.requestPurchase({
289
320
  type: 'inapp',
290
321
  skuArr: skus,
291
322
  purchaseToken: undefined,
@@ -300,7 +331,7 @@ export const requestPurchase = (requestObj) => {
300
331
  if (type === 'subs') {
301
332
  const { skus, obfuscatedAccountIdAndroid, obfuscatedProfileIdAndroid, isOfferPersonalized, subscriptionOffers = [], replacementModeAndroid = -1, purchaseTokenAndroid, purchaseToken, } = normalizedRequest;
302
333
  return (async () => {
303
- return ExpoIapModule.buyItemByType({
334
+ return ExpoIapModule.requestPurchase({
304
335
  type: 'subs',
305
336
  skuArr: skus,
306
337
  purchaseToken: purchaseTokenAndroid || purchaseToken,
@@ -363,9 +394,9 @@ export const finishTransaction = ({ purchase, isConsumable = false, }) => {
363
394
  return Promise.reject(new PurchaseError('[expo-iap]: PurchaseError', 'Purchase token is required to finish transaction', undefined, undefined, 'E_DEVELOPER_ERROR', androidPurchase.productId, 'android'));
364
395
  }
365
396
  if (isConsumable) {
366
- return ExpoIapModule.consumeProduct(token);
397
+ return ExpoIapModule.consumeProductAndroid(token);
367
398
  }
368
- return ExpoIapModule.acknowledgePurchase(token);
399
+ return ExpoIapModule.acknowledgePurchaseAndroid(token);
369
400
  },
370
401
  }) || (() => Promise.reject(new Error('Unsupported Platform'))))();
371
402
  };