Test vs live mode
Every HelaMesh client belongs to one of two environments, stamped on the client at creation time and immutable afterwards:
| Mode | API key prefix | Publishable key prefix | Can simulate? |
|---|---|---|---|
| Test | hm_test_* | pk_test_* | β Yes β click a button or call the simulate endpoint |
| Live | hm_live_* | pk_live_* | β Never β real on-chain payments only |
Test and live data are fully isolated. Test invoices never appear in live reports, live invoices never appear in test reports, and the simulate endpoint refuses to touch live clients at the service layer β no auth context, no API key, no admin override can fast-forward a live invoice.
HelaMesh uses the same Stripe-style pattern Plaid, Coinbase Commerce, and Paystack use: one API host, one dashboard, one set of URLs. Test mode is a flag on the client, not a separate cluster. There is no sandbox-api.helamesh.com β you hit api.helamesh.com with a test key and HelaMesh handles the isolation.
Picking an environmentβ
When you create a new client in the dashboard, you pick its environment. That choice is permanent β environment is baked into every invoice the client creates, so rotating it after the fact would corrupt historical data. Most merchants run:
- One test client for local dev, CI integration tests, and staging.
- One live client per store, product line, or brand.
Keep them separate. Use the test client's keys in .env.test / .env.development; use the live client's keys only in production deployment secrets.
What changes between modesβ
Everything about the test-mode experience is designed to be indistinguishable from live, except where the difference is load-bearing:
- Same API host, same endpoints, same request/response shapes.
- Same webhook delivery pipeline β signed, retried, redrivable.
- Same hosted checkout UI, with a yellow
TESTbadge so customers never mistake a sandbox invoice for a real one. - Same dashboard, with
TESTandSIMULATEDbadges on every test-mode invoice. - Different: test invoices can be fast-forwarded through the state machine by clicking a button or hitting
POST /v1/invoices/:id/simulate. Live invoices cannot. - Different: test-mode webhooks include
"simulated": truein the payload body so your handler can route them to staging instead of production tables.
Simulating paymentsβ
The sandbox is the main reason to use test mode. You have three ways to fast-forward a test invoice:
- Dashboard button β open any test PENDING invoice and click β‘ Simulate payment.
- Hosted checkout β test invoices show a β‘ Simulate test payment button right on the customer-facing checkout page (hidden entirely on live invoices). Clicking it animates through Detected β Confirming β Confirmed in ~1.5 seconds.
- API endpoint β for CI pipelines and integration tests:
POST /v1/invoices/:id/simulatewith your test API key.
All three route through the same InvoiceSimulationService, which enforces the live-client refusal at the service layer. See Sandbox for the full loop, code examples, and the simulated webhook flag contract.
simulated: true in your handlerIf your webhook handler updates real accounting systems, moves real balances, or triggers irreversible fulfillment, branch on event.simulated and route test events to a staging DB or a no-op path. Never mirror simulated events into production tables.
When to create whichβ
| You are⦠| Use⦠|
|---|---|
| Building a new integration from scratch | Start with a test client. Iterate until your webhook handler does the right thing on simulated events. |
| Running CI / integration tests | Use a test client's API key as a CI secret. Hit the simulate endpoint inside your test suite. |
| Shipping to production customers | Create a live client. Point its webhook URL at your prod backend. Swap the key in your prod secrets. |
You never need to run HelaMesh locally to integrate with it β the sandbox on the production API covers every test scenario a real customer could trigger.