Stripe

Test-mode Stripe keys from an account we run and everyone shares.

AI/LLM: this page is available in plain markdown at /docs/resources/stripe.md

npx extraorbital add stripe
✓ Provisioned stripe/default (mode test)
✓ Wrote 2 variables to .env

  STRIPE_SECRET_KEY, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY

! Shared test account: every ExtraOrbital project provisioning stripe gets these
  same keys.

A project that mentions STRIPE_SECRET_KEY gets this from extraorbital provision without naming it. It exists so an agent can build and exercise a checkout flow end to end — a real payment_intent, a real webhook, a real test card — without stopping to ask a human to open a Stripe dashboard and sign up.

What it writes

VariableExample
STRIPE_SECRET_KEYsk_test_51Q…
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYpk_test_51Q…
STRIPE_WEBHOOK_SECRETwhsec_9c4e…

The publishable key carries the NEXT_PUBLIC_ prefix because that is the one Stripe value the browser needs — Stripe.js runs client-side, and Next.js only exposes NEXT_PUBLIC_* variables to it. A publishable key is public by design, so the prefix gives nothing away that the page would not already show. On a framework that reads .env without a prefix convention, the name is just a name.

Only test-mode keys are ever handed out: the broker refuses to publish a value that does not carry a sk_test_, rk_test_ or pk_test_ prefix, so there is no configuration mistake that turns this into live credentials.

STRIPE_WEBHOOK_SECRET is written only where an endpoint has been configured for the shared account. For local development you usually want your own anyway — stripe listen prints a signing secret for the session it forwards, and that is the one your handler should verify against.

Options

npx extraorbital add stripe [--slug <name>]
FlagDefaultDescription
--slugdefaultA second copy of the same keys, tracked separately

There is nothing to configure, because nothing is created. A second slug gives you a second resource record, not a second account: the credentials behind both are identical.

What "shared" costs you

Test mode is free on every plan, so this resource has no allowance and never meters. What it costs is isolation, and that is worth being concrete about:

  • Your data is visible to everyone else. Any project holding these keys can list your customers, products and payment intents, and can delete them.
  • Their data is visible to you. A customer.list returns everyone's, so filter on something of your own rather than assuming the account is empty.
  • Nothing is guaranteed to survive. The account is periodically cleared, and any other agent may remove what you created.
  • Webhooks fan out. An endpoint on the shared account receives events caused by other people's requests, so verify that an event belongs to you before acting on it.

The practical version of all four is one habit: prefix everything you create and filter on that prefix. Stripe metadata is the tidiest place for it.

checkout.ts
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
const MINE = "acme-demo";

const customer = await stripe.customers.create({
  email: "buyer@example.com",
  // Yours to find again on an account that is not only yours.
  metadata: { app: MINE },
});

const intent = await stripe.paymentIntents.create({
  amount: 1999,
  currency: "usd",
  customer: customer.id,
  metadata: { app: MINE },
});

Then read back by search rather than by list, so nobody else's rows reach your code:

customers.ts
const mine = await stripe.customers.search({
  query: `metadata['app']:'${MINE}'`,
});

Test cards work exactly as they do in your own account — 4242 4242 4242 4242 for a success, 4000 0000 0000 9995 for a decline. See Stripe's testing guide for the full set.

Moving to your own account

Nothing about the shared account is special, so moving off it is a variable swap:

npx extraorbital remove stripe

Then set STRIPE_SECRET_KEY and NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY to your own values in .env. Removing the resource first is what stops extraorbital provision writing the shared keys back over yours on the next run.

Do that before you take a payment from anyone real, before you store anything you would mind losing, and before you connect anything you would mind a stranger reading.

Next