Feature · Churn reduction · Stripe + Google
Subscription pause
When a user is about to cancel, offering "pause 3 months instead" recovers many of them. Stubkit models pause as a first-class subscription state with dedicated APIs and dashboard controls.
Platform support
| Provider | Support | How pause is triggered |
|---|---|---|
| Stripe | ✓ | Dashboard button → stubkit calls subscriptions.update pause_collection.behavior=void |
| Google Play | ✓ | User-initiated in the Play app or via Play Billing client API; Google sends RTDN notificationType 10, stubkit flips status. |
| Apple | ❌ | Apple doesn't support pause. Offer cancel + win-back campaign instead — see Win-back campaigns. |
Dashboard flow
- Open
/users/<user_id> - Active Stripe subscription rows show a Pause button
- Click — stubkit calls Stripe's update endpoint. Stripe fires
customer.subscription.updatedback. The consumer Worker flips status topausedwith a freshpaused_attimestamp. - The row now shows a Resume button that clears the pause.
REST API
POST /v1/admin/subscriptions/:id/pause
Authorization: Bearer sk_live_...
{
"action": "pause", // or "resume"
"resume_at": 1798761600000 // optional unix ms for auto-resume
}State machine
Pause transitions preserve expires_at — the billing period does NOT advance while paused. Resume extends by the pause window on Google Play (Google updates the expiry); Stripe does not auto-extend (customer is billed from the next renewal date).
Entitlement reads return status: "paused". Treat this exactly like cancelled in your app — isActive() returns false.