Back to Blogs
Instant Pay vs. Subscription: A Comedy of Errors (and Best Practices)
Handling immediate one-time payments versus complex recurring subscription lifecycles. I share my horror stories and the ultimate best practices for payment gateway integrations.
## The Payments Nightmare
Integrating a basic instant-pay gateway seems easy. You charge $10, Stripe fires a webhook, and you grant the user a digital product. It's a linear, predictable flow.
However, subscriptions are a chaotic state machine.
## The Subscriptions State Machine
When a user subscribes, you aren't just handling a payment. You have to handle:
- **Proration:** What happens if they upgrade mid-month?
- **Dunning:** What if their credit card expires next month? Do you revoke access immediately or give a 3-day grace period?
- **Cancellations vs. Expirations:** If a user cancels, they usually still have access until the billing period ends. Your database must distinctly track `cancel_at_period_end` versus actual `status = canceled`.
## Webhooks are your source of truth
Never trust the client-side return URL. A user might close the tab while the payment processes. Always, absolutely always, rely on your server's Webhook listeners (e.g., `invoice.payment_succeeded`) to update database entitlements.
Building subscription logic taught me that writing code isn't about the happy path—it's about gracefully handling the thousand ways a payment can fail.
Loved this read? Read on Medium