Stablecoin Checkout docs
v1.0.0
Live demoOperator console demo Get help
● Ship · Fixes

Troubleshooting
errors and their fixes.

Messages you may see, what they mean and what to do, grouped by where they appear. Tip: paste the exact message or error code into the search box. API errors have the shape {"error":{"code":"…","message":"…"}}.

01Install and build

pnpm setup does something unexpected

pnpm setup and pnpm licenses are pnpm built-ins. Use pnpm run setup and pnpm run licenses.

better-sqlite3 fails to install

No prebuilt binary for your platform and no compiler. Install your OS build tools (Xcode Command Line Tools on macOS, build-essential and python3 on Debian/Ubuntu), then run pnpm install again. Use Node 22.

pnpm run build stops at the contract

Hardhat downloads the solc compiler on first use and needs internet access. If you only need the server, build it alone: pnpm --filter "@mikodes-checkout/server..." build.

build:web prints "looks like a secret and will be public in the bundle"

A VITE_* variable in your shell has key, secret, token or password in its name. Remove it: every VITE_* value ships to browsers.

02Server start

invalid configuration: …

The server validates the env file and names every wrong value, for example OPERATOR_ADMIN_KEY must be at least 32 characters, OPERATOR_SOLANA_ADDRESS is not a valid Solana address or MAIL_FROM is required when SMTP_URL is set. Fix the line and start again.

BASE_ROUTER_ADDRESS is required when BASE_RPC_URL is set

Deploy the router first (how), or leave BASE_RPC_URL empty.

A chain is missing from /health

Its RPC URL is empty or invalid. The first log lines say which chains are disabled and why.

Two servers on one database

Not supported: webhooks would be delivered twice. Run exactly one process per SQLite file.

03Operator console

/admin returns 404

On the checkout domain this is intended: the console is only on the admin domain. On the admin domain, ADMIN_SECRET_KEY is empty, so the console is not mounted. Set it (openssl rand -hex 32) and restart.

I lost the setup code

Restart the server: while no owner exists, every start prints a new one-time code in the log.

"The setup code is wrong"

Use the code from the latest start; each restart replaces it.

Product pages (/ops) redirect to /admin or show nothing

You are not signed in to the console, or apps/ops/dist was not built. Build @mikodes-checkout/ops (or set OPS_UI_DIR) and restart.

operator_disabled

OPERATOR_ADMIN_KEY is not set, so every /v1/operator endpoint is off.

403 on the admin domain

Your IP is not in ADMIN_ALLOW_IPS. Behind a CDN or Docker's userland proxy, Caddy may not see real client IPs.

Telegram or SMTP stored values are unreadable after a change

ADMIN_SECRET_KEY changed. Re-enter the secrets under Integrations.

04Checkout and payments

Wallet pay fails at "prepare" with rpc_error

The server cannot reach your Solana RPC or is rate-limited. Check the provider; switch to a second one and restart. Payments made meanwhile are still found later.

Exchange pay is not offered

The merchant's fee credit is below the invoice fee, or Exchange pay is off in Console → Checkout, or exchange pay is switched off for that merchant.

The invoice stays confirming

A transaction was seen and the server waits for finality (on Base, BASE_CONFIRMATIONS blocks, default 12). A seen transaction keeps the invoice confirming past its expiry; this is intended.

Underpaid or overpaid

The amount received differs from the invoice. It goes to review and is never treated as paid automatically. The merchant can refund from the portal.

The payer says the payment link does not work

A link that was mistyped, deleted or has passed its retention window resolves to nothing. The payer gets a dead end that names no order, no amount and no merchant, and the fix is a fresh link from the store rather than an edit to the old one.

Stablecoin Checkout opened on a payment link that does not exist: a Payment link not found panel saying the link may be mistyped or no longer valid and to ask the store for a new payment link, with no order details and nothing else about the merchant on the page
What a payer sees on a mistyped, deleted or expired link. The page leaks no order, no amount and no merchant detail. Captured on the live demo at stablecoin-demo.mikodes.com/pay.

chain_not_enabled when creating an invoice

That chain has no RPC on the server, or it is switched off in Console → Chains & assets.

maintenance (503) when creating an invoice

Maintenance mode is on in Console → Access. Open invoices still settle.

topup_not_configured

No operator fee wallet is set for that chain, so there is no address to send fee credit to. Set OPERATOR_SOLANA_ADDRESS / OPERATOR_BASE_ADDRESS.

The browser shows a CORS error

Add the page's origin to CORS_ORIGINS (comma-separated, no trailing slash) and restart. Behind the provided Caddyfile the apps use the same origin and need no CORS entry.

05Webhooks

Deliveries to localhost or a private IP fail

They are refused on purpose (SSRF protection). For local development only, set WEBHOOK_ALLOW_PRIVATE=true. Never in production.

The merchant says the signature does not match

The receiver must compute HMAC-SHA256 over "<t>.<raw body>" with the current webhook secret, using the raw bytes, not re-serialised JSON. After a secret rotation the old secret stops working.

A delivery is a dead letter

It failed 8 times (default). Fix the endpoint, then retry it from the console or the portal (incident checklist).

06Demo instance

demo-reset.mjs wipe refuses to run

By design unless DEMO_MODE is true, every chain is a testnet, --yes-wipe-demo is given and every merchant is a demo merchant. It protects production databases.

Testers get 429 from devnet

The public devnet endpoint is rate-limited. Use your own devnet RPC for a busy demo.