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

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.

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:

json
{
  "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"
  }
}

Check state anywhere#

  • On deviceresult.entitlements["pro"]?.isActive after a purchase or CashSDK.offerings() / CashSDK.restorePurchases() on launch.
  • Server-sideGET /v1/apps/{app}/customers/{app_user_id} returns the customer's active entitlements and their expiration.

Next steps#