Stripe Integration
Accept payments, manage subscriptions, and handle billing in your INSTROC app with Stripe.
Setup
1. Create a Stripe Account
If you don't have one, sign up at stripe.com.
2. Get Your API Keys
- Go to Stripe Dashboard
- Copy your Publishable key (
pk_test_...orpk_live_...) - Copy your Secret key (
sk_test_...orsk_live_...)
3. Connect to INSTROC
- Open your project in INSTROC
- Go to Project Settings → Integrations
- Click Stripe → Connect
- Enter both API keys
- Click Save
Use Cases
One-Time Payments
Accept single payments with Stripe Checkout:
AI prompt:
Add a "Buy Now" button that creates a Stripe checkout
session for a $49 product called "Premium Template"
Generated code:
// app/api/checkout/route.ts
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(request: Request) {
const { productName, amount } = await request.json();
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [{
price_data: {
currency: 'usd',
product_data: { name: productName },
unit_amount: amount * 100, // Stripe uses cents
},
quantity: 1,
}],
mode: 'payment',
success_url: `${process.env.NEXT_PUBLIC_URL}/success`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/cancel`,
});
return Response.json({ url: session.url });
}
Subscriptions
Set up recurring billing:
AI prompt:
Create a pricing page with 3 subscription tiers that
use Stripe for recurring payments
Code for subscription checkout:
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [{
price: 'price_xxxxx', // Your Stripe Price ID
quantity: 1,
}],
mode: 'subscription',
success_url: `${process.env.NEXT_PUBLIC_URL}/dashboard`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
});
Payment Links
Create shareable payment links:
const paymentLink = await stripe.paymentLinks.create({
line_items: [{
price: 'price_xxxxx',
quantity: 1,
}],
});
// Share paymentLink.url
Webhooks
Handle Stripe events in your app:
1. Create Webhook Endpoint
// app/api/webhook/stripe/route.ts
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(request: Request) {
const body = await request.text();
const sig = request.headers.get('stripe-signature')!;
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(
body,
sig,
process.env.STRIPE_WEBHOOK_SECRET!
);
} catch (err) {
return Response.json({ error: 'Invalid signature' }, { status: 400 });
}
switch (event.type) {
case 'checkout.session.completed':
const session = event.data.object as Stripe.Checkout.Session;
// Handle successful payment
await handlePaymentSuccess(session);
break;
case 'customer.subscription.updated':
const subscription = event.data.object as Stripe.Subscription;
// Handle subscription change
await updateUserSubscription(subscription);
break;
case 'customer.subscription.deleted':
// Handle cancellation
break;
}
return Response.json({ received: true });
}
2. Register Webhook in Stripe
- Go to Stripe Webhooks
- Click Add endpoint
- Enter URL:
https://yourapp.instroc.app/api/webhook/stripe - Select events to listen for
- Copy the webhook secret to your environment variables
Customer Portal
Let users manage their subscriptions:
// Create portal session
const portalSession = await stripe.billingPortal.sessions.create({
customer: customerId,
return_url: `${process.env.NEXT_PUBLIC_URL}/dashboard`,
});
// Redirect to portalSession.url
Testing
Test Mode
Use test API keys during development:
- Publishable:
pk_test_... - Secret:
sk_test_...
Test Cards
| Number | Result |
|---|---|
| 4242424242424242 | Successful payment |
| 4000000000000002 | Card declined |
| 4000002500003155 | Requires authentication |
Use any future expiry date and any 3-digit CVC.
Test Webhooks Locally
- Install Stripe CLI:
brew install stripe/stripe-cli/stripe - Login:
stripe login - Forward webhooks:
stripe listen --forward-to localhost:3000/api/webhook/stripe - Use the provided webhook secret
Common Patterns
Store Customer ID
Save Stripe customer ID with your users:
// Create customer
const customer = await stripe.customers.create({
email: user.email,
metadata: { userId: user.id }
});
// Save to database
await db.from('users').update({ stripe_customer_id: customer.id })
.eq('id', user.id);
Check Subscription Status
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
if (subscription.status === 'active') {
// User has active subscription
}
Handle Failed Payments
case 'invoice.payment_failed':
const invoice = event.data.object as Stripe.Invoice;
// Notify user, update status
await notifyPaymentFailed(invoice.customer);
break;
Environment Variables
STRIPE_SECRET_KEY=sk_live_xxxxx
STRIPE_PUBLISHABLE_KEY=pk_live_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx