Test vs Live mode for developers
Each webhook and API key has a mode: live (production) or test (development). Environments are fully isolated. Use the toggle at the top of /dashboard/developer…
Short answer
Each webhook and API key has a mode: live (production) or test (development). Environments are fully isolated. Use the toggle at the top of /dashboard/developers to switch view and create resources in the correct mode.
Why isolate
You don't want:
- Real payment events firing your dev environment's webhook
- Your production API key being used in local tests (consuming rate limit, showing in logs)
- Confusing test order IDs with production ones
The live/test split solves this. Stripe and most gateways use the same model.
How it works
Webhooks
| Mode | Receives automatic events? | Receives sandbox/mock? |
|---|---|---|
| Live | ✅ Yes (real payments) | ❌ No |
| Test | ❌ No | ✅ Yes |
Test endpoints only receive events when you fire them manually via the "Sandbox" button in the dashboard. This guarantees your dev environment never processes a real payment.
API keys
| Mode | Prefix |
|---|---|
| Live | lk_live_... |
| Test | lk_test_... |
Fully separated — a test key can't see live data and vice versa.
Recommended workflow
- Create a test endpoint pointing to your local server (use ngrok/cloudflared if it's
localhost) - Create a test API key to use in local tests
- Implement your handler validating signature, idempotency, etc.
- Use the Sandbox: fire each event type (
order.paid,subscription.activated, etc.) and verify your handler treats each one correctly - When everything's good, flip the toggle to Live, create a new endpoint pointing to your production server, copy the new signing secret to your prod env, deploy, done
Sandbox — firing mock events
Inside a test endpoint:
- The Sandbox section appears with a dropdown
- Pick the event type
- Click Fire mock event
- LimaoPay sends a POST with a realistic payload (with
livemode: false,external_metadata: { mock: true })
This lets you validate:
- Your HMAC validation works (signing secret is correct)
- Your handler processes each event type correctly
- Your idempotency works (fire the same event twice)
- Your retry handling works (intentionally respond 500 once, watch LimaoPay retry)
Limits
- Test endpoints: unlimited on all plans (don't count toward quota)
- Live endpoints: 1 (Free) / 5 (Growth) / unlimited (Scale)
- Test and live API keys: no quota distinction — rate limit is per key
Heads up
- Switching the toggle to "Test" only shows test webhooks/keys
- Switching to "Live" only shows live ones
- Resources don't disappear — they're just filtered by view
- Creating a resource while in "Test" creates it as test (and vice versa)