Auto Upi API documentation
Auto Upi is a self-serve UPI collection gateway. Create an order from your server, send the customer to the hosted checkout page, and the order is confirmed automatically — no commission, no reconciliation, money straight into your UPI account.
https://autoupi.in/api/public/v1application/jsonX-API-KeyQuickstart
- Create an account and sign in to the merchant console.
- Connect an account — pick PhonePe or Paytm and complete the setup on the Connect Accounts page.
- Generate an API key on the API Keys page. Copy it once; regenerating replaces the old key.
- Create an order from your server and redirect the customer to the returned
payment_url. - Confirm the payment through the status endpoint or your webhook, then fulfil the order.
Authentication
Every request carries your secret key in the X-API-Key header. Keys start withaupi_live_ and are stored hashed — an old key can never be shown again. Call the API only from your server; never expose the key in browser code.
X-API-Key: aupi_live_xxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/jsonCreate order
POST /api/public/v1/create-order
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Order amount in INR, 1 to 10,00,000. |
customer_name | string | No | Shown on the checkout page. |
webhook_url | string | No | HTTPS URL that receives the signed payment.paid webhook. |
link_type | string | No | one_time (default) or reusable. |
curl -X POST https://autoupi.in/api/public/v1/create-order \
-H "X-API-Key: aupi_live_your_key" \
-H "Content-Type: application/json" \
-d '{"amount": 1499, "customer_name": "Rahul Sharma", "webhook_url": "https://yoursite.com/autoupi-webhook.php"}'{
"ok": true,
"order_id": "ORD20260915A1B2C3",
"slug": "9fkq2wra",
"amount": 1499,
"payable_amount": 1499.37,
"status": "active",
"payment_url": "https://autoupi.in/pay/9fkq2wra"
}Always charge payable_amount: it can differ from amount by up to ₹0.99 so each active order stays unique. The customer pays payable_amount; your books are credited with the base amount.
Order status
GET /api/public/v1/order-status?order_id=ORD…
Poll this endpoint from your server (or after the customer returns) to confirm a payment before fulfilment.
curl "https://autoupi.in/api/public/v1/order-status?order_id=ORD20260915A1B2C3" \
-H "X-API-Key: aupi_live_your_key"{
"ok": true,
"order": {
"order_id": "ORD20260915A1B2C3",
"slug": "9fkq2wra",
"customer_name": "Rahul Sharma",
"amount": 1499,
"payable_amount": 1499.37,
"status": "paid",
"payer_name": "RAHUL SHARMA",
"paid_at": "2026-09-15T10:21:44.120Z",
"detected_at": "2026-09-15T10:21:52.480Z",
"expires_at": "2026-09-15T10:26:00.000Z"
}
}| Status | Meaning |
|---|---|
active | Waiting for payment. Links expire 5 minutes after creation. |
paid | A matching credit alert was detected. Safe to fulfil. |
expired | No payment detected in time. Create a new order. |
Webhooks
Each API key ships with a webhook secret (whsec_…) shown on the API Keys page. Pass awebhook_url when creating an order and we POST a signed payment.paid event the moment the order is confirmed as paid.
POST https://yoursite.com/autoupi-webhook.php
X-AutoUpi-Signature: t=1789453200,v1=6f3c…9ab
{
"event": "payment.paid",
"order_id": "ORD20260915A1B2C3",
"amount": 1499,
"payable_amount": 1499.37,
"status": "paid",
"payer_name": "RAHUL SHARMA",
"paid_at": "2026-09-15T10:21:44.120Z"
}
signed_payload = "{t}." + raw_request_body
v1 = hex(hmac_sha256(webhook_secret, signed_payload))<?php
// autoupi-webhook.php
$secret = "whsec_your_webhook_secret";
$raw = file_get_contents("php://input");
$header = $_SERVER["HTTP_X_AUTOUPI_SIGNATURE"] ?? "";
parse_str(str_replace(",", "&", $header), $parts); // t=..., v1=...
$expected = hash_hmac("sha256", $parts["t"] . "." . $raw, $secret);
if (!hash_equals($expected, $parts["v1"] ?? "")) {
http_response_code(401);
exit("bad signature");
}
$event = json_decode($raw, true);
if ($event["event"] === "payment.paid") {
// idempotent: skip if this order_id is already fulfilled
mark_order_paid($event["order_id"], $event["amount"]);
}
http_response_code(200);
echo "ok";Always treat delivery as at-least-once and keep your handler idempotent.
PHP integration in 3 files
Copy these three files into any PHP site (WordPress, Laravel, CodeIgniter or plain PHP). Only the API key, webhook secret and your database calls need changing.
<?php
class AutoUpi {
private string $key;
private string $base;
public function __construct(string $key, string $base = "https://autoupi.in/api/public/v1") {
$this->key = $key;
$this->base = $base;
}
private function request(string $url, ?array $body = null): array {
$ch = curl_init($url);
$headers = ["X-API-Key: {$this->key}"];
if ($body !== null) {
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_TIMEOUT => 20]);
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
return is_array($res) ? $res : ["ok" => false, "error" => "network_error"];
}
public function createOrder(float $amount, string $customer = "", string $webhook = ""): array {
return $this->request($this->base . "/create-order", [
"amount" => $amount,
"customer_name" => $customer,
"webhook_url" => $webhook,
]);
}
public function status(string $orderId): array {
return $this->request($this->base . "/order-status?order_id=" . urlencode($orderId));
}
public static function verify(string $raw, string $header, string $secret): bool {
parse_str(str_replace(",", "&", $header), $p);
if (empty($p["t"]) || empty($p["v1"])) return false;
return hash_equals(hash_hmac("sha256", $p["t"] . "." . $raw, $secret), $p["v1"]);
}
}<?php
require "autoupi.php";
$api = new AutoUpi("aupi_live_your_key");
$order = $api->createOrder(1499, "Rahul Sharma", "https://yoursite.com/autoupi-webhook.php");
if (empty($order["ok"])) {
die("Could not start payment: " . ($order["error"] ?? "unknown"));
}
// store it so the webhook can find the buyer later
save_order($order["order_id"], $_SESSION["user_id"], $order["amount"]);
header("Location: " . $order["payment_url"]);
exit;<?php
require "autoupi.php";
$raw = file_get_contents("php://input");
$sig = $_SERVER["HTTP_X_AUTOUPI_SIGNATURE"] ?? "";
if (!AutoUpi::verify($raw, $sig, "whsec_your_webhook_secret")) {
http_response_code(401);
exit("bad signature");
}
$event = json_decode($raw, true);
if (($event["event"] ?? "") === "payment.paid") {
// amount = your original order value; payable_amount = what the customer actually paid
mark_order_paid($event["order_id"], $event["amount"]);
}
http_response_code(200);
echo "ok";No webhook endpoint yet? Poll order-status on your thank-you page instead — the result is the same, just a few seconds slower.
Errors
| HTTP | Code | Fix |
|---|---|---|
| 401 | invalid_api_key | Key missing, revoked or replaced by a regenerate. |
| 400 | invalid_amount | Amount must be greater than 0 and up to 10,00,000. |
| 400 | UPI_NOT_CONFIGURED | Save a UPI ID on Connect Accounts first. |
| 400 | QUOTA_EXCEEDED | QR limit finished — upgrade to Pro. |
| 400 | ALL_PAYMENT_SLOTS_BUSY | Too many pending orders at the same amount; retry shortly. |
| 404 | not_found | The order ID does not belong to this key. |
Pricing
No per-transaction commission — you collect straight into your own UPI account.
Free
₹0to get started- 3 payment QR codes total
- 1 merchant account
- Full REST API access
- Automatic payment confirmation
Pro
₹299per 30 days- 3,000 QR codes per 30 days
- Unlimited payment links
- Signed webhooks
- Priority support
Custom
Talk to ushigh volume- Higher QR limits
- Multiple merchant accounts
- Self-hosted deployment
- Dedicated support
FAQ
No. Money reaches your own UPI account directly; Auto Upi only confirms and records the order.
They can't — each active order carries its own unique payable_amount.
5 minutes. After that the order becomes expired and moves to Transactions.
PHP 7.4 or newer with the cURL extension — no composer package required.
Yes. Regenerating issues a new key and instantly disables the previous one.
Auto UpiDOCS