Payments API
Four endpoints. Payments and refunds on any gateway.
Create a payment, look it up, refund it, look the refund up. Plain HTTPS and JSON, the same request whichever gateway takes the money, and samples in cURL and six languages. There is no SDK to install.
Try it
Build a request.
Choose an endpoint, a key and a language. The request and an example response update as you go. Nothing is sent anywhere.
curl https://api.zoppay.in/v1/payments \ -H "Authorization: Bearer sk_test_…" \ -H "Idempotency-Key: order-17391" \ -H "Content-Type: application/json" \ -d '{ "amount": 19900, "currency": "INR", "reference": "order-17391", "return_url": "https://your-shop.example/thanks", "customer": { "email": "alice@example.com", "phone": "+919876543210" } }'
{ "data": { "id": "pay_01JCP6W8TXZBVM3A2QZ6FKXWR4", "status": "pending", "amount": 19900, "currency": "INR", "reference": "order-17391", "checkout_url": "https://checkout.zoppay.in/chk_lw0...xyq" } }
Test key: the payment goes through the built-in test gateway and no real money moves. Create a test key on the API keys page of your dashboard. Showing Create a payment with a test key in cURL.
Built in
The details you would otherwise build yourself.
Versioned under /v1
Every endpoint lives under /v1. Responses wrap the object in "data". Creating something answers 201.
Safe retries
Send an Idempotency-Key with a POST. A retry with the same key within 24 hours returns the first response, so a payment or refund is never made twice.
Clear rate limit
300 requests a minute per API key. Over that you get a 429 with Retry-After: 60, so your code knows when to try again.
Test and live kept apart
sk_test_ keys use the built-in test gateway and only see test payments. A live key never sees a test payment, and the other way round.
Bearer keys over HTTPS
Send your key as Authorization: Bearer. You create keys on the API keys page; ZopPay keeps only a SHA-256 hash and shows the last 4 characters.
Your own API domain
You can set an API and checkout domain of your own, such as payments-api.yourstore.com, in Settings. Our team finishes the DNS set-up with you.
Errors
One error shape. Standard status codes.
Every error has the same JSON shape, so one handler covers them all. When a gateway refuses, you get its own reason, with emails and long numbers masked.
| Status | What it means |
|---|---|
| 400 | Something in the request is missing or invalid |
| 401 | Missing or wrong API key |
| 403 | A live payment before your account is live |
| 404 | Not found, or it belongs to the other mode |
| 409 | A request with the same Idempotency-Key is still running |
| 422 | Key reused with a different body, or the gateway refused |
| 429 | Too many requests; retry after 60 seconds |
| 5xx | A problem on our side; the details stay in our logs |
HTTP/1.1 422 Unprocessable Entity Content-Type: application/json { "error": { "message": "the gateway rejected the refund: The refund amount provided is greater than amount captured" } }
Start with test mode today.
Sign up free, make a test payment from your dashboard and see how it works. Connect your gateway when you're ready.