Checkout, webhooks, credits, subscriptions — server-side, production-ready.
The MVP includes a complete Stripe integration: checkout sessions, webhook handling, credit management with optimistic locking, and subscription lifecycle. All server-side. All wired to your users.
Set your Stripe keys in env vars (STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET). The MVP registers webhook handlers and checkout session creation automatically.
When a user upgrades, the MVP creates a Stripe Checkout session linked to their vibe_app user ID. After payment, the webhook handler updates their tier and credits in the database.
Subscription lifecycle events (renewal, cancellation, payment failure) are handled by webhook routes that update the user's status in real time. No polling, no cron jobs.
Credit management uses optimistic locking to prevent race conditions — if two requests try to deduct credits simultaneously, one succeeds and the other retries with the updated balance.
The MVP provides a server-side checkout endpoint that creates Stripe Checkout sessions. The session is pre-populated with the user's email (from their vibe_app profile) and the selected plan. After payment, Stripe redirects to your success page. The webhook fires simultaneously and updates the user's tier in the database. The user sees their new tier immediately on redirect — no delay, no "processing" screen.
// Creating a checkout session (built into MVP)
// POST /api/billing/checkout
{
"priceId": "price_1234", // Stripe price ID
"successUrl": "/dashboard",
"cancelUrl": "/pricing"
}
// The MVP handles:
// - Links session to vibe_app user ID
// - Sets customer email from user profile
// - Creates/reuses Stripe customer record
// - Returns checkout URL for redirectThe MVP registers handlers for the critical Stripe webhook events: - checkout.session.completed — user paid, upgrade their tier - customer.subscription.updated — plan change or renewal - customer.subscription.deleted — cancellation, downgrade to free - invoice.payment_failed — flag the account, send notification Webhook signature verification is handled automatically. Each event is logged to the audit trail with the Stripe event ID for reconciliation.
// Webhook events handled automatically
// at POST /api/billing/webhook
// You can add custom logic for any event:
import { onStripeEvent } from '@payez/next-mvp';
onStripeEvent('checkout.session.completed',
async (event, user) => {
// Custom logic after payment
// user is already resolved from Stripe metadata
await sendWelcomeEmail(user.email);
await provisionResources(user.id);
}
);For usage-based billing (API calls, storage, AI tokens), the MVP provides a credit system with optimistic locking. Credits are stored per-user with a version column. Deductions use UPDATE ... WHERE version = expected_version — if another request modified the balance first, the deduction retries with the updated version. This prevents the classic race condition: user has 10 credits, two requests arrive simultaneously, both read 10, both deduct 1, user ends up with 9 instead of 8.
// Credit deduction with optimistic locking
// (handled by the MVP's credit service)
// Attempt 1: read balance
// { credits: 10, version: 5 }
// Deduct:
UPDATE vibe_app.user_credits
SET credits = credits - 1,
version = version + 1
WHERE user_id = 42
AND version = 5; -- optimistic lock
// If version changed (concurrent update):
// 0 rows affected → retry with fresh read
// If version matches: 1 row affected → successThe tier system and Stripe integration work together. When a user's subscription status changes (via webhook), their tier updates in the database. Middleware reads the tier on every request and enforces limits. See the Tier System page for details on how limits are configured and enforced per feature.
- No Stripe Checkout session creation logic - No webhook signature verification - No subscription lifecycle state machine - No credit balance race condition handling - No Stripe customer ↔ app user mapping - No payment failure retry logic - No plan change proration calculations You configure your Stripe products/prices in the Stripe dashboard, set the env vars, and the MVP handles the rest.
Stripe Integration ships with every @payez/next-mvp install. 10K MAU free. No credit card required.