Quickstart
From a new account to a paid test transaction, in five steps.
Before you start
You will need three things, and only the first is instant:
- An API key for the TEST environment, which you issue yourself in the dashboard.
- A signing secret and an encryption key — the data-plane key pair. These are issued with your account rather than self-served; see Signing requests.
- A server. Every call below is a server-to-server call: none of these credentials may ever reach a browser or a mobile app.
Step 1 — Create your account
Register with your business email and confirm the code we send you. You are signed in immediately — you do not need to be verified to look around.
Step 2 — Pass verification
Submit your KYC or KYB documents from the Verification page and wait for a decision. Until it arrives, most of the dashboard is visible but locked, and you cannot issue an API key — so this is the step that decides how soon you can start.
The form itself is not fixed: which fields and which document slots you see depends on whether you registered as an individual or an organization, and on what the reviewers currently ask for. Fill in what the page shows you.
Step 3 — Issue a test API key
Go to API keys, choose the TEST environment, and create one. The full key is shown once; after that only its first 16 characters are ever displayed again. Copy it into your server's environment now.
ECASH_BASE_URL=https://api.ecashpay.example/api ECASH_API_KEY=ecpay_test_… # from the API keys page, TEST ECASH_API_SECRET=… # signing secret, issued with your account ECASH_ENC_KEY=… # 32-byte AES key, as 64 hex characters
Nothing else about the key needs configuring. It carries its environment inside it: this one can only ever create test payments, and it can never see live data.
Step 4 — Create your first payment
Ask for a hosted checkout — the shortest path to a working payment, because we render the page your customer pays on:
{
"referenceId": "order-1001",
"amount": 1500,
"currency": "PHP",
"method": "EWALLET",
"customerEmail": "payer@example.com",
"description": "Order #1001",
"successReturnUrl": "https://your-shop.example/orders/1001/paid",
"cancelReturnUrl": "https://your-shop.example/orders/1001/cancelled"
}EWALLET is the example, not a special case. The other three — CARD_CREDIT, CARD_DEBIT and QR — take this same body with one word changed, and Payment methods shows each of them with what it answers. Only QR answers differently.
That is the body before it goes on the wire. A request body is encrypted and the request is signed, so you cannot send the JSON above as-is: what you actually post is base64( iv ‖ tag ‖ ciphertext ) with Content-Type: application/octet-stream, and the signature covers those bytes rather than the plaintext — Signing requests has the four headers and a copy-pasteable client that does it for you. With that in place, the answer is:
{
"success": true,
"data": {
"id": "b0f9c6d2-…",
"referenceId": "order-1001",
"status": "PENDING",
"environment": "TEST",
"amount": 1500,
"currency": "PHP",
"method": "EWALLET",
"qrString": null,
"paymentLinkUrl": "https://checkout.example/…",
"processorReference": "pr-7c21…",
"failureCode": null,
"createdAt": "2026-08-13T09:00:00.000Z",
"updatedAt": "2026-08-13T09:00:00.000Z"
},
"meta": { "timestamp": "2026-08-13T09:00:00.000Z", "requestId": "3f1c…" }
}Send your customer to paymentLinkUrl. In TEST no money moves and you can complete or abandon the payment as often as you like.
Step 5 — Confirm the outcome
When the customer returns to your successReturnUrl, ask the API what happened — do not trust the redirect:
{ "status": "SUCCEEDED" }A SUCCEEDED payment is money you will be settled for. Now fill in the rest:
- Creating a payment — the other flow, every field, and what each status means.
- Confirming the outcome — polling properly, and why there is no webhook to wait for.
- Testing — driving a payment to a chosen status from your dashboard.

