Core Concepts

Test Mode

Every LuniPay account has a fully-isolated sandbox. Build, break, and rebuild without touching a real card, a real bank account, or a real customer.

What test mode is

Test mode is a parallel universe with the same schema, the same API surface, and the same dashboard — but none of the data is real. A test payment is a simulated charge; a test payout is a simulated payout; a test refund never moves money. You can reset the sandbox by rotating keys, but you can also just leave it there.

Test mode is keyed on the API key you use. A sk_test_… request always writes to test state; a sk_live_… request always writes to live state. There is no per-request toggle and no shared rows.

What is isolated

  • Resources: customers, invoices, payments, payment links, and checkout sessions are filtered by livemode on every query.
  • Webhook endpoints: test-mode endpoints only receive test events. Live endpoints only receive live events.
  • Ledger and payouts: test payouts never hit Stripe Connect. They exist only as simulated rows in your LuniPay ledger.
  • Rate limits: test and live share the same quota so you cannot use test to bypass live-mode throttling.

Test cards

LuniPay accepts every Stripe test card in test mode. Use any future expiry, any CVC, and any ZIP code:

NumberResult
4242 4242 4242 4242Approved.
4000 0027 6000 3184Triggers 3D Secure authentication.
4000 0000 0000 9995Declined — insufficient funds.
4000 0000 0000 0002Declined — generic.
4000 0000 0000 0069Expired card.
4000 0000 0000 0127Incorrect CVC.

Test mode in the dashboard

Every page in the LuniPay dashboard has a topbar toggle between Test and Live. In test mode a bright orange banner is shown so there is no ambiguity about which mode you are looking at. Test keys live under their own tab in Settings → Developer.

Going live

When you are ready to accept real money, swap your server-side secret from sk_test_… to sk_live_…, re-register your webhook endpoints in live mode, and re-run your integration tests. Nothing else changes — the API shape and response format are identical.

Sanity check before you flip

Before you deploy live keys, double-check your success and webhook URLs point at production domains, not staging. A misrouted webhook is the most common reason early-stage go-lives fail.

Resetting test data

There is no destructive "reset" button — rows accumulate as you test. If you need a clean slate, rotate your test keys to invalidate old idempotency caches and register a fresh test-mode webhook endpoint in the dashboard. You can also delete individual customers and invoices from the UI.

Filtering your own queries

Every response from LuniPay includes a top-level livemode boolean. If you persist LuniPay ids in your database, store the livemode alongside them so you can reliably filter test rows from your own reports.

{
  "id": "pay_01JRZK9XA0PMK4JHGF7Z3V8TRC",
  "object": "payment",
  "livemode": false,
  "status": "SUCCEEDED",
  "amount_cents": 5000,
  "currency": "usd"
}