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