Payments (Dodo)
Setup checks your Dodo Payments API key, works out whether it's a test or live key, and creates a Dodo product for every plan you sell.
What you need
A Dodo Payments account. Test mode works straight away. Live mode needs your business verified by Dodo first.
Steps
Create an API key with Write access
- Open app.dodopayments.com.
- Choose the mode with the Live Mode switch in the sidebar:
- Off (test mode): fake cards, no real money. Start here.
- On (live mode): real payments. Only available once Dodo has verified your business.
- Go to Developer → API Keys → Create New Key, and enter any key name.
- Under access, click Select all and choose Write. Write includes Read.
- Leave IP Allowlist empty. Vercel's servers don't have fixed IP addresses, so an allowlist would block your live site.
- Create the key and copy it. Dodo shows it only once.
Paste it when setup asks for Dodo API key. It's saved as DODO_PAYMENTS_API_KEY.
Why full Write access?
Setup creates products and the webhook with this key, and your app uses the same key to create customers, checkouts and billing-portal links. A key missing any of these fails with 403 INSUFFICIENT_PERMISSION. You can change a key's access later with Edit Permissions.
Test and live keys are separate
A key belongs to the mode that was selected when you created it. Products, customers and webhooks are also separate per mode. A test key can't see live products, and the other way round.
Setup works out the mode
◇ Checking your Dodo API key ✓
● Test mode key: checkout uses test cards.You don't choose the mode: setup asks Dodo which mode accepts the key and saves DODO_PAYMENTS_ENVIRONMENT as test_mode or live_mode.
If neither accepts it, setup stops with Dodo rejected that API key in both test and live mode. See the fix.
Setup creates one product per plan
Every plan in src/config.ts is sold as a Dodo product, and checkout needs that product's ID. Setup prints one line per plan:
● Creating a Dodo product for each plan in src/config.ts (Starter, Pro).
◇ Plan "Starter": created a new Dodo product (pdt_0NratpuES3GoyhIYvg2s9)
◇ Plan "Pro": using the Dodo product made by an earlier run (pdt_0NrLaoYtQLASArqYow2Ca)- created a new Dodo product: the plan had no product in this mode yet, so one was created with the plan's name, description and price.
- using the Dodo product made by an earlier run: a product for this plan already exists (setup tags each product with the plan's
slug), so it's reused instead of creating a duplicate.
Each product ID is saved to the plan's productEnv variable, such as DODO_PRODUCT_STARTER.
What the product looks like in Dodo
Plan setting in src/config.ts | Dodo product |
|---|---|
interval: "month" or "year" | Subscription, billed every month or year, running until cancelled |
interval: null | One-time payment |
amount: 1900, currency: "USD" | $19.00 |
name, description | Product name and description |
The tax category is set to SaaS. Change it in the Dodo dashboard if your product is something else, such as an e-book or a service.
Changing a price later
Setup reuses a plan's existing product and doesn't change its price. To change a price, see Changing a plan's price.
The webhook
Dodo tells your app about payments through a webhook. Setup only registers it when you deploy, because Dodo must be able to reach your app over the internet. To test payments on your computer, see Testing payments locally.
Problems
See Payment errors and Setup errors.