Iaptic provides a comprehensive solution for managing in-app subscriptions across all major platforms. This guide explains our approach to handling recurring payments, subscription lifecycles, and entitlement management.
Why Subscription Management Matters?
Modern apps increasingly rely on subscription models for sustainable revenue. However, managing recurring payments presents unique challenges:
- Platform fragmentation: Different rules for Apple, Google, and others
- Renewal tracking: Handling successful/unsuccessful renewals
- Entitlement management: Track which users have access to a subscription
- Special cases: Handling payment failures, recovery, paused subscriptions, family sharing, etc.
Iaptic solves these challenges through our unified API and dashboard tools.
Core Concepts
1. Subscription Lifecycle Management
stateDiagram-v2
direction LR
[*] --> Active
Active --> Active : Renewal\nSuccess
Active --> Expired : Non-renewal
Active --> GracePeriod : Payment\nIssue
GracePeriod --> Active : Payment\nRecovered
GracePeriod --> Expired
Active --> Paused
Paused --> Active
classDef activeState fill:#90EE90
classDef graceState fill:#90EE90
classDef expiredState fill:#FFB6C1
classDef pausedState fill:#FFA500
class Active,GracePeriod activeState
class Expired expiredState
class Paused pausedState
note right of Paused : Access\nsuspended
Key State Behaviors:
-
Active: Full access, next charge pending
-
isPaused: Access temporarily suspended
-
isBillingRetryPeriod: Platform dependent retry window
-
Expired: Access revoked, manual renewal required
Iaptic tracks platform-reported states and updates the expirationDate
field accordingly. Your app should:
- Compare current time with
expirationDate
or use theisExpired
field (which is set by iaptic when returning a subscription from the API). - Check
cancellationReason
for voluntary/involuntary expiration. - Monitor webhooks for state changes.
2. Cross-Platform Harmonization
Iaptic abstracts platform-specific behaviors while surfacing important details in a unified format.
Platform | Key Differences Handled |
---|---|
Apple App Store | Introductory pricing, family sharing |
Google Play | Account hold, pause and resume options |
Check the Purchase class for information about the unified purchase object.
At the most high level, you can simply check the expirationDate
field, and if it's in the past, it means the user is not entitled to the subscription anymore (be it because it's paused, on hold, expired or has been refunded). To adapt you UI to the reason why the subscription is expired you can use:
cancellationReason
field to know more about why the subscription is expired.isPaused
field to know if the subscription is paused by the user or the system.isBillingRetryPeriod
field to know if the subscription is in the grace period.discountId
field to know if the subscription has a discount or introductory pricing applied.
See the Platform Specific Notes section for more details on how platform specific states are represented in the unified purchase object.
Implementation Workflow
-
Configure Products
- Set up subscription tiers in platform developer consoles
- Sync with Iaptic using our Dashboard UI or Sync API
-
Integrate Client Library
- Use our React Native, Cordova, or Swift SDKs
- Implement purchase flows with built-in UI components
-
Handle Server-Side Logic
- Set up webhook endpoints
- Implement entitlement checks
- Configure subscription analytics
-
Monitor & Optimize
- Use Dashboard Reports
- Set up Email Alerts
- Analyze with Claude AI Integration
Automatic Renewal
Each platform is responsible for automatically renewing subscriptions, iaptic is notified when a renewal occurs.
Entitlement Enforcement
Iaptic tracks subscription access using configurable entitlement strategies, to know which users are entitled to a given subscription.
flowchart TD
Subscription -->|Entitlement Strategy| User1
Subscription -->|Entitlement Strategy| User2
Subscription -->|Entitlement Strategy| User3
Key features:
- Multiple strategies supported
- Automatic updates when purchase status changes
- Webhook notifications on entitlement changes
entitledUsers
array in Purchase objects.
Learn more about entitlement strategies.
Common Scenarios
New Subscription
sequenceDiagram
participant App
participant Iaptic
participant Server
Note over App: User completes purchase
App->>Iaptic: Receipt+UserID
Iaptic->>Server: PURCHASED
- User initiates subscription
- Platform processes payment
- Iaptic:
- Creates unified purchase record
- Adds initial transaction
- Sets
expirationDate
based on platform data - Triggers
purchases.updated
webhook with:- notification.reason
PURCHASED
- notification.purchaseId: the ID of that subscription
- notification.reason
Successful Renewal
sequenceDiagram
participant Platform
participant Iaptic
participant Server
Platform->>Iaptic: Renewal notification
Iaptic->>Server: purchases.updated (RENEWED)
Server->>Iaptic: 200 OK
Renewal Process:
- Platform processes recurring payment
- Iaptic:
- Adds new transaction to existing purchase
- Updates
expirationDate
andlastRenewalDate
- Triggers
purchases.updated
webhook with:- notification.reason
RENEWED
- notification.purchaseId: the ID of that subscription
- notification.reason
Failed Payment & Recovery
sequenceDiagram
participant Platform
participant Iaptic
participant Server
Platform->>Iaptic: Payment failed
Iaptic->>Server: ENTERED_GRACE_PERIOD
Note over Platform: Retry logic
Platform->>Iaptic: Renewed or Expired
alt Success
Iaptic->>Server: RENEWED
else Failure
Iaptic->>Server: EXPIRED
end
- Platform payment fails
- Iaptic:
- Sets
isBillingRetryPeriod: true
- Updates
expirationDate
to the end of the grace period - Triggers
purchases.updated
webhook with:- notification.reason
ENTERED_GRACE_PERIOD
- notification.purchaseId: the ID of that subscription
- notification.reason
- Sets
- Platform manages retries
- Final outcome:
- Success: Clear retry status and triggers
purchases.updated
withRENEWED
- Failure: Set
expirationDate
and triggerpurchases.updated
withEXPIRED
- Success: Clear retry status and triggers
Dashboard Usage
Locate subscriptions using platform-specific identifiers:
Platform | Search Field | Example Value |
---|---|---|
Apple | Original Transaction | 1000000123456789 |
Apple | Line Item ID | 1234567890 |
Order ID | GPA.1234-5678-9012 |
|
Stripe | Subscription ID | sub_ABC123DEF456 |
Stripe | Invoice ID | in_1234567890 |
All | Application Username | prod_123456 |
Getting Started
Check our Getting Started page and Stripe Integration page for more details.
For complex implementations, consider our Professional Services offering.
Platform Specific Notes
Apple App Family Sharing
field | value |
---|---|
isSharedPurchase |
true |
Apple App Store and Google Play Grace Period
field | value |
---|---|
isBillingRetryPeriod |
true |
expirationDate |
the end of the grace period (in the future) |
isExpired |
false |
Google Play Paused Subscriptions
If allowed, users can pause their Google Play subscriptions. To simplify handling of that use case, Iaptic reports is as expired (so your server can only rely on expirationDate to know if the user has access).
field | value |
---|---|
expirationDate |
last renewal date or purchase date (in the past) |
isExpired |
true |
isPaused |
true |
Google Play On Hold Subscriptions
When a subscription failed to renew due to a billing error, Google marks it as "on hold" for a few days while it tries to recover. In that timeframe, the subscription is considered as expired. Iaptic reports the following:
field | value |
---|---|
expirationDate |
actual expiry date (in the past) |
isPaused |
true |
isExpired |
true |
isBillingRetryPeriod |
true |
cancelationReason |
System.BillingError |
Apple's implicit On Hold
When a Apple subscription is expired, Apple implicitely considers it "On Hold" for 60 days, which means that if the user re-subscribe in that time frame, the same subscription will be renewed instead of generating a new purchase.
Data is just as with expired subscription.
field | value |
---|---|
expirationDate |
actual expiration date (in the past) |
isExpired |
true |
cancellationReason |
The actual reason set by the customer or the system |
If isBillingRetryPeriod
is true
, it means that the subscription is still in the 60 days billing retry period.
Stripe
- Enables custom billing cycles. See Stripe Products with Iaptic
- Supports prorations for plan changes.