# Recipe: Replit

For an app running on Replit, built by Replit Agent or by hand. Replit apps run a real server (usually Node.js with Express, or Python with Flask), so the code is the recipe for that server; this file covers what's different on Replit and the prompt to paste. [The playbook](https://checkouts.md/playbook.md) has the reasons and every error code.

| | |
|---|---|
| Server code runs in | The Repl's own server process |
| Code | [recipes/express.md](https://checkouts.md/recipes/express.md) for Node.js; [recipes/django.md](https://checkouts.md/recipes/django.md) (its Flask note) for Python |
| Database | The Repl's PostgreSQL (`DATABASE_URL`), which the Express recipe uses as it is |
| Secrets | Replit Secrets, read as environment variables (`process.env.RAILBED_SECRET_KEY`) |
| Webhook URL | The running Repl's public address, then the deployment's |
| Connect | `npx checkouts.md login` in the Shell, or keys entered in Secrets (below) |

## 1. Connect

Replit's Shell runs `npx`, and the app reads Secrets as environment variables. Pick the first that applies:

1. **The agent can run commands in the Shell** (Replit Agent can): run `npx checkouts.md login --test-only --env-path .env`. It writes the Test key into `.env` (gitignored) and prints only the masked key. Load it in development with `node --env-file=.env` or `dotenv`, or ask the person to move it into Secrets (open `.env`, copy the value into the Secrets pane as `RAILBED_SECRET_KEY`, then delete the line). Keep the Repl private while a key is in a file.
2. **Otherwise**, ask the person to sign in or sign up at https://app.railbed.io/signup, switch on **Test mode**, open **Developers**, **Create key** (purpose Checkout API, Full access, named "Replit"), and add it in Replit's Secrets pane as `RAILBED_SECRET_KEY`. Never into the chat.

> To connect payments I need a Railbed key, which only you can create. Sign in at app.railbed.io (or create an account), turn on Test mode in the menu at the top left, open Developers and choose Create key. Then add it in Replit's Secrets as RAILBED_SECRET_KEY, not in this chat. Nothing is charged in Test mode.

The Live key goes into the deployment's secrets at go-live, the same way (step 6).

## 2. The prompt to paste

```text
Read checkouts.md/recipes/replit.md and add a Railbed checkout to this app, following it exactly.
Sell: Pro plan for 49.00 USD.
Keep RAILBED_SECRET_KEY and RAILBED_WEBHOOK_SECRET only in Replit Secrets or a gitignored .env,
never in code or in this chat. Mark an order paid only from a verified Railbed webhook after re-reading
the payment. Test it in Railbed's Test mode before anything goes live.
```

## 3. What gets built

The [Express recipe](https://checkouts.md/recipes/express.md) as it is: `db/railbed.sql`, `src/railbed/*.js`, the routes mounted with the webhook before `express.json()`, the Pay button and `/checkout/success`. On Replit:

- The database is the Repl's PostgreSQL; `DATABASE_URL` is already set when it's enabled. Apply `db/railbed.sql` with `psql "$DATABASE_URL" -f db/railbed.sql` in the Shell.
- Set `APP_URL` in Secrets to the Repl's public address (shown in the Webview's address bar, ending in `.replit.dev`) while testing.
- The server listens on `process.env.PORT` (the Express recipe already does) and `0.0.0.0` if the template binds a host.
- For a Python Repl, use the Django recipe's `railbed.py` and views with Flask, as its notes describe.

## 4. The webhook endpoint

While the Repl runs, its address is public, so no tunnel is needed:

```bash
npx checkouts.md webhook https://<your-repl-address>/api/webhooks/railbed --env-path .env
```

It writes `RAILBED_WEBHOOK_SECRET` into `.env`; restart the app (or move it into Secrets as in step 1). Without the CLI, ask the person to add the endpoint in Railbed (Developers → **Add endpoint**), **Reveal** its signing secret, and add it in Secrets as `RAILBED_WEBHOOK_SECRET`. The development address changes when the Repl does; create a new endpoint then, and delete the old one.

## 5. Test it

1. Open the app, click the Pay button; Railbed's checkout opens. Or in the Shell: `curl -s -o /dev/null -w '%{redirect_url}\n' -X POST http://localhost:3000/api/checkout -d product=pro` (use the app's port).
2. Pay it: choose **Simulate successful payment** on the test provider page, or run the playbook's `simulate.mjs` in the Shell ([7.1](https://checkouts.md/playbook.md#71-the-end-to-end-run)).
3. Check: the Console shows `Railbed webhook payment.paid evt_…: fulfilled`; the order is `paid` in the database; `/checkout/success?order=order_…` says it's confirmed.
4. Run the other scenarios in the playbook's [7.2](https://checkouts.md/playbook.md#72-the-scenarios).
5. Record the ids under Evidence in `CHECKOUTS.md`, and delete the development endpoint once the deployment has its own.

## 6. Go live

1. The business adds a payout wallet in Railbed's Settings.
2. Deploy the Repl (Deployments). Its address ends in `.replit.app`, or is a custom domain.
3. Put the Live values in the deployment's secrets: `RAILBED_SECRET_KEY` (`rb_live_…`, from `npx checkouts.md login` run again with Live approved and `--live-to env:.env.production`, moved from that file into the deployment's secrets by the person; or created in Railbed's Developers in Live mode), and `APP_URL` (the deployment's `https://` address). Check the deployment's settings list them.
4. Add the Live endpoint for the deployment's address (`npx checkouts.md webhook https://<deployment>/api/webhooks/railbed --live`, which saves its secret in `.env.production` beside the Live key; or in Developers in Live mode), and put its secret in the deployment's secrets as `RAILBED_WEBHOOK_SECRET`. Once the deployment has both Live values, delete `.env.production`. Redeploy.
5. Check: `curl -s -o /dev/null -w '%{http_code}\n' -X POST https://<deployment>/api/webhooks/railbed -H 'Content-Type: application/json' -d '{}'` answers `400`.
6. Set `mode: live` in `CHECKOUTS.md`. The first real payment is the Live evidence.

## 7. CHECKOUTS.md

As in the [Express recipe](https://checkouts.md/recipes/express.md#7-checkoutsmd), with "Secrets: Replit Secrets (development) and the deployment's secrets (Live)" under Wiring.

## Platform notes

These describe Replit as it works at the time of writing; if Replit differs, follow its documentation and keep the rules.

- Secrets are visible to everyone who can edit the Repl. Invite only people who should see payment keys.
- A deployment may not pick up workspace changes to Secrets until it's redeployed.
