antrix.dev
Free guide

Payments with Stripe

Accept real payments with Stripe. Set up products, checkout sessions, and webhooks for your business.

Reading this alone?

Do it with peers — bi-weekly calls, $29/mo founding.

Join →

What it does

Stripe handles your payments — one-time purchases, subscriptions, invoicing. You create products and prices in the dashboard, integrate Checkout Sessions in your app, and Stripe handles the entire payment UI, card processing, receipts, and compliance. You never touch sensitive card data directly.

Checkout Sessions handle the entire payment UI — card form, validation, error messages, receipts, and compliance. You redirect the user to Stripe, they pay, and Stripe redirects them back. For subscriptions, Stripe manages the recurring billing, dunning (failed payment retries), and cancellation flows automatically. You don't build any of this yourself.

Why we use it

Industry standard. Stripe handles PCI compliance so you don't touch card numbers. Checkout Sessions mean you don't build payment forms. The rate is 2.9% + 30 cents per transaction with no monthly fee. You only pay when you make money. The API is clean, the docs are excellent, and the developer experience is unmatched.

Stripe handles PCI compliance — you never touch card numbers, so you don't need to pass a PCI audit. The alternative (building your own payment form with PaymentIntents) requires more code, more security responsibility, and more edge case handling. Start with Checkout Sessions. Only move to custom forms when you have a specific UX requirement that Checkout can't handle.

Setup checklist

1

Create a Stripe account

Go to stripe.com and sign up. You'll need to complete identity verification, which takes 1–2 business days. Don't wait around for it — you can start building in test mode immediately while verification processes. Test mode is fully functional with its own API keys, products, and data. No real money moves until you explicitly go live.

2

Understand test vs live mode

There's a toggle in the top-right of the dashboard that switches between test and live mode. These are completely separate environments — different API keys, different products, different transaction data. Build everything in test mode first. Test mode keys start with sk_test_ and pk_test_. Live keys start with sk_live_ and pk_live_. Only switch to live when you're ready for real payments.

3

Create your products and prices

Go to Products > Add Product in the dashboard. Give it a name, description, and image. Then add a price — either one-time or recurring (for subscriptions). Each price gets a unique ID that looks like price_xxx. This is what you reference in your code when creating Checkout Sessions.

Create test mode products that mirror exactly what you plan to sell. A product can have multiple prices — different tiers, different billing intervals, different currencies. The dashboard is your source of truth for pricing, not your codebase.

4

Get your API keys

Go to Developers > API Keys. You need two keys. The Secret Key (starts with sk_) is for server-side code only — never expose this in the browser or in any NEXT_PUBLIC_ environment variable. The Publishable Key (starts with pk_) is safe for client-side code.

Copy both test mode keys first. Add them to your .env.local file as STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY. You'll swap these for live keys later when you go to production.

5

Install the Stripe SDK

Run npm install stripe in your project. Then create a Stripe client file at lib/stripe.ts that imports Stripe, initializes it with your secret key from environment variables, and exports the client. Use the latest API version. This file is server-side only — never import it in a client component.

6

Implement Checkout Sessions

This is the core integration. Create an API route (e.g., app/api/checkout/route.ts) that creates a Checkout Session. The session needs: line_items (your price IDs and quantities), a success_url where the customer lands after paying, a cancel_url where they go if they bail, and a mode ("payment" for one-time, "subscription" for recurring).

Your frontend calls this API route, gets back a session URL, and redirects the user to it. Stripe hosts the entire payment page — card inputs, validation, Apple Pay, Google Pay, all of it. After payment, the customer redirects back to your success URL. You can include {CHECKOUT_SESSION_ID} in the success URL to retrieve session details on the success page.

7

Set up webhooks

Webhooks are how Stripe tells your app that something happened — a payment succeeded, a subscription was canceled, a refund was issued. Go to Developers > Webhooks > Add endpoint. Set the URL to your webhook route: https://yourdomain.com/api/webhook.

Select the events you care about. At minimum: checkout.session.completed and payment_intent.succeeded. For subscriptions, also add customer.subscription.updated and customer.subscription.deleted. After creating the endpoint, Stripe gives you a webhook signing secret (starts with whsec_). Save this as STRIPE_WEBHOOK_SECRET in your environment variables.

8

Handle webhook events

Create an API route at app/api/webhook/route.ts. This route needs to: read the raw request body (not parsed JSON — the signature verification needs the raw bytes), verify the signature using your webhook signing secret, parse the event, and handle it based on the event type.

For checkout.session.completed, this is where you grant access to whatever the customer bought — update the database, send a confirmation email, deliver a digital product. This webhook is your single source of truth for whether a payment succeeded. Don't rely on the success page redirect alone — customers can close the browser before it loads.

9

Test the full flow

Stripe provides test card numbers. Use 4242 4242 4242 4242 for a successful payment and 4000 0000 0000 0002 for a declined card. Any future expiry date works. Any 3-digit CVC works.

Test the complete path: click buy, go through checkout, enter the test card, complete payment, verify the webhook fires, confirm the database is updated, check that the confirmation email sends, and land on the success page. Then test the decline path — make sure the user sees a clear error and can retry.

10

Handle edge cases

Card declines should show a friendly error message, not a stack trace. Duplicate webhooks are the biggest gotcha — Stripe retries failed webhook deliveries, so your handler must be idempotent. Before granting access, check if you already processed this session ID. Use the session ID as a unique key in your database.

Also handle: expired sessions (Checkout Sessions expire after 24 hours), refunds (listen for charge.refunded events and revoke access), and partial failures (webhook received but email failed to send — log the error, don't throw).

11

Go live

Switch to live mode in the dashboard. Create the same products and prices in live mode — the IDs will be different from test mode. Update your environment variables with live API keys (sk_live_, pk_live_). Add a new webhook endpoint for your production URL with the live signing secret.

Do a real test: charge yourself $1 using a real card, verify the webhook fires, confirm the product is delivered, then refund the charge. This catches issues that test mode can't — like domain verification and payment method availability in your country.

12

Set up Stripe CLI for local development

Install the Stripe CLI: brew install stripe/stripe-cli/stripe. Run stripe login to authenticate. Then forward webhooks to your local server: stripe listen --forward-to localhost:3000/api/webhook.

The CLI prints a temporary webhook signing secret for local testing — use this as your STRIPE_WEBHOOK_SECRET during development. This is essential for testing the webhook flow without deploying. You can also trigger test events with stripe trigger checkout.session.completed.

Pro tips

Use Stripe's Customer Portal for subscription management — one line of code gives users a self-service page to update payment methods, view invoices, and cancel. You don't build any of that UI yourself.

Set up Stripe Tax for automatic sales tax calculation if you sell to customers in multiple jurisdictions. Tax compliance gets complicated fast — let Stripe handle the rates, rules, and reporting.

Use Stripe's test clocks to simulate subscription lifecycle events (renewal, trial end, payment failure) in test mode. This lets you verify your webhook handlers work correctly for events that would normally take days or weeks to occur.

Enable Stripe Radar for fraud detection — it's on by default for Checkout Sessions and catches suspicious transactions using machine learning trained on data from millions of businesses.

Checkout session code

// app/api/checkout/route.ts
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

export async function POST(req: Request) {
  const { priceId } = await req.json();
  if (!priceId) return Response.json({ error: "Missing price" }, { status: 400 });
  const session = await stripe.checkout.sessions.create({
    line_items: [{ price: priceId, quantity: 1 }],
    mode: "payment",
    success_url: `${process.env.NEXT_PUBLIC_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.NEXT_PUBLIC_URL}`,
  });
  return Response.json({ url: session.url });
}

AI prompt to get started

I'm integrating Stripe into my Next.js app. I need: 1) A checkout API route that creates a session for [product type], 2) A webhook handler that verifies signatures and processes checkout.session.completed events, 3) A success page that retrieves the session details, 4) Environment variable setup for test and live modes.

Mistakes to avoid

  • Trusting client-side amounts — NEVER pass prices from the frontend. Use Stripe price IDs, which are set in the dashboard
  • Not verifying webhook signatures — without verification, anyone can fake a payment event and get free access
  • Hardcoding price IDs — use environment variables so you can switch between test and live without code changes
  • Not handling duplicate webhooks — Stripe retries failed webhooks. Your handler must be idempotent (use session ID as a unique key)
  • Going live without testing the full flow — test every path: success, decline, webhook delivery, email confirmation
  • Exposing your secret key — it goes in server-side code only, never in client components or NEXT_PUBLIC_ variables

Reading this and want to actually do it with others?

The community is bi-weekly live calls, async accountability, and a group of builders shipping in parallel. Founding seats are $29/mo.

[ 01 ] the community · waitlist open

Build next to people who actually ship.

AI isn't going to make you money. Products do. Clients do. Real businesses do. AI is the unfair advantage — wire it into how you build, sell, and serve, and you move faster than everyone still doing it by hand.

operator:youwaitlist:openfleet:yours to installcalls:weekly liveprice:$29/mo founding

Is this you?

$ qualify --you

  • You live in Claude Code (or Codex) all day — and you're still the one doing every task, one prompt at a time.
  • You bill by the hour, and you can feel the ceiling. You want agents doing the repeatable work.
  • You're shipping your own thing — and want the whole business automated, not just the code.
  • You're senior and employed — and want this leverage running before your industry expects it.
  • You'd rather install the system than watch one more video about it.
  • Not for the make-money-online crowd. Not for day-one beginners. This is for people who already ship.

What you get

os/

Antrix OS — your fleet's control room

The system I run on real client work, installed where you build — not a video walkthrough.

Claude Code core MCP servers + hooks subagents + worktrees one dashboard

skills/

ax-* skill packs + installers

Drop-in capability. The packs and one-command installers that do the repeatable work.

  • ax-audit, ax-deliver, ax-simplify, ax-content
  • Ship Your Product — installer
  • Run the Machine — installer
  • Overnight pipelines: issues → PRs

setups/

Wired-up service setups

The integrations already configured the way production needs them.

  • Stripe — billing + webhooks
  • Supabase — auth + data
  • Vercel — deploy + edge
  • Resend — transactional email

access/

Direct access — to me and the network

When you're mid-build and stuck, you post and get an answer from someone who's shipped it.

  • Live working calls every week — builds, teardowns, Q&A
  • Architecture + payment reviews on your code
  • A peer network of operators who ship, not spectate
  • First look at overflow client work
Antrix OS — projects across every company, with live agents and open tasksAntrix OS — the agent roster: system agents, PMs, personas, and workers

← drag to explore the dashboard

The control room you'll run your fleet from — every project, agent, skill, schedule, and secret in one place. Members get the codebase.

$ fleet --ships

IG carousels, drafted overnightLead lists scraped for consultingClient reports + invoices, generatedContent research, done by morningOvernight PRs from open issuesWeekly ops digest, auto-assembled

[ 03 ] work with me directly

Hire me, and you get me — not an agency.

Don't want to run the fleet yourself — or need senior hands on your product now? I take a few clients each quarter, working direct on your codebase, your stack, your business. No junior handoffs, no account managers. Best fit if you're already shipping something real.

You're stuck on the hard part

We pair and ship it — the product, the agent, or the integration that's been blocking you — in the session, not in a follow-up doc.

AI is still just a chat window for you

I wire agentic workflows, multi-agent pipelines, and scheduled jobs into your business — turning AI from a tab you open into real leverage on revenue work.

You shipped it but you're not sure it holds

I review architecture, AI usage, and payments, then tell you what to keep, what to rip out, and what to ship next. Straight, no hedging.

You want to run it yourself

Sometimes you don't need me to run it — you need me in the room while you do. I set up the system and hand you the keys.

Specialty — payments & billing

If your product touches money, that's where I help most — subscriptions, marketplaces, and migrations at Babbel scale, Stripe-certified. Those engagements run through my consulting practice at invocation.io.

Tell me what you're building.

I reply within 24 hours.