Skip to main content

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

  1. Go to Stripe Dashboard
  2. Copy your Publishable key (pk_test_... or pk_live_...)
  3. Copy your Secret key (sk_test_... or sk_live_...)

3. Connect to INSTROC

  1. Open your project in INSTROC
  2. Go to Project SettingsIntegrations
  3. Click StripeConnect
  4. Enter both API keys
  5. 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`,
});

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

  1. Go to Stripe Webhooks
  2. Click Add endpoint
  3. Enter URL: https://yourapp.instroc.app/api/webhook/stripe
  4. Select events to listen for
  5. 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

NumberResult
4242424242424242Successful payment
4000000000000002Card declined
4000002500003155Requires authentication

Use any future expiry date and any 3-digit CVC.

Test Webhooks Locally

  1. Install Stripe CLI: brew install stripe/stripe-cli/stripe
  2. Login: stripe login
  3. Forward webhooks: stripe listen --forward-to localhost:3000/api/webhook/stripe
  4. 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

Resources