Merchant sign in ↗
DEVELOPER DOCUMENTATION · V1

Connect once.
Keep every payment in view.

Create UPI collection requests, submit a UTR for review, and receive signed payment notifications. All amounts are INR. Call these APIs from your server; keep your secret out of browser and mobile code.

Before calling the API: ask your administrator for a merchant account, generate API credentials in API & security, add your server's IP address, and enable API access. Configure a callback hostname approved by the server operator.

01 / Authenticate every request

Use HTTPS and a fresh cryptographically random nonce for each attempt. The timestamp is Unix seconds, accepted within ±300 seconds. The signature is lowercase hex HMAC-SHA256, using your API secret as UTF-8 bytes. Sign the exact body bytes sent on the wire.

X-PRN-Key: prn_...
X-PRN-Timestamp: 1789560000
X-PRN-Nonce: random-string-at-least-16-characters
X-PRN-Signature: lowercase-hex-hmac

Canonical string (five lines, no final newline):
HTTP_METHOD
EXACT_PATH_AND_QUERY
UNIX_TIMESTAMP
NONCE
LOWERCASE_HEX_SHA256_OF_BODY

The path includes the application virtual directory, if any, and the query string in its original order. For GET, hash an empty body. Nonces must be 16–80 letters, digits, underscores or hyphens. Reused nonces are rejected. Each merchant is limited to 120 requests per minute, with an additional IP limit.

02 / Create a payment

POST /Apis/v1.ashx/payments
Content-Type: application/json

{
  "order_id": "ORDER-1001",
  "amount": 1250.00,
  "customer": "Example Customer",
  "customer_mobile": "9876543210"
}

order_id is 1–80 letters, digits, dots, underscores or hyphens. Customer names are 2–100 characters. customer_mobile is required and must contain 10–15 digits. Amounts must be positive, have at most two decimal places, and fit the merchant's configured limits. The server allocates an active UPI destination with sufficient capacity.

{
  "success": true,
  "reference_no": "PRN0123456789abcdef0123456789abcdef",
  "merchant_order_id": "ORDER-1001",
  "customer_name": "Example Customer",
  "customer_mobile": "9876543210",
  "amount": 1250.00,
  "status": "PENDING",
  "expires_at": "2026-09-16T12:00:00.000Z",
  "upi_uri": "upi://pay?pa=...",
  "qr_image": "data:image/png;base64,..."
}

Requests expire in 1 hour. The merchant/order pair is the idempotency key: retrying identical details returns the existing payment; changing the amount or customer returns 409. Use a fresh nonce for every retry. Creation returns 201, including an idempotent replay.

03 / Submit the UTR and proof

POST /Apis/v1.ashx/payments/utr
{
  "reference": "PRN0123456789abcdef0123456789abcdef",
  "utr": "634512789012",
  "proof_base64": "optional-raw-base64-without-data-prefix"
}

UTRs must contain 12–22 alphanumeric characters and are globally unique, case-insensitively. Images must be PNG or JPEG and smaller than 2 MB, with dimensions no greater than 4096 × 4096 and 12 million pixels. The decoded image is re-encoded and stored privately. The complete JSON request must be under 3,000,000 bytes. This API uses JSON base64 uploads so the entire proof is covered by the request signature.

Only the owning merchant can submit a UTR, while the payment is pending and unexpired. A screenshot and UTR require bank-record verification before approval.

04 / Check payment status

GET /Apis/v1.ashx/payments/status
/Apis/v1.ashx/payments/status?reference=PRN0123456789abcdef0123456789abcdef
/Apis/v1.ashx/payments/status?utr=634512789012

Supply exactly one reference or UTR. Results are restricted to the authenticated merchant. The response contains success and a data object with Reference, OrderId, Amount, Status, Utr, CreatedUtc, ReviewedUtc and other transaction fields.

05 / Verify callbacks

Approval and rejection queue durable notifications. Callback delivery has separate state from payment status. A worker retries unsuccessful deliveries up to eight times, with exponential delays starting at 60 seconds. Administrators can requeue failed events.

X-PRN-Event-ID: stable-event-uuid
X-PRN-Timestamp: unix-seconds-for-this-attempt
X-PRN-Signature: lowercase-hex-hmac

Webhook canonical string:
EVENT_ID
TIMESTAMP
RAW_JSON_BODY

{
  "event": "payment.approved",
  "reference_no": "PRN...",
  "merchant_order_id": "ORDER-1001",
  "amount": 1250.00,
  "utr_no": "634512789012",
  "status": "APPROVED",
  "reviewed_at": "2026-09-16T12:01:00Z"
}

Verify HMAC with the API secret active when the event was queued, compare signatures in constant time, and reject timestamps outside your allowed window. Retain the previous secret for pending callbacks after rotation. Deduplicate by event ID and return a 2xx status after durable processing. Redirects are not followed. Callback endpoints require an operator-approved public HTTPS hostname on port 443.

Errors and states

{"success":false,"message":"Description","request_id":"correlation-id"}
StatusMeaning
400Invalid fields, JSON, limits, or HTTPS requirement
401 / 403Invalid authentication / insufficient access or disallowed IP
404Unknown endpoint or payment
409Duplicate UTR/nonce/order, insufficient capacity, or conflicting state
413 / 415Request too large / unsupported content type
429Rate limit reached; retry later with a fresh nonce
500 / 503Internal failure / unavailable database

Payment states: PENDING → UTR_SUBMITTED → APPROVED or REJECTED. Unpaid requests become EXPIRED. Approval and rejection are final. Callback delivery is tracked independently as Pending, Retrying, Delivered, or Failed.