Appearance
Stripe Subscriptions
FreshSource: shipfa.st/docs/tutorials/subscriptions
INFO
The flow is the same for one-time payments. For Lemon Squeezy, see the Payments feature.
Prerequisites
Procedure
Step 1: Create a Stripe Product
- In Stripe Dashboard, click More+ > Product Catalog > + Add Product
- Set a name and monthly price
- Click Save Product
- Copy the price ID (starts with
price_) toconfig.stripe.plans[0].priceIdinconfig.js
Step 2: Add Checkout to Dashboard
javascript
import ButtonAccount from "@/components/ButtonAccount";
import ButtonCheckout from "@/components/ButtonCheckout";
import config from "@/config";
export const dynamic = "force-dynamic";
export default async function Dashboard() {
return (
<main className="min-h-screen p-8 pb-24">
<section className="max-w-xl mx-auto space-y-8">
<ButtonAccount />
<h1 className="text-3xl md:text-4xl font-extrabold">
Subscribe to get access:
</h1>
<ButtonCheckout
mode="subscription"
priceId={config.stripe.plans[0].priceId}
/>
</section>
</main>
);
}Step 3: Test the Payment
- Open
http://localhost:3000/dashboard - Log in and click the subscribe button
- Use test card:
4242 4242 4242 4242
Step 4: Webhook Handling
The webhook at /api/webhook/stripe/route.js handles:
- Setting
hasAccessboolean on the User model - Processing
checkout.session.completedevents
WARNING
You need a Stripe local endpoint running for dev mode.
Step 5: Customize
- Add business logic in
/api/webhook/stripe/route.js(abandoned cart emails, credits, etc.) - Users manage accounts with
<ButtonAccount />(cancel, update card)
Verification Checklist
- [ ] Product created in Stripe with price ID
- [ ] Price ID added to config.js
- [ ] Test payment succeeds with 4242 card
- [ ] Webhook sets hasAccess to true
- [ ] ButtonAccount allows subscription management