Introduction
The {{ config('app.name') }} API lets you create UPI payment orders, redirect customers to a hosted checkout, and receive signed webhooks when payments complete. All API calls are server-to-server — never expose your secret in a browser or mobile app.
{{ $desc }}
Authentication
Every request must include your API key and secret as headers. Find them in Dashboard → API & Webhooks.
Never expose your X-Api-Secret in client-side code, mobile apps, or public repositories.
/api/v1/orders
Create order
Creates a pending order and returns a payment_url. Redirect your customer there. For standard UPI accounts, a upi_intent deep-link is also returned so you can render your own QR.
| Parameter | Type | Description |
|---|---|---|
{{ $name }}
@if ($required)
required
@else
optional
@endif
|
{{ $type }} | {{ $desc }} |
/api/v1/orders/{order_id | client_order_id}
Get order status
Returns the latest order state, checking the payment provider if the order is still pending. Always confirm with this endpoint or a verified webhook before fulfilling an order — never trust the redirect URL alone.
@include('docs._code', ['title' => 'cURL', 'lang' => 'bash', 'code' => "curl {$base}/orders/INV1001 \\ -H \"X-Api-Key: key_xxx\" \\ -H \"X-Api-Secret: sec_xxx\" \\ -H \"Accept: application/json\""]) @include('docs._code', ['title' => 'Response · 200 OK', 'lang' => 'json', 'code' => '{ "success": true, "data": { "order_id": "ORDAB12CD34EF56GH78", "client_order_id": "INV1001", "amount": "199.00", "currency": "INR", "status": "paid", "utr": "427123456789", "paid_at": "2026-01-01T12:10:00+05:30" } }'])Order object
An order moves through these statuses:
{{ $d }}
/api/v1/accounts
List UPI accounts
Returns your active UPI accounts with their IDs, daily limits, and remaining capacity. Use the id as payment_account_id when creating an order to pin it to a specific account.
Rotation & daily limits
When you omit payment_account_id, the gateway automatically picks an account based on your rotation mode:
A random account among those with remaining daily capacity.
Your default account is used until it hits its daily limit, then falls back to others.
Each account has a daily limit (₹1,00,000 by default). Usage includes paid orders from today plus open pending orders. If no account has capacity, the API returns 422 with an amount error.
Webhook events
Configure your endpoint in Dashboard → API & Webhooks. We send a signed POST request for each event. Respond with any 2xx status; failed deliveries are retried up to 6 times with exponential backoff.
{{ $event }} |
{{ $desc }} |
The same event may be delivered more than once. Always handle webhooks idempotently using client_order_id.
Verify signature
Every webhook includes an X-Signature header containing the HMAC-SHA256 of the raw request body, keyed with your API secret. Always verify this before processing.
Error codes
All errors return a JSON body with a message field. Validation errors (422) also include an errors object keyed by field name.
| Status | Meaning |
|---|---|
{{ $code }} |
{{ $meaning }} |
Code examples
Quick-start snippets for common server-side languages.
@include('docs._code', ['title' => 'Python (requests)', 'lang' => 'python', 'code' => "import requests, hmac, hashlib headers = { 'X-Api-Key': 'key_xxx', 'X-Api-Secret': 'sec_xxx', 'Accept': 'application/json', 'Content-Type': 'application/json', } res = requests.post( '". $base ."/orders', json={'amount': 199, 'client_order_id': 'INV1001'}, headers=headers, timeout=10, ) data = res.json() payment_url = data['data']['payment_url']"]) @php $guzzleCode = implode("\n", [ ' "' . $base . '"]);', '', '$res = $client->post("/orders", [', ' "headers" => [', ' "X-Api-Key" => "key_xxx",', ' "X-Api-Secret" => "sec_xxx",', ' "Accept" => "application/json",', ' ],', ' "json" => ["amount" => 199, "client_order_id" => "INV1001"],', ']);', '', '$data = json_decode($res->getBody(), true);', '$paymentUrl = $data["data"]["payment_url"];', ]); @endphp @include('docs._code', ['title' => 'PHP (Guzzle)', 'lang' => 'php', 'code' => $guzzleCode])