LLPay API
Programmatically create UPI payment requests and check their status. All requests are JSON over HTTPS.
Base URL
/api/public/v1Relative to your LLPay deployment, e.g. https://yourdomain.com/api/public/v1.
Authentication
All requests must include your API key as a bearer token. Generate keys in API keys.
Authorization: Bearer llp_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXPOST /payments
Create a new payment request.
Request body
{
"amount": 499.00,
"customer_name": "Aman Verma",
"customer_email": "aman@example.com",
"customer_phone": "+91 98765 43210",
"external_ref": "order_12345"
}Response (201)
{
"id": "b13a...",
"status": "pending",
"amount": 499.00,
"currency": "INR",
"upi_id": "merchant@upi",
"upi_intent": "upi://pay?pa=...",
"pay_url": "https://yourdomain.com/pay/b13a...",
"external_ref": "order_12345",
"created_at": "2026-05-22T12:34:56Z",
"expires_at": "2026-05-22T13:04:56Z"
}GET /payments/:id
Look up the status of a payment.
curl https://yourdomain.com/api/public/v1/payments/<id> \
-H 'Authorization: Bearer llp_live_...'Response (200)
{
"id": "b13a...",
"status": "approved",
"amount": 499.00,
"utr_reference": "412345678901",
"external_ref": "order_12345",
"approved_at": "2026-05-22T12:38:11Z"
}Status values: pending, approved, rejected, expired.
GET /me
Retrieve your merchant profile and current balance.
{
"merchant_id": "...",
"business_name": "My Shop",
"balance": 14200.50,
"currency": "INR"
}Errors
- 400 — invalid request body
- 401 — missing or invalid API key
- 403 — accessing a payment from a different merchant
- 404 — payment or merchant not found
- 503 — no active collection UPI accounts configured
Webhooks
Register endpoints in Webhooks to receive a signed HTTP POST whenever a payment changes status.
Events
payment.approved— payment was approved by adminpayment.rejected— payment was rejected by adminpayment.expired— payment expired before approval
Headers
x-llpay-event: payment.approved
x-llpay-timestamp: 1716499200
x-llpay-signature: t=1716499200,v1=<hex hmac sha256>
x-llpay-delivery-id: <uuid>Body
{
"event": "payment.approved",
"created_at": "2026-05-22T12:38:11Z",
"data": {
"id": "b13a...",
"merchant_id": "...",
"amount_cents": 49900,
"currency": "INR",
"status": "approved",
"utr_reference": "412345678901",
"external_ref": "order_12345",
"customer_name": "Aman Verma",
"customer_email": "aman@example.com",
"approved_at": "2026-05-22T12:38:11Z"
}
}Verifying the signature (Node.js)
import crypto from 'crypto';
function verify(req, secret) {
const header = req.headers['x-llpay-signature']; // "t=...,v1=..."
const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));
const expected = crypto.createHmac('sha256', secret)
.update(parts.t + '.' + req.rawBody)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}Retries: failed deliveries (non-2xx or timeout) retry up to 6 times with backoff (30s → 1m → 5m → 30m → 2h → 6h). Respond 2xx within 10 seconds.