Commit e92746e
authored
feat: add subscription status APIs (#522)
This PR implements standardized subscription management APIs as
specified in the OpenIAP specification, providing a unified way to check
subscription status across iOS and Android platforms with automatic
detection of all active subscriptions and platform-specific details like
iOS expiration dates and Android auto-renewal status.
## OpenIAP Specification References
-
[getActiveSubscriptions](https://www.openiap.dev/docs/apis#getactivesubscriptions)
-
[hasActiveSubscriptions](https://www.openiap.dev/docs/apis#hasactivesubscriptions)
- [ActiveSubscription
Type](https://www.openiap.dev/docs/types#activesubscription)
## Changes
### New APIs
- Add `getActiveSubscriptions()` to retrieve detailed subscription
information
- Returns list of `ActiveSubscription` objects with platform-specific
fields
- Supports optional filtering by subscription IDs
- Automatically detects all active subscriptions when no filter provided
- Add `hasActiveSubscriptions()` for simple boolean subscription checks
- Returns `true` if user has any active subscriptions
- Supports optional filtering by specific subscription IDs
- Handles errors gracefully by returning `false`
### Type System
- Add `ActiveSubscription` model with platform-specific fields:
- **iOS**: `expirationDateIOS`, `environmentIOS`,
`daysUntilExpirationIOS`
- **Android**: `autoRenewingAndroid`
- **Cross-platform**: `productId`, `isActive`, `willExpireSoon` (within
7 days)
### Code Quality
- Rename `IAPPlatform` to `IapPlatform` following Dart naming
conventions
- Fix type casting issues in `extractPurchased` and `extractItems`
utilities
- Add proper iOS transaction state mapping in `_convertToPurchase`
- Replace `getCurrentPlatform()` calls with instance-based platform
detection
### Testing
- Add comprehensive unit tests for both iOS and Android platforms
- Test subscription filtering functionality
- Verify platform-specific field population
## Usage Example
```dart
// Get all active subscriptions
final subscriptions = await FlutterInappPurchase.instance.getActiveSubscriptions();
// Check specific subscriptions
final hasMonthly = await FlutterInappPurchase.instance.hasActiveSubscriptions(
subscriptionIds: ['monthly_subscription', 'yearly_subscription'],
);
// Access platform-specific information
for (final sub in subscriptions) {
if (Platform.isIOS && sub.daysUntilExpirationIOS != null) {
print('Expires in ${sub.daysUntilExpirationIOS} days');
}
if (Platform.isAndroid && sub.autoRenewingAndroid == true) {
print('Auto-renewing subscription');
}
}
```
## Breaking Changes
None - these are new additions to the API surface.
## Migration Notes
- Developers using custom subscription checking logic can migrate to
these standardized APIs
- The deprecated `checkSubscribed()` method (removed in v6.0.0) can now
be replaced with `hasActiveSubscriptions()`
## Related
- OpenIAP Discussion: https://github.com/hyochan/openiap.dev/discussions
- Reference Implementation: hyochan/expo-iap#1581 parent f671fe6 commit e92746e
File tree
8 files changed
+526
-84
lines changed- example/lib/src/screens
- lib
- test
8 files changed
+526
-84
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | 64 | | |
76 | 65 | | |
77 | 66 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
174 | | - | |
| 174 | + | |
175 | 175 | | |
176 | 176 | | |
177 | 177 | | |
| |||
190 | 190 | | |
191 | 191 | | |
192 | 192 | | |
193 | | - | |
| 193 | + | |
194 | 194 | | |
195 | 195 | | |
196 | 196 | | |
| |||
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
252 | | - | |
| 252 | + | |
253 | 253 | | |
254 | 254 | | |
255 | 255 | | |
| |||
324 | 324 | | |
325 | 325 | | |
326 | 326 | | |
327 | | - | |
| 327 | + | |
328 | 328 | | |
329 | 329 | | |
330 | 330 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
92 | | - | |
| 92 | + | |
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| |||
104 | 104 | | |
105 | 105 | | |
106 | 106 | | |
107 | | - | |
| 107 | + | |
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
| |||
175 | 175 | | |
176 | 176 | | |
177 | 177 | | |
178 | | - | |
| 178 | + | |
179 | 179 | | |
180 | | - | |
| 180 | + | |
181 | 181 | | |
182 | 182 | | |
183 | 183 | | |
| |||
196 | 196 | | |
197 | 197 | | |
198 | 198 | | |
199 | | - | |
200 | | - | |
| 199 | + | |
| 200 | + | |
201 | 201 | | |
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
206 | 206 | | |
207 | 207 | | |
208 | | - | |
209 | | - | |
| 208 | + | |
| 209 | + | |
210 | 210 | | |
211 | 211 | | |
212 | 212 | | |
| |||
0 commit comments