A trial grants the entitlement immediately without charging. CashSDK emits
trial.started when the trial begins. If the customer keeps the
subscription, the first renewal fires subscription.renewed; if they
cancel before conversion, you get subscription.canceled and, at period
end, subscription.expired. The entitlement stays active for the full trial
window either way.
Subscriptions
How CashSDK models the subscription lifecycle — trials, intro offers, renewals, grace periods, upgrades, and refunds.
CashSDK tracks the full subscription lifecycle across Apple and Google and normalizes it into a single model. Your app checks an entitlement; your backend reacts to webhook events. You never parse store notifications by hand.
The lifecycle at a glance#
A subscription moves through states as the store bills, renews, and eventually cancels it. Each transition emits an event and updates the customer's entitlement in real time.
Free trials
Introductory & promo offers
Intro offers (discounted first period, pay-as-you-go, or pay-up-front) are modeled as part of the product. The customer's active offer is reflected on the transaction so you can attribute revenue correctly. Promo codes and win-back offers flow through the same lifecycle events.
Renewals
When the store bills a renewal, CashSDK validates it server-side and emits
subscription.renewed with the new expiration date. The entitlement's
active window extends automatically — no client action needed.
Grace periods & billing retry
If a renewal payment fails, the store enters billing retry. CashSDK keeps
the entitlement active during the grace period so paying-in-good-faith
customers aren't locked out. You'll see the subscription flagged as in grace;
on recovery you get subscription.renewed, and only if recovery fails does
subscription.expired fire.
Upgrades, downgrades & proration
When a customer switches plans within the same subscription group, the store
handles proration and CashSDK reconciles the entitlement. Upgrades take
effect immediately; downgrades typically take effect at the next renewal.
Because your app checks the pro entitlement rather than a specific product,
plan changes need no client logic.
Cancellations & expirations
Turning off auto-renew emits subscription.canceled — but the entitlement
stays active until the paid period ends. When the period actually ends
without renewal, subscription.expired fires and the entitlement is
revoked.
Refunds & revocations
When Apple or Google issues a refund or revokes a purchase, CashSDK emits
refund.issued and revokes the entitlement. Use this to reclaim access and
reconcile revenue.
React with webhooks#
Subscribe to the events that matter and let CashSDK push state changes to your backend:
{
"id": "evt_2f9c1a",
"type": "subscription.renewed",
"created": 1752787200,
"data": {
"app_user_id": "u_812",
"product_id": "pro_monthly",
"entitlement": "pro",
"expires_at": "2026-08-17T00:00:00Z",
"environment": "production"
}
}
Never expire access on a timer in your own code. Let CashSDK be the source of truth — grace periods, billing retry, and refunds all change the effective expiration in ways only server-side validation can see.
Check state anywhere#
- On device —
result.entitlements["pro"]?.isActiveafter a purchase orCashSDK.offerings()/CashSDK.restorePurchases()on launch. - Server-side —
GET /v1/apps/{app}/customers/{app_user_id}returns the customer's active entitlements and their expiration.