Manual Payments Payments Setup

Payments Setup

elements man payments/setup Read as markdown

One env value turns payments on. Development runs without it, on the test checkout. Production refuses to build or start without it.

Config

config.jsoc
{ // ... stripe: { // Required: a build without it fails. Development sets it empty. secretKey: env!("STRIPE_SECRET_KEY"), // Development only, printed by `stripe listen`. Production registers its // own endpoint and stores the secret (see `payments/webhook`). webhookSecret: env("STRIPE_WEBHOOK_SECRET", ""), }, }

Put empty placeholders in config/env/development.env, and nothing else:

config/env/development.env
STRIPE_SECRET_KEY= STRIPE_WEBHOOK_SECRET=

development.env is committed, so the owner's key goes in their copy, or in the shell environment, which env values read first. An edit to the env file rebuilds the config and hot reloads the app and its open pages, so pay buttons switch from the test checkout to Stripe the moment the key is saved. Live keys go in config/env/production.env, which is gitignored. A production build with no STRIPE_SECRET_KEY line is a build error, so a deploy without the key never goes out.

The Client

app/shared/stripe.ts
import Stripe from "stripe"; import { getEnv } from "@elements/app"; import config from "#config"; let client: Stripe | undefined; export function stripeConfigured(): boolean { return config.stripe.secretKey !== ""; } /** True when payments go through the in-app test checkout instead of Stripe. */ export function testCheckout(): boolean { return !stripeConfigured() && getEnv() !== "production"; } export function stripe(): Stripe { client ??= new Stripe(config.stripe.secretKey); return client; }

An empty key in production is refused at startup, before the app serves a request. Put the check in index.ts, ahead of app.start:

index.ts
if (getEnv() === "production" && !stripeConfigured()) { throw new Error("STRIPE_SECRET_KEY is required in production."); }

So a running app can always take a payment: through Stripe when the key is set, through the test checkout when it is not. Pay buttons are always shown; there is no "not set up" state to build.

Telling the Owner

The final report names the one step left: create a free Stripe account at dashboard.stripe.com/register (a sandbox works right away, with no business details), open Developers, API keys, copy the secret key (sk_test_...), and add it to config/env/development.env as STRIPE_SECRET_KEY=. Until then the test checkout stands in. Do not build a settings or setup page for this; the env file is the setting.

Related

  • payments/checkout: the checkout rpc, the test checkout, and fulfillment.
  • payments/webhook: the webhook route and its registration.
  • config: env files and getEnv().