Testing
What TEST mode does and does not do, the sandbox in your dashboard, and how to drive a payment to a chosen status.
What TEST mode is
A key issued for TEST gives you the whole API against a world of its own. No money moves, no card is charged, no cash is collected, and nothing you create is visible to anyone reading live reports.
What is the same as production:
- Every endpoint, every field, every error. Signing is enforced identically — a client that works in TEST works in LIVE.
- Statuses, and the fact that they arrive asynchronously. Test payments are
PENDINGbefore they are anything else. - The duplicate-reference guard, the rate limits and the 300-second signature window.
What is not:
- No real settlement, and no real timing. A test payment will not teach you how long a real customer takes to approve a charge in their wallet app.
- Test payers are their own directory.
GET /v1/customerswith a test key never shows you a real person's contact details.
The sandbox in your dashboard
The dashboard has a Sandbox for signed-in merchants, and it is the fastest way to see a correct request. Pick an endpoint, edit the body, run it as one of your keys — and the sandbox shows you the actual request it made: the headers, the exact string that was signed, the sealed body, and the response.
Two reasons to start there rather than in your editor:
- Nothing secret is in your browser. The signing and encryption happen on our server, so a run needs no key pasted anywhere.
- It shows the signed pre-image. When your own client gets
SIGNATURE_INVALID, running the same call in the sandbox and diffing that string against yours finds the problem in seconds. See Signing requests.
The sandbox also has a clock check against GET /v1/payments/server-time — worth running once from any machine that is about to sign requests.
Driving a payment to a status
Your code has to handle a payment that succeeds, one that fails, one that expires and one that is refunded. Waiting for a test payment to expire on its own is not a test strategy, so the sandbox can simulate the payment service's callback: pick one of your test transactions, pick an event, and the payment moves as if the rail had reported it.
That is what lets you build the whole flow before a single real customer exists — including the paths that are hardest to reach on purpose:
- Drive a payment to
SUCCEEDED, then fulfil, then refund it. - Drive one to
EXPIREDand check your order is released rather than stuck. - Fire the same event twice and confirm your side is idempotent — we de-duplicate, and your fulfilment should too.
Going live
Going live is one credential change. Issue a LIVE key, put it in your production environment, and leave the test key in place for your staging system:
ECASH_API_KEY=ecpay_live_… # the only line that differs from staging
The base URL does not change, the signing secret and encryption key do not change, and no code changes. If something behaves differently in LIVE, the difference is which payment methods are enabled there — the routing is set per environment — rather than the API.
Before you switch:
- Confirm the payment methods you plan to offer —
CARD_CREDIT,CARD_DEBIT,QR,EWALLET— are enabled in LIVE. One that is switched off answers503PAYMENT_METHOD_UNAVAILABLE. See Payment methods. - Make sure the reconciliation sweep runs in production too — it is the part that is easy to leave behind in staging.
- Take one real payment for a small amount, refund it, and read both back before you announce anything.

