Stripe for web

Web checkout with a restricted key, and a webhook Contrast registers for you.

Stripe covers the web side of monetization: checkout, web subscriptions, and one-time payments. It pairs with RevenueCat rather than competing with it; the architecture the installed skills build reconciles both providers into the same app-owned subscription row, so a user who subscribes on the web is premium in the native app and vice versa.

Create the keys

In the Stripe dashboard, collect two keys. Use test mode first; switch both keys to live together only after the checkout and webhook flow pass end to end.

  • A restricted key, not the unrestricted secret key. Grant only what the integration uses: Account read, Checkout Sessions write, Customers write, Prices and Products read, Subscriptions read and write, Invoices and Charges read (for revenue metrics), and Webhook Endpoints read and write (for deploy-time registration).
  • The publishable key for Stripe.js in the browser.

Connect

Open Project Settings → Integrations, pick Stripe, paste both values, and press Verify:

SecretRuntimePurpose
STRIPE_RESTRICTED_KEYServer onlyCheckout sessions, subscription reconciliation, revenue metrics
VITE_STRIPE_PUBLISHABLE_KEYClientStripe.js in the app client

Verification probes the Stripe API with the restricted key and reports exactly what is missing if it fails. A third secret, STRIPE_WEBHOOK_SECRET, is created for you at deploy time; you never make it by hand.

What connecting teaches your agents

The installed skill has agents build checkout the way Stripe’s own docs recommend and most first implementations get wrong:

  • Checkout Sessions are created on the server with the restricted key, from a server-owned map of plan names to Stripe price ids. The client never chooses a price or amount the server trusts.
  • Success pages are confirmation UI, not proof of payment. Durable access comes from the webhook-reconciled subscription row.
  • The webhook route verifies the Stripe-Signature header on the raw body before acting, handles events idempotently by recorded event id, and upserts the same subscription row RevenueCat writes.

The deploy-time webhook

When a project with verified Stripe deploys to production, Contrast registers the Stripe webhook endpoint for the deployed app’s /api/webhooks/stripe route, stores the signing secret as the server-only STRIPE_WEBHOOK_SECRET, and injects it into the deployed worker. A redeploy updates the existing endpoint rather than adding another. Do not create a second endpoint for the same route in the Stripe dashboard.

This is the piece that makes web subscriptions durable in production without manual webhook setup: the deploy is what wires payment events to your app’s subscription row.

Revenue

A verified Stripe integration feeds the Revenue pane in the Production section the same way RevenueCat does: MRR, 7/30/90-day revenue, active subscriptions, and trials. A Live or Sandbox pill on the pane says which mode the numbers come from, so test-mode revenue is never mistaken for real money.

Ready?

Create a web, iOS, and Android app in minutes with agents working alongside you.