Skip to content

Commit 27347e0

Browse files
committed
3.1.0
1 parent 333061d commit 27347e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+9978
-77
lines changed

README.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55

66
[![Version](http://img.shields.io/npm/v/expo-iap.svg?style=flat-square)](https://npmjs.org/package/expo-iap) [![Download](http://img.shields.io/npm/dm/expo-iap.svg?style=flat-square)](https://npmjs.org/package/expo-iap) [![CI](https://github.com/hyochan/expo-iap/actions/workflows/ci.yml/badge.svg)](https://github.com/hyochan/expo-iap/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/hyochan/expo-iap/graph/badge.svg?token=47VMTY5NyM)](https://codecov.io/gh/hyochan/expo-iap) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fhyochan%2Fexpo-iap.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Fhyochan%2Fexpo-iap?ref=badge_shield&issueType=license)
77

8-
In app purchase module in [Expo](https://docs.expo.dev/guides/in-app-purchases) that conforms to the [Open IAP specification](https://openiap.dev)
9-
10-
<a href="https://openiap.dev"><img src="https://openiap.dev/logo.png" alt="Open IAP" height="40" /></a>
8+
Expo IAP is a powerful in-app purchase solution for Expo and React Native applications that conforms to the Open IAP specification. It provides a unified API for handling in-app purchases across iOS and Android platforms with comprehensive error handling and modern TypeScript support.
9+
10+
If you're shipping an app with expo-iap, we’d love to hear about it—please share your product and feedback in [Who's using Expo IAP?](https://github.com/hyochan/expo-iap/discussions/143). Community stories help us keep improving the ecosystem.
11+
12+
<a href="https://openiap.dev"><img src="https://openiap.dev/logo.png" alt="Open IAP" height="40" /></a>
13+
1114
</div>
1215

1316
## 📚 Documentation
@@ -44,7 +47,7 @@ npx expo install expo-iap
4447
"expo-build-properties",
4548
{
4649
"android": {
47-
"kotlinVersion": "2.0.21"
50+
"kotlinVersion": "2.1.20"
4851
}
4952
}
5053
]
@@ -53,6 +56,8 @@ npx expo install expo-iap
5356
}
5457
```
5558

59+
If you're targeting Expo SDK 54 or newer, please confirm whether this manual override is still required and share findings with the community at [github.com/hyochan/expo-iap/discussions](https://github.com/hyochan/expo-iap/discussions).
60+
5661
## Contributing
5762

5863
We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details on:
@@ -67,14 +72,21 @@ For detailed usage examples and error handling, see the [documentation](https://
6772

6873
> Sharing your thoughts—any feedback would be greatly appreciated!
6974
70-
## Sponsors
75+
## Our Sponsors
7176

7277
💼 **[View Our Sponsors](https://openiap.dev/sponsors)**
7378

79+
We're building the OpenIAP ecosystem—defining the spec at [openiap.dev](https://www.openiap.dev), maintaining [openiap-gql](https://github.com/hyodotdev/openiap-gql) for the shared type system, and shipping platform SDKs like [openiap-apple](https://github.com/hyodotdev/openiap-apple) and [openiap-google](https://github.com/hyodotdev/openiap-google) that power [expo-iap](https://github.com/hyochan/expo-iap), [flutter_inapp_purchase](https://github.com/hyochan/flutter_inapp_purchase), React Native, and [kmp-iap](https://github.com/hyochan/kmp-iap). The work so far has focused on untangling fragmented APIs; the next milestone is a streamlined purchase flow: `initConnection → fetchProducts → requestPurchase → (server receipt validation) → finishTransaction`.
80+
81+
Your sponsorship helps ensure developers across platforms, OS, and frameworks can implement in-app purchases without headaches. It also fuels new plugins, payment systems, and partner integrations already being explored in the OpenIAP community. Sponsors receive shout-outs in every release and can request tailored support depending on tier. If you’re interested—or have rollout feedback to share—you can view sponsorship options at [openiap.dev/sponsors](https://openiap.dev/sponsors).
82+
7483
### <p style="color: rgb(255, 182, 193);">Angel</p>
7584

7685
<a href="https://meta.com">
77-
<img width="600" alt="courier_dot_com" src="https://static.xx.fbcdn.net/rsrc.php/y3/r/y6QsbGgc866.svg" />
86+
<div style="display: inline-flex; flex-direction: column; align-items: center; gap: 0.25rem; padding: 0.75rem 1rem; border-radius: 12px; background: rgba(212, 165, 116, 0.12);">
87+
<img alt="Meta" src="https://www.openiap.dev/meta.svg" style="width: 120px;" />
88+
<span style="font-size: 0.85rem; font-weight: 600; color: rgb(107, 78, 61); text-align: center; width: 100%;">Meta</span>
89+
</div>
7890
</a>
7991

8092
## Past Supporters
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
2-
slug: v2.6
3-
title: 2.6 - Major iOS Improvements
2+
slug: 2.6.0
3+
title: 2.6.0 - Major iOS Improvements
44
authors: [hyochan]
55
tags: [release, ios, typescript, breaking-changes]
66
date: 2025-07-21
77
---
88

9-
# 2.6 - Major iOS Improvements
9+
# 2.6.0 - Major iOS Improvements
1010

11-
We're excited to announce the release of expo-iap v2.6.0! This release brings significant improvements to iOS functionality, better TypeScript support, and enhanced developer experience.
11+
We're excited to announce the release of expo-iap 2.6.0! This release brings significant improvements to iOS functionality, better TypeScript support, and enhanced developer experience.
1212

1313
<!-- truncate -->
1414

@@ -22,14 +22,14 @@ import AdFitTopFixed from "@site/src/uis/AdFitTopFixed";
2222

2323
The biggest improvement in this release is the proper serialization of iOS subscription data. Previously, the `subscription` field would return undefined for subscription products. Now, all subscription information is properly serialized and accessible.
2424

25-
#### Before (v2.5.x)
25+
#### Before (2.5.x)
2626

2727
```typescript
2828
const subscriptions = await getSubscriptions(['com.example.premium']);
2929
console.log(subscriptions[0].subscription); // undefined 😢
3030
```
3131

32-
#### After (v2.6.0)
32+
#### After (2.6.0)
3333

3434
```typescript
3535
const subscriptions = await getSubscriptions(['com.example.premium']);
@@ -40,15 +40,15 @@ console.log(subscriptions[0].subscription); // ✅ Full subscription data!
4040

4141
We've restructured how period information is returned to be more consistent and useful. The `period` and `subscriptionPeriod` properties now return objects with `unit` and `value` properties instead of just the unit string.
4242

43-
**Before (v2.5.x):**
43+
**Before (2.5.x):**
4444

4545
```typescript
4646
type SubscriptionInfo = {
4747
subscriptionPeriod: SubscriptionIosPeriod; // 'DAY' | 'WEEK' | 'MONTH' | 'YEAR'
4848
};
4949
```
5050

51-
**After (v2.6.0):**
51+
**After (2.6.0):**
5252

5353
```typescript
5454
type SubscriptionInfo = {
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
2-
slug: v2.7
3-
title: 2.7 - New Platform API & Google Play Billing v8
2+
slug: 2.7.0
3+
title: 2.7.0 - New Platform API & Google Play Billing v8
44
authors: [hyochan]
55
tags: [release, api, breaking-changes, android, google-play-billing]
66
date: 2025-07-23
77
---
88

99
# 2.7.0 - New Platform API & Google Play Billing v8
1010

11-
We're excited to announce expo-iap v2.7.0! This release includes a cleaner platform-specific API for handling purchases and full support for Google Play Billing Library v8.0.0.
11+
We're excited to announce expo-iap 2.7.0! This release includes a cleaner platform-specific API for handling purchases and full support for Google Play Billing Library v8.0.0.
1212

1313
<!-- truncate -->
1414

@@ -199,7 +199,7 @@ const buySubscription = async (subId: string) => {
199199

200200
## 🔄 Deprecation Notice: requestSubscription
201201

202-
Starting from v2.7.0, `requestSubscription` is deprecated in favor of using `requestPurchase` with `type: 'subs'`. This unifies our API and makes the codebase cleaner.
202+
Starting from 2.7.0, `requestSubscription` is deprecated in favor of using `requestPurchase` with `type: 'subs'`. This unifies our API and makes the codebase cleaner.
203203

204204
**Migration example:**
205205

docs/blog/2025-08-18-v2.8-migration-guide.md renamed to docs/blog/2025-08-18-2.8.0-migration-guide.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
---
2-
slug: v2-8-migration-guide
3-
title: v2.8 Migration Guide - iOS Field Naming Convention Update
2+
slug: 2.8.0-migration-guide
3+
title: 2.8.0 Migration Guide - iOS Field Naming Convention Update
44
authors: [hyochan]
55
tags: [release, breaking-change, migration]
66
date: 2025-08-18
77
---
88

9-
# Migrating to expo-iap v2.8
9+
# Migrating to expo-iap 2.8.0
1010

1111
## Breaking Changes
1212

13-
Version 2.8 introduces naming convention changes:
13+
Version 2.8.0 introduces naming convention changes:
1414

1515
1. **iOS suffix convention**: Fields with iOS suffixes now use uppercase `IOS` instead of `Ios`
1616
2. **ID suffix convention**: All fields ending with `ID` now use `Id` instead for consistency (e.g., `subscriptionGroupID``subscriptionGroupId`, `bundleID``bundleId`)
@@ -149,14 +149,14 @@ import AdFitTopFixed from "@site/src/uis/AdFitTopFixed";
149149
Search your codebase for any references to the old field names and update them:
150150

151151
```typescript
152-
// Before (v2.7.x)
152+
// Before (2.7.x)
153153
const purchase = await requestPurchase({sku: 'product-id'});
154154
if (purchase.expirationDateIos) {
155155
console.log('Expires:', purchase.expirationDateIos);
156156
}
157157

158-
// After (v2.8.0)
159-
// Note: requestPurchase API signature has also changed in v2.8.0
158+
// After (2.8.0)
159+
// Note: requestPurchase API signature has also changed in 2.8.0
160160
const purchase = await requestPurchase({
161161
request: {
162162
ios: {sku: 'product-id'},
@@ -174,15 +174,15 @@ if (purchase.expirationDateIOS) {
174174
Type names have also been updated to use uppercase `IOS`:
175175

176176
```typescript
177-
// Before (v2.7.x)
177+
// Before (2.7.x)
178178
import {
179179
ProductIOS,
180180
ProductPurchaseIos,
181181
ProductSubscriptionIOS,
182182
ProductStatusIos,
183183
} from 'expo-iap';
184184

185-
// After (v2.8.0)
185+
// After (2.8.0)
186186
import {
187187
ProductIOS,
188188
ProductPurchaseIOS,
@@ -198,12 +198,12 @@ import {
198198
If you're using TypeScript and checking for iOS-specific fields:
199199

200200
```typescript
201-
// Before (v2.7.x)
201+
// Before (2.7.x)
202202
if ('expirationDateIos' in purchase) {
203203
// Handle subscription
204204
}
205205

206-
// After (v2.8.0)
206+
// After (2.8.0)
207207
if ('expirationDateIOS' in purchase) {
208208
// Handle subscription
209209
}
@@ -214,12 +214,12 @@ if ('expirationDateIOS' in purchase) {
214214
Update all ID field references to use `Id` instead:
215215

216216
```typescript
217-
// Before (v2.7.x)
217+
// Before (2.7.x)
218218
const appTransaction = await getAppTransactionIOS();
219219
console.log(appTransaction.bundleID);
220220
console.log(appTransaction.appID);
221221

222-
// After (v2.8.0)
222+
// After (2.8.0)
223223
const appTransaction = await getAppTransactionIOS();
224224
console.log(appTransaction.bundleId);
225225
console.log(appTransaction.appId);
@@ -230,13 +230,13 @@ console.log(appTransaction.appId);
230230
If you're using the subscription helper functions:
231231

232232
```typescript
233-
// Before (v2.7.x)
233+
// Before (2.7.x)
234234
const subscription = {
235235
expirationDateIos: purchase.expirationDateIos,
236236
environmentIos: purchase.environmentIos,
237237
};
238238

239-
// After (v2.8.0)
239+
// After (2.8.0)
240240
const subscription = {
241241
expirationDateIOS: purchase.expirationDateIOS,
242242
environmentIOS: purchase.environmentIOS,
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
2-
slug: v2.9
3-
title: v2.9 - OpenIAP Apple Integration
2+
slug: 2.9.0
3+
title: 2.9.0 - OpenIAP Apple Integration
44
authors: [hyochan]
55
tags: [release, openiap, ios, architecture, performance]
66
date: 2025-09-05
77
---
88

9-
# v2.9 Release Notes
9+
# 2.9.0 Release Notes
1010

11-
We're excited to announce v2.9, featuring full integration with OpenIAP Apple that reduces our Swift codebase by **~1,180 lines (73% reduction)**!
11+
We're excited to announce 2.9.0, featuring full integration with OpenIAP Apple that reduces our Swift codebase by **~1,180 lines (73% reduction)**!
1212

1313
<!-- truncate -->
1414

@@ -28,14 +28,14 @@ The core achievement of this release is integrating [OpenIAP Apple](https://gith
2828

2929
## 🏗️ Architecture Evolution
3030

31-
### Before (v2.8.x)
31+
### Before (2.8.x)
3232

3333
```txt
3434
Expo IAP → Custom Swift Implementation → StoreKit 2
3535
(1,620 lines of complex logic)
3636
```
3737

38-
### After (v2.9.0)
38+
### After (2.9.0)
3939

4040
```txt
4141
Expo IAP → OpenIAP Apple → StoreKit 2
@@ -89,9 +89,9 @@ import {OpenIapEvent} from 'expo-iap';
8989
purchaseUpdatedListener((purchase) => {}, OpenIapEvent.PurchaseUpdated);
9090
```
9191

92-
## 🚀 Looking Ahead: v3.0.0
92+
## 🚀 Looking Ahead: 3.0.0
9393

94-
This release sets the foundation for v3.0.0:
94+
This release sets the foundation for 3.0.0:
9595

9696
- **Android**: OpenIAP Android integration (Google Play Billing)
9797
- **Bundle Size**: Further optimizations through shared native libraries
@@ -141,7 +141,7 @@ bun add expo-iap@2.9.0
141141

142142
### Note
143143

144-
- Android native module integration with OpenIAP Android planned for v3.0.0
144+
- Android native module integration with OpenIAP Android planned for 3.0.0
145145

146146
## 🙏 Acknowledgments
147147

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
2-
slug: v3.0
3-
title: Expo IAP 3.0 — OpenIAP Integration, Unified Core, Leaner API
2+
slug: 3.0.0
3+
title: 3.0.0 — OpenIAP Integration, Unified Core, Leaner API
44
tags: [release, breaking-change, android, ios]
55
authors: [hyochan]
66
date: 2025-09-13
77
---
88

9-
Expo IAP 3.0 is a major release that fully integrates [OpenIAP](https://openiap.dev)’s Android and iOS modules. Expo IAP is no longer just a framework bridge — it now leverages a centralized [OpenIAP](https://openiap.dev) core for shared logic across platforms and SDKs. The result is a leaner, more maintainable codebase with faster iteration and greater stability.
9+
Expo IAP 3.0.0 is a major release that fully integrates [OpenIAP](https://openiap.dev)’s Android and iOS modules. Expo IAP is no longer just a framework bridge — it now leverages a centralized [OpenIAP](https://openiap.dev) core for shared logic across platforms and SDKs. The result is a leaner, more maintainable codebase with faster iteration and greater stability.
1010

1111
<!-- truncate -->
1212

docs/blog/2025-09-21-3.1.0.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
slug: 3.1.0
3+
title: 3.1.0 - Full OpenIAP Ecosystem Adoption
4+
authors: [hyochan]
5+
tags: [release, openiap, ios, android, tooling]
6+
date: 2025-09-21
7+
---
8+
9+
# 3.1.0 Release Notes
10+
11+
Expo IAP 3.1.0 graduates the project into the full **OpenIAP ecosystem**. The release ships with three dedicated native stacks:
12+
13+
- **[openiap-apple](https://github.com/hyodotdev/openiap-apple)** — StoreKit 2 implementation for Apple platforms
14+
- **[openiap-google](https://github.com/hyodotdev/openiap-google)** — Google Play Billing integration for Android
15+
- **[openiap-gql](https://github.com/hyodotdev/openiap-gql)** — GraphQL helpers that drive types and tooling
16+
17+
From 3.1.0 onward, Expo IAP stays in lockstep with these modules: Apple **v1.2.2**, Google **v1.2.6**, and GQL **v1.0.8**. That shared version alignment gives Expo IAP stable native compatibility and a unified type system straight from the OpenIAP schema.
18+
19+
<!-- truncate -->
20+
21+
## 🚀 Highlights
22+
23+
- Adopted the full OpenIAP core stack—[openiap-gql](https://github.com/hyodotdev/openiap-gql), [openiap-apple](https://github.com/hyodotdev/openiap-apple) v1.2.2, and [openiap-google](https://github.com/hyodotdev/openiap-google) v1.2.6)—bringing Expo IAP into alignment with the shared ecosystem used across Flutter, React Native, and KMP.
24+
- Trimmed roughly **two thirds** of our custom native bridge code by delegating logic to the OpenIAP modules.
25+
- Expanded automated coverage to about **98%**, spanning purchase flows, native bridge entry points, and error mapping utilities.
26+
27+
## 🔁 OpenIAP Upgrades
28+
29+
- Normalized purchase payloads on both platforms so every bridge call sanitizes platform casing and forwards the complete OpenIAP record.
30+
- Migrated Android to the new `RequestPurchaseProps` / `PurchaseResult` / `ErrorCode` contracts, achieving parity with the Apple module.
31+
- Centralized native dependency versions via [`openiap-versions.json`](https://github.com/hyochan/expo-iap/blob/main/openiap-versions.json); Gradle now fails fast if the Google artifact version is missing and scripts/migrations read from one source of truth.
32+
33+
## 🐞 Bug Fixes
34+
35+
- `fix(android): honor subscription offerToken` ([#214](https://github.com/hyochan/expo-iap/pull/214)) restores proper handling of `subscriptionOfferDetailsAndroid` so Google Play discounts apply reliably.
36+
37+
## 🛡️ Safer Purchases & Better Errors
38+
39+
- `requestPurchase` on iOS explicitly rejects unsupported product types instead of silently treating `all` as `in-app`.
40+
- Error handling now consistently routes through the shared `ErrorCode` table so promise rejections, platform conversions, and predicates remain aligned.
41+
- Additional coverage for `createPurchaseError`, `ErrorCodeUtils`, and the user-friendly error helper keeps error copy in sync with OpenIAP terminology.
42+
43+
## 🛠️ Tooling & Workflow
44+
45+
- Contributor docs clarify how to bump OpenIAP packages, regenerate types, and keep `openiap-versions.json` synchronized for Android and iOS builds.
46+
47+
## ⚠️ Important Changes
48+
49+
- **Transaction identifiers**: `transactionId` is reinstated as the primary store reference (`orderId` on Android, StoreKit transaction ID on iOS). Android’s generic `id` is no longer repurposed for orders; when Google Play omits an `orderId` (typical for consumables), `transactionId` becomes `null` and clients should rely on the unified `purchaseToken` (Android purchase token / iOS JWS). This value is the canonical receipt for server validation. See the related [react-native-iap discussion](https://github.com/hyochan/react-native-iap/discussions/3016).
50+
- **iOS request types**: purchase requests must specify either `in-app` or `subs`. Passing `all` (or any other type) throws an explicit error.
51+
- **Promoted products**: events now emit the full sanitized product payload; downstream listeners should expect the entire object instead of just `productId`.
52+
- **Deprecated helpers removed**: `getProducts`, `requestSubscription`, and `requestProducts` are removed. Use `fetchProducts` with the unified purchase flow.
53+
54+
## Minor Updates
55+
56+
- Removed the legacy `useIAP` state shims (`currentPurchase`, `currentPurchaseError`, and their `clear*` helpers) in favour of the hook’s `onPurchaseSuccess` / `onPurchaseError` callbacks ([#213](https://github.com/hyochan/expo-iap/pull/213)).
57+
58+
## 📦 Installation
59+
60+
```bash
61+
bun add expo-iap@3.1.0
62+
# or
63+
npm install expo-iap@3.1.0
64+
# or
65+
yarn add expo-iap@3.1.0
66+
```
67+
68+
## 🔗 References
69+
70+
- Recent work: [Closed pull requests](https://github.com/hyochan/expo-iap/pulls?q=is%3Apr+is%3Aclosed)
71+
- Release builds on the OpenIAP ecosystem: [openiap.dev](https://openiap.dev)
72+
73+
Enjoy the smoother upgrade path and richer diagnostics shipped in 3.1.0! Let us know how it goes via [GitHub issues](https://github.com/hyochan/expo-iap/issues).

0 commit comments

Comments
 (0)