Skip to content

Commit db8df9e

Browse files
hyochanclaude
andauthored
refactor: add platform-specific suffixes to native functions (#182)
## Summary - Add IOS/Android suffixes to platform-specific functions for clarity - Deprecate getPurchaseHistories and buyPromotedProductIOS - Maintain common names for cross-platform functions (requestProducts, requestPurchase) - Compliant with [Open IAP v1.0.1](https://www.openiap.dev/docs/versions#v1-0-1) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - Added unified requestProducts/requestPurchase flows, iOS promoted-product purchase API, initConnection and validateReceiptIOS, new purchase/history helpers. - Refactor - Renamed many platform exports to IOS-suffixed variants and Android-specific finalize actions; wrappers, hooks, and mocks updated to match while preserving deprecated aliases. - Documentation - Added deprecation notices and migration guidance for renamed/legacy methods. - Tests - Updated mocks and tests to reflect new API names and platform-specific variants. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <[email protected]>
1 parent abe9135 commit db8df9e

File tree

13 files changed

+388
-131
lines changed

13 files changed

+388
-131
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# CHANGELOG
22

3+
## [2.8.6] - TBD
4+
5+
### Changed
6+
- **BREAKING NAMING CONVENTION**: Added platform-specific suffixes to native functions for clarity
7+
- iOS functions now use `IOS` suffix (e.g., `getPromotedProductIOS`, `clearTransactionIOS`)
8+
- Android functions now use `Android` suffix (e.g., `acknowledgePurchaseAndroid`, `consumeProductAndroid`)
9+
- Common cross-platform functions remain without suffix (`requestProducts`, `requestPurchase`)
10+
- Renamed `buyPromotedProductIOS` to `requestPurchaseOnPromotedProductIOS` for consistency
11+
12+
### Added
13+
- Added `getPendingTransactionsIOS` function for iOS
14+
- Added `clearTransactionIOS` function for iOS
15+
16+
### Deprecated
17+
- `getPurchaseHistories` - Use `getAvailablePurchases` instead (will be removed in v2.9.0)
18+
- `buyPromotedProductIOS` - Use `requestPurchaseOnPromotedProductIOS` instead (will be removed in v2.9.0)
19+
- `disable` function - No longer needed, observer management is automatic (will be removed in v2.9.0)
20+
321
## [2.8.5] - 2025-09-03
422

523
### Fixed

android/src/main/java/expo/modules/iap/ExpoIapModule.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class ExpoIapModule :
154154
promise.resolve(true)
155155
}
156156

157-
AsyncFunction("getItemsByType") { type: String, skuArr: Array<String>, promise: Promise ->
157+
AsyncFunction("requestProducts") { type: String, skuArr: Array<String>, promise: Promise ->
158158
ensureConnection(promise) { billingClient ->
159159
val skuList =
160160
skuArr.map { sku ->
@@ -310,7 +310,7 @@ class ExpoIapModule :
310310
// getPurchaseHistoryByType removed in Google Play Billing Library v8
311311
// Use getAvailableItemsByType instead to get active purchases
312312

313-
AsyncFunction("buyItemByType") { params: Map<String, Any?>, promise: Promise ->
313+
AsyncFunction("requestPurchase") { params: Map<String, Any?>, promise: Promise ->
314314
val type = params["type"] as String
315315
val skuArr =
316316
(params["skuArr"] as? List<*>)?.filterIsInstance<String>()?.toTypedArray()
@@ -475,7 +475,7 @@ class ExpoIapModule :
475475
}
476476
}
477477

478-
AsyncFunction("acknowledgePurchase") {
478+
AsyncFunction("acknowledgePurchaseAndroid") {
479479
token: String,
480480
promise: Promise,
481481
->
@@ -507,7 +507,7 @@ class ExpoIapModule :
507507
}
508508
}
509509

510-
AsyncFunction("consumeProduct") {
510+
AsyncFunction("consumeProductAndroid") {
511511
token: String,
512512
promise: Promise,
513513
->

docs/docs/api/methods/core-methods.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -592,26 +592,30 @@ const restorePurchases = async () => {
592592

593593
**Returns:** `Promise<Purchase[]>`
594594

595-
## getPurchaseHistories()
595+
## ~~getPurchaseHistories()~~ (Deprecated)
596+
597+
:::warning Deprecated
598+
`getPurchaseHistories` is deprecated and will be removed in v2.9.0. Use `getAvailablePurchases()` instead.
599+
600+
This function internally just calls `getAvailablePurchases()` on iOS and returns an empty array on Android (Google Play Billing v8 removed purchase history API).
601+
:::
596602

597603
Retrieves purchase history for the user.
598604

599605
```tsx
600-
import {getPurchaseHistories} from 'expo-iap';
606+
import {getAvailablePurchases} from 'expo-iap'; // Use this instead
601607

602608
const fetchPurchaseHistory = async () => {
603609
try {
604-
const histories = await getPurchaseHistories();
605-
console.log('Purchase histories:', histories);
606-
return histories;
610+
const purchases = await getAvailablePurchases();
611+
console.log('Available purchases:', purchases);
612+
return purchases;
607613
} catch (error) {
608-
console.error('Failed to fetch purchase histories:', error);
614+
console.error('Failed to fetch purchases:', error);
609615
}
610616
};
611617
```
612618

613-
**Note:** The previous `getPurchaseHistory` (singular) function is deprecated and will be removed in version 3.0.0. Please use `getPurchaseHistories` (plural) instead.
614-
615619
**Returns:** `Promise<Purchase[]>`
616620

617621
## deepLinkToSubscriptions()

docs/docs/api/use-iap.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,16 +426,17 @@ interface UseIAPOptions {
426426
};
427427
```
428428

429-
#### buyPromotedProductIOS
429+
#### requestPurchaseOnPromotedProductIOS
430430

431431
- **Type**: `() => Promise<void>`
432432
- **Description**: Complete the purchase of a promoted product (iOS only)
433+
- **Note**: `buyPromotedProductIOS` is deprecated, use `requestPurchaseOnPromotedProductIOS` instead
433434
- **Example**:
434435

435436
```tsx
436437
const completePurchase = async () => {
437438
try {
438-
await buyPromotedProductIOS();
439+
await requestPurchaseOnPromotedProductIOS();
439440
console.log('Promoted product purchase completed');
440441
} catch (error) {
441442
console.error('Failed to purchase promoted product:', error);
@@ -600,7 +601,7 @@ Handle App Store promoted products when users tap on them in the App Store:
600601

601602
```tsx
602603
const PromotedProductExample = () => {
603-
const {promotedProductIOS, buyPromotedProductIOS} = useIAP({
604+
const {promotedProductIOS, requestPurchaseOnPromotedProductIOS} = useIAP({
604605
onPromotedProductIOS: (product) => {
605606
console.log('Promoted product detected:', product);
606607
},
@@ -619,7 +620,7 @@ const PromotedProductExample = () => {
619620

620621
if (confirmed) {
621622
// Complete the promoted purchase
622-
await buyPromotedProductIOS();
623+
await requestPurchaseOnPromotedProductIOS();
623624
}
624625
} catch (error) {
625626
console.error('Error handling promoted product:', error);
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
title: Migration to v2.8.6
3+
sidebar_label: v2.8.6 Migration
4+
sidebar_position: 2
5+
---
6+
7+
# Migration Guide for v2.8.6
8+
9+
This version introduces a significant naming convention change for platform-specific functions to improve code clarity and maintainability.
10+
11+
## Breaking Changes
12+
13+
### Platform-Specific Function Naming
14+
15+
All platform-specific functions now have consistent suffixes:
16+
17+
- **iOS functions**: Use `IOS` suffix
18+
- **Android functions**: Use `Android` suffix
19+
- **Common functions**: No suffix
20+
21+
### iOS Function Changes
22+
23+
| Old Name | New Name |
24+
|----------|----------|
25+
| `buyPromotedProduct` | `requestPurchaseOnPromotedProductIOS` |
26+
| `sync` | `syncIOS` |
27+
| `isEligibleForIntroOffer` | `isEligibleForIntroOfferIOS` |
28+
| `subscriptionStatus` | `subscriptionStatusIOS` |
29+
| `currentEntitlement` | `currentEntitlementIOS` |
30+
| `latestTransaction` | `latestTransactionIOS` |
31+
| `showManageSubscriptions` | `showManageSubscriptionsIOS` |
32+
| `beginRefundRequest` | `beginRefundRequestIOS` |
33+
| `isTransactionVerified` | `isTransactionVerifiedIOS` |
34+
| `getTransactionJws` | `getTransactionJwsIOS` |
35+
| `getReceiptData` | `getReceiptIOS` |
36+
| `presentCodeRedemptionSheet` | `presentCodeRedemptionSheetIOS` |
37+
| `getAppTransaction` | `getAppTransactionIOS` |
38+
39+
### Android Function Changes
40+
41+
| Old Name | New Name |
42+
|----------|----------|
43+
| `acknowledgePurchase` | `acknowledgePurchaseAndroid` |
44+
| `consumeProduct` | `consumeProductAndroid` |
45+
46+
### New Functions Added
47+
48+
- `getPendingTransactionsIOS()` - Get pending transactions on iOS
49+
- `clearTransactionIOS()` - Clear a specific transaction on iOS
50+
51+
## Deprecated Functions
52+
53+
The following functions are deprecated and will be removed in v2.9.0:
54+
55+
### `getPurchaseHistories()`
56+
- **Reason**: This function just calls `getAvailablePurchases()` internally
57+
- **Migration**: Use `getAvailablePurchases()` instead
58+
59+
```tsx
60+
// Before
61+
const histories = await getPurchaseHistories();
62+
63+
// After
64+
const purchases = await getAvailablePurchases();
65+
```
66+
67+
### `buyPromotedProductIOS()`
68+
- **Reason**: Renamed for consistency
69+
- **Migration**: Use `requestPurchaseOnPromotedProductIOS()` instead
70+
71+
```tsx
72+
// Before
73+
await buyPromotedProductIOS();
74+
75+
// After
76+
await requestPurchaseOnPromotedProductIOS();
77+
```
78+
79+
### `disable()`
80+
- **Reason**: Observer management is now automatic
81+
- **Migration**: Remove calls to this function - it's no longer needed
82+
83+
## Migration Examples
84+
85+
### Using the useIAP Hook
86+
87+
```tsx
88+
// Before
89+
import { useIAP } from 'expo-iap';
90+
91+
const MyComponent = () => {
92+
const {
93+
buyPromotedProductIOS,
94+
getPurchaseHistories
95+
} = useIAP();
96+
97+
// ...
98+
};
99+
100+
// After
101+
import { useIAP } from 'expo-iap';
102+
103+
const MyComponent = () => {
104+
const {
105+
requestPurchaseOnPromotedProductIOS,
106+
getAvailablePurchases
107+
} = useIAP();
108+
109+
// ...
110+
};
111+
```
112+
113+
### Direct Function Imports
114+
115+
```tsx
116+
// Before
117+
import {
118+
isEligibleForIntroOffer,
119+
acknowledgePurchase,
120+
getPurchaseHistories
121+
} from 'expo-iap';
122+
123+
// After
124+
import {
125+
isEligibleForIntroOfferIOS,
126+
acknowledgePurchaseAndroid,
127+
getAvailablePurchases
128+
} from 'expo-iap';
129+
```
130+
131+
### Platform-Specific Code
132+
133+
```tsx
134+
import { Platform } from 'react-native';
135+
import {
136+
acknowledgePurchaseAndroid,
137+
clearTransactionIOS
138+
} from 'expo-iap';
139+
140+
const finishPurchase = async (purchase: Purchase) => {
141+
if (Platform.OS === 'ios') {
142+
// iOS-specific function with IOS suffix
143+
await clearTransactionIOS();
144+
} else if (Platform.OS === 'android') {
145+
// Android-specific function with Android suffix
146+
await acknowledgePurchaseAndroid({ token: purchase.purchaseToken });
147+
}
148+
};
149+
```
150+
151+
## Benefits of the New Naming Convention
152+
153+
1. **Clarity**: Function names immediately indicate platform compatibility
154+
2. **Type Safety**: Better TypeScript support with platform-specific types
155+
3. **Maintainability**: Easier to identify and manage platform-specific code
156+
4. **Consistency**: All platform-specific functions follow the same pattern
157+
158+
## Need Help?
159+
160+
If you encounter any issues during migration:
161+
162+
1. Check the [API documentation](/docs/api) for updated function signatures
163+
2. Review the [example app](https://github.com/hyochan/expo-iap/tree/main/example) for usage patterns
164+
3. Open an issue on [GitHub](https://github.com/hyochan/expo-iap/issues) if you need assistance

example/__tests__/core-functions.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ describe('Core Functions Tests', () => {
3737
expect(typeof ExpoIap.finishTransaction).toBe('function');
3838
});
3939

40-
it('should export getPurchaseHistories function', () => {
40+
it('should export deprecated getPurchaseHistories function', () => {
4141
expect(ExpoIap.getPurchaseHistories).toBeDefined();
4242
expect(typeof ExpoIap.getPurchaseHistories).toBe('function');
4343
});

0 commit comments

Comments
 (0)