Skip to content

Commit 4cee870

Browse files
authored
feat: add standardized DiscountOffer and SubscriptionOffer types (#63)
- Add new cross-platform types: DiscountOffer, SubscriptionOffer, DiscountOfferType, PaymentMode, SubscriptionPeriod, SubscriptionPeriodUnit - Use flat structure with platform-specific suffixes (offerTokenAndroid, keyIdentifierIOS, etc.) - Deprecate old platform-specific types for migration path - Update Android BillingConverters to populate new standardized fields - Update iOS StoreKitTypesBridge to convert StoreKit offers to standardized types - Add Horizon flavor support with null/empty defaults - Add comprehensive unit tests for both platforms - Update example apps to use new standardized offer types - Add documentation page for offer types <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced standardized cross-platform DiscountOffer and SubscriptionOffer types and surfaced them across product/subscription APIs; subscription UI now displays intro/promotional badges (e.g., "Free Trial"). * **Documentation** * Added Offer Types docs, migration guidance, updated platform type pages/TLDRs, and comprehensive per-platform sync/workflow guides. * **Deprecations** * Marked platform-specific offer types/fields as deprecated in favor of standardized types. * **Tests** * Expanded unit tests covering new offer types, enums, period/serialization, and integration with product models. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 49427b5 commit 4cee870

28 files changed

Lines changed: 7205 additions & 94 deletions

File tree

.claude/commands/sync-all-platforms.md

Lines changed: 461 additions & 0 deletions
Large diffs are not rendered by default.

.claude/commands/sync-expo-iap.md

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
# Sync Changes to expo-iap
2+
3+
Synchronize OpenIAP changes to the [expo-iap](https://github.com/hyochan/expo-iap) repository.
4+
5+
**Target Repository:** `$IAP_REPOS_HOME/expo-iap`
6+
7+
> **Note:** Set `IAP_REPOS_HOME` environment variable (see [sync-all-platforms.md](./sync-all-platforms.md#environment-setup))
8+
9+
## Project Overview
10+
11+
- **Package Manager:** Bun
12+
- **Framework:** Expo Module (React Native)
13+
- **Current Version:** Check `package.json`
14+
- **OpenIAP Version Tracking:** `openiap-versions.json`
15+
16+
## Key Files
17+
18+
| File | Purpose | Auto-Generated |
19+
|------|---------|----------------|
20+
| `src/types.ts` | TypeScript types from OpenIAP | YES |
21+
| `src/index.ts` | Main API exports | NO |
22+
| `src/useIAP.ts` | React Hook for IAP | NO |
23+
| `src/modules/ios.ts` | iOS-specific functions | NO |
24+
| `src/modules/android.ts` | Android-specific functions | NO |
25+
| `openiap-versions.json` | Version tracking | NO |
26+
27+
## Sync Steps
28+
29+
### 0. Pull Latest (REQUIRED)
30+
31+
**Always pull the latest code before starting any sync work:**
32+
33+
```bash
34+
cd $IAP_REPOS_HOME/expo-iap
35+
git pull
36+
```
37+
38+
### 1. Sync openiap-versions.json (REQUIRED)
39+
40+
**IMPORTANT:** Before generating types, sync version numbers from openiap monorepo.
41+
42+
```bash
43+
cd $IAP_REPOS_HOME/expo-iap
44+
45+
# Check current versions in openiap monorepo
46+
cat $OPENIAP_HOME/openiap/openiap-versions.json
47+
48+
# Update expo-iap's openiap-versions.json to match:
49+
# - "gql": should match openiap's "gql" version
50+
# - "apple": should match openiap's "apple" version
51+
# - "google": should match openiap's "google" version
52+
```
53+
54+
**Version fields to sync:**
55+
| Field | Source | Purpose |
56+
|-------|--------|---------|
57+
| `gql` | `$OPENIAP_HOME/openiap/openiap-versions.json` | TypeScript types version |
58+
| `apple` | `$OPENIAP_HOME/openiap/openiap-versions.json` | iOS native SDK version |
59+
| `google` | `$OPENIAP_HOME/openiap/openiap-versions.json` | Android native SDK version |
60+
61+
### 2. Type Synchronization
62+
63+
```bash
64+
cd $IAP_REPOS_HOME/expo-iap
65+
66+
# Download and regenerate types (uses versions from openiap-versions.json)
67+
bun run generate:types
68+
69+
# Verify types
70+
bun run typecheck
71+
```
72+
73+
### 3. Native Code Modifications
74+
75+
#### iOS Native Code
76+
77+
**Location:** `ios/`
78+
79+
Key files to update:
80+
- `ios/ExpoIapModule.swift` - Main Expo module implementation
81+
- `ios/ExpoIap.podspec` - CocoaPods spec (update `apple` version dependency)
82+
83+
**When to modify:**
84+
- New iOS-specific API methods added to OpenIAP
85+
- Type conversion changes needed
86+
- StoreKit 2 API changes
87+
88+
**Update workflow:**
89+
```bash
90+
cd $IAP_REPOS_HOME/expo-iap
91+
92+
# 1. Update apple version in openiap-versions.json
93+
# 2. Review openiap/packages/apple/Sources/ for changes
94+
# 3. Update ios/ExpoIapModule.swift accordingly
95+
96+
# Install updated pod
97+
cd example/ios && pod install --repo-update
98+
```
99+
100+
#### Android Native Code
101+
102+
**Location:** `android/src/main/java/`
103+
104+
Key files to update:
105+
- `ExpoIapModule.kt` - Main Expo module implementation
106+
- `build.gradle` - Dependencies (auto-reads `google` version)
107+
108+
**When to modify:**
109+
- New Android-specific API methods added to OpenIAP
110+
- Type conversion changes needed
111+
- Play Billing API changes
112+
113+
**Update workflow:**
114+
```bash
115+
cd $IAP_REPOS_HOME/expo-iap
116+
117+
# 1. Update google version in openiap-versions.json
118+
# 2. Review openiap/packages/google/openiap/src/main/ for changes
119+
# 3. Update android/src/main/java/ accordingly
120+
121+
# Gradle auto-syncs on build
122+
```
123+
124+
### 4. Build & Test Native Code
125+
126+
#### iOS Build Test
127+
128+
```bash
129+
cd $IAP_REPOS_HOME/expo-iap/example
130+
131+
# Clean and prebuild
132+
npx expo prebuild --clean --platform ios
133+
134+
# Install pods
135+
cd ios && pod install --repo-update && cd ..
136+
137+
# Build for simulator
138+
npx expo run:ios --device "iPhone 15 Pro"
139+
140+
# Or build via Xcode
141+
open ios/expoiapexample.xcworkspace
142+
# Build: Cmd+B, Run: Cmd+R
143+
```
144+
145+
#### Android Build Test
146+
147+
```bash
148+
cd $IAP_REPOS_HOME/expo-iap/example
149+
150+
# Clean and prebuild
151+
npx expo prebuild --clean --platform android
152+
153+
# Build debug APK
154+
npx expo run:android
155+
156+
# Or build via Android Studio
157+
# Open android/ folder in Android Studio
158+
# Build > Make Project
159+
```
160+
161+
#### Android Horizon Build (Meta Quest)
162+
163+
```bash
164+
cd $IAP_REPOS_HOME/expo-iap/example
165+
166+
# Enable Horizon flavor in gradle.properties
167+
echo "horizonEnabled=true" >> android/gradle.properties
168+
169+
# Prebuild and build with Horizon
170+
npx expo prebuild --clean --platform android
171+
npx expo run:android
172+
173+
# Revert for Play Store builds
174+
sed -i '' '/horizonEnabled=true/d' android/gradle.properties
175+
```
176+
177+
#### Full Build Matrix
178+
179+
```bash
180+
cd $IAP_REPOS_HOME/expo-iap
181+
182+
# TypeScript build
183+
bun run build
184+
185+
# iOS build
186+
cd example && npx expo run:ios
187+
188+
# Android build (Play Store)
189+
cd example && npx expo run:android
190+
191+
# Android build (Horizon)
192+
cd example && echo "horizonEnabled=true" >> android/gradle.properties && npx expo run:android
193+
194+
# All tests
195+
bun run test
196+
cd example && bun run test
197+
```
198+
199+
### 5. Update Example Code
200+
201+
**Location:** `example/app/`
202+
203+
Key example screens:
204+
- `index.tsx` - Home/Overview
205+
- `purchase-flow.tsx` - Purchase flow demo
206+
- `subscription-flow.tsx` - Subscription demo
207+
- `alternative-billing.tsx` - Android alt billing
208+
- `offer-code.tsx` - Promo code redemption
209+
210+
### 6. Update Tests
211+
212+
**Library Tests:** `src/__tests__/`
213+
**Example Tests:** `example/__tests__/`
214+
215+
```bash
216+
# Run all tests
217+
bun run test
218+
219+
# Run example tests
220+
cd example && bun run test
221+
```
222+
223+
### 7. Update Documentation
224+
225+
**Location:** `docs/`
226+
- `docs/api/` - API reference
227+
- `docs/guides/` - Usage guides
228+
- `docs/examples/` - Code examples
229+
230+
### 8. Update llms.txt Files
231+
232+
**Location:** `docs/static/`
233+
234+
Update AI-friendly documentation files when APIs or types change:
235+
236+
- `docs/static/llms.txt` - Quick reference for AI assistants
237+
- `docs/static/llms-full.txt` - Detailed AI reference
238+
239+
**When to update:**
240+
- New API functions added
241+
- Function signatures changed
242+
- New types or enums added
243+
- Usage patterns updated
244+
- Error codes changed
245+
246+
**Content to sync:**
247+
1. Installation commands
248+
2. Core API reference (useIAP hook, direct functions)
249+
3. Key types (Product, Purchase, ErrorCode)
250+
4. Common usage patterns
251+
5. Platform-specific APIs (iOS/Android suffixes)
252+
6. Error handling examples
253+
254+
### 9. Pre-commit Checklist
255+
256+
```bash
257+
bun run lint # ESLint
258+
bun run typecheck # TypeScript
259+
bun run test # Jest
260+
cd example && bun run test # Example app tests
261+
```
262+
263+
## Naming Conventions
264+
265+
- **iOS-only:** `functionNameIOS` (e.g., `syncIOS`, `getPromotedProductIOS`)
266+
- **Android-only:** `functionNameAndroid` (e.g., `validateReceiptAndroid`)
267+
- **Cross-platform:** No suffix (e.g., `fetchProducts`, `requestPurchase`)
268+
- **Error codes:** kebab-case (e.g., `'user-cancelled'`)
269+
270+
## Deprecation Check
271+
272+
Search for deprecated patterns:
273+
```bash
274+
cd $IAP_REPOS_HOME/expo-iap
275+
grep -r "@deprecated" src/
276+
grep -r "DEPRECATED" src/
277+
```
278+
279+
Known deprecated functions:
280+
- `requestProducts` -> Use `fetchProducts`
281+
- `validateReceipt` -> Use `verifyPurchase`
282+
- `validateReceiptIOS` -> Use `verifyPurchase`
283+
284+
## Commit Message Format
285+
286+
```text
287+
feat: add discount offer support
288+
fix: resolve iOS purchase verification
289+
docs: update subscription flow guide
290+
```
291+
292+
## References
293+
294+
- **CLAUDE.md:** `$IAP_REPOS_HOME/expo-iap/CLAUDE.md`
295+
- **OpenIAP Docs:** [openiap.dev/docs](https://openiap.dev/docs)
296+
- **expo-iap Docs:** [expo-iap.vercel.app](https://expo-iap.vercel.app)

0 commit comments

Comments
 (0)