# CHECKOUT.UZ API Documentation (for LLMs) > CHECKOUT.UZ is a unified payment gateway for Uzbekistan. This file is a > plain-text, complete reference of its REST API, written for LLMs and AI > agents that need to understand or integrate with it without executing > JavaScript or crawling a rendered web page. The human-friendly, interactive version of this documentation (with a live "Try it out" console, and cURL/JavaScript/PHP code samples) is at: https://checkout.uz/api-docs — also available in Russian, English and Tajik via the language switcher. ## Overview - API version: 1.3.0 - Style: REST, JSON request and response bodies - Base URL (production): https://checkout.uz/api/v1 - Base URL (backup): https://pre-view.checkout.uz/api/v1 - All endpoints below are called with POST and accept/return `application/json` (except where noted). - Monetary amounts are in UZS (Uzbek so'm) unless a response explicitly says otherwise (e.g. `get_balance`, which can also hold `usd`/`ton`). ## Authentication Every request must include your cash desk's ("kassa") API key as a Bearer token in the `Authorization` header: Authorization: Bearer YOUR_API_KEY - Get your API key from the dashboard: cash desk settings → API (https://checkout.uz/dashboard/shops). - The cash desk must be in `Faol` (Active) status — a pending or disabled cash desk's key will not authenticate, even if the key itself is correct. - If IP Whitelist is enabled for the cash desk, requests are only accepted from the whitelisted IP addresses. - Missing/invalid token → `401 Unauthorized`. - IP not whitelisted → `403 Forbidden`. ## Error format Errors are returned as JSON with an `error` field and an appropriate HTTP status code. Examples: 401 { "error": "Unauthorized: Invalid or missing Bearer token" } 403 { "error": "Access denied: Your IP (1.2.3.4) is not whitelisted" } 404 { "error": "Payment not found" } 400 { "error": "Invalid amount", "allowed": { "min": 1000, "max": 10000000, "currency": "UZS" } } ## Endpoints ### 1. POST /create_payment Create a new payment link (invoice). Request body (JSON): - `amount` (number, required) — payment amount in UZS. Must be between 1,000 and 10,000,000 inclusive. - `description` (string, optional) — free text shown to the payer. Defaults to a generic description if omitted. - `webhook_url` (string, optional) — if supplied, the payment-confirmed webhook is sent to this URL for this invoice IN ADDITION to the cash desk's configured `webhook_url` (both are called, not one-or-the-other). Must be a valid URL or the request is rejected with `400`. - `return_url` (string, optional) — if supplied, the payer is automatically redirected here (with a ~1.5s delay after the "paid" confirmation is shown) once payment succeeds — e.g. an e-commerce plugin's order-received page. Must be a valid URL or the request is rejected with `400`. If omitted, the payer simply stays on checkout.uz's own "paid" page. Not used for popup-window checkouts (window.opener flows use postMessage instead — see widget notes below). Example request: curl -X POST https://checkout.uz/api/v1/create_payment \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"amount": 50000, "description": "Order #12345", "return_url": "https://mysite.uz/order-received/12345"}' Example success response (200): { "status": "success", "payment": { "_id": 152, "_uuid": "550e8400-e29b-41d4-a716-446655440000", "_url": "https://checkout.uz/pay/550e8400-e29b-41d4-a716-446655440000", "_amount": 50000, "_status": "pending", "_pay_via": { "click": "https://checkout.uz/pay/550e8400-e29b-41d4-a716-446655440000/click", "payme": "https://checkout.uz/pay/550e8400-e29b-41d4-a716-446655440000/payme" }, "custom_payment_pages": [], "_return_url": "https://mysite.uz/order-received/12345", "_lifteme": { "_second": 3600, "_hour": 1 } } } Notes: - `_url` is a hosted checkout page — redirect the payer there, or open it in an iframe/new tab. - `_pay_via` gives direct one-click links per payment method, in the exact form `https://checkout.uz/pay/{_uuid}/{provider_key}` (NOT `/pay/via/...` — there is no `via` path segment), and only includes methods enabled on the cash desk. It excludes bank-card flows (`card`/`vmcard`), which are only reachable through `_url` or via `pay_via_card`/`confirm_card_payment` below. - `custom_payment_pages` lists any custom domains attached to the cash desk, each with the same invoice hosted at `https://{domain}/pay/{_uuid}`. - `_return_url` echoes back the `return_url` you supplied (or `null` if you didn't supply one) — purely informational, confirms what was stored. - The invoice expires after `_lifteme` (default: 1 hour / 3600 seconds) if left unpaid. - Errors: `400` invalid amount, invalid `webhook_url`, or invalid `return_url`; `401` unauthorized; `403` IP not whitelisted. ### 2. POST /status_payment Check the status of a payment by its numeric ID or UUID. Request body (JSON): - `id` (integer, optional) — the invoice's numeric ID. - `uuid` (string, optional) — the invoice's UUID (same value as `_uuid` from `create_payment`). - Exactly one of `id` or `uuid` must be supplied. Example request: curl -X POST https://checkout.uz/api/v1/status_payment \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"uuid": "550e8400-e29b-41d4-a716-446655440000"}' Example success response (200): { "status": "success", "data": { "id": 152, "amount": 50000, "status": "paid", "created_at": "2026-01-31 10:00:00", "paid_at": "2026-01-31 10:05:22" } } `status` is one of: `pending`, `paid` (an invoice may also be left unpaid and simply expire after its `_lifteme` window). Errors: `400` neither/both of id and uuid supplied with the wrong type, `404` payment not found (also returned if the invoice belongs to a different cash desk than the one that owns the API key used). ### 3. POST /get_balance Get the current balance of the authenticated cash desk, broken down by currency. Request body: none. Example request: curl -X POST https://checkout.uz/api/v1/get_balance \ -H "Authorization: Bearer YOUR_API_KEY" Example success response (200): { "status": "success", "balance": { "uzs": 2500000, "usd": 120, "ton": 15.5 } } ### 4. POST /get_history List the most recent transactions (invoices) for the authenticated cash desk, newest first. Request body (JSON): - `limit` (integer, optional, default `10`) — maximum number of records to return. Example request: curl -X POST https://checkout.uz/api/v1/get_history \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"limit": 5}' Example success response (200): { "status": "success", "data": [ { "id": 152, "amount": 50000, "status": "paid", "created_at": "2026-01-31 10:00:00", "paid_at": "2026-01-31 10:05:22" }, { "id": 151, "amount": 120000, "status": "paid", "created_at": "2026-01-30 18:22:11", "paid_at": "2026-01-30 18:23:40" } ] } ### 5. POST /get_stats Get aggregate statistics for the authenticated cash desk. Request body: none. Example request: curl -X POST https://checkout.uz/api/v1/get_stats \ -H "Authorization: Bearer YOUR_API_KEY" Example success response (200): { "status": "success", "stats": { "total_orders": 450, "total_amount": 12500000.50 } } `total_orders` counts every invoice ever created for the cash desk (any status); `total_amount` sums only invoices whose `status` is `paid`. ### 6. POST /get_payment_methods List the payment methods currently enabled on the authenticated cash desk, with display name and logos (light/dark variants for UI theming). Request body: none. Example request: curl -X POST https://checkout.uz/api/v1/get_payment_methods \ -H "Authorization: Bearer YOUR_API_KEY" Example success response (200): { "status": "success", "data": [ { "key": "click", "name": "Click - O'zbekiston", "logo_light": "https://.../click-light.png", "logo_dark": "https://.../click-dark.png" }, { "key": "payme", "name": "Payme - O'zbekiston", "logo_light": "https://.../payme-light.png", "logo_dark": "https://.../payme-dark.png" } ] } Only methods that are BOTH globally active AND enabled for this specific cash desk are returned. No secret/config data is ever included. ### 7. POST /pay_via_card — Step 1: send SMS code ### 8. POST /confirm_card_payment — Step 2: confirm SMS code These two endpoints let you replicate the "enter card number on our own UI" flow (the same one used on the hosted `/pay/{token}` checkout page) from your OWN server/app, instead of redirecting the payer to checkout.uz. Card payments are processed via Uzcard/Humo (Plum) and require a two-step SMS/OTP confirmation — there is no single-call "charge this card" endpoint, by design (the OTP must be entered by the actual cardholder). Flow: 1. Call `/pay_via_card` with the invoice's `order_id` plus the card number and expiry the payer typed in. If accepted, a bank SMS with a confirmation code is sent to the phone linked to that card, and you get back a `payment_token`. 2. Ask the payer for the SMS code, then call `/confirm_card_payment` with that `payment_token` and the `sms_code`. On success the invoice is marked `paid` immediately and the webhook (if configured) fires. `payment_token` is an opaque, encrypted, self-contained value (not a database ID) — treat it like a short-lived bearer credential. It expires 5 minutes after `/pay_via_card` returns it; after that you must call `/pay_via_card` again to get a fresh one and a new SMS. #### POST /pay_via_card Request body (JSON): - `order_id` (integer, required) — the invoice's numeric ID (`_id` from `create_payment`). - `card_number` (string, required) — 16-digit card number, with or without spaces. - `card_expiry` (string, required) — expiry date, `MM/YY` format. Example request: curl -X POST https://checkout.uz/api/v1/pay_via_card \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"order_id": 152, "card_number": "8600123456789012", "card_expiry": "12/28"}' Example success response (200): { "status": "success", "message": "Tasdiqlash kodi hamyoningiz ulangan telefonga yuborildi.", "payment_token": "2Q85LemHnysZBQWSgubRX6hL7h8ZfuaXKP-ma2CNZlZVyBtCPwlGsMZTGUfiJWWdQmzVSB5a3Wfeuu..." } Errors (`400`): invoice not found/not yours, invoice not pending (already paid/canceled), missing fields, or the card issuer/gateway rejected the card (wrong number, insufficient funds, etc. — the exact message is gateway-supplied). `403`: card payments not enabled on this cash desk. #### POST /confirm_card_payment Request body (JSON): - `payment_token` (string, required) — the token returned by `/pay_via_card`. - `sms_code` (string, required) — the confirmation code the payer received by SMS (usually 6 digits). Example request: curl -X POST https://checkout.uz/api/v1/confirm_card_payment \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"payment_token": "2Q85LemHnysZBQWSgubRX6hL7h8ZfuaXKP-ma2CNZlZVyBtCPwlGsMZTGUfiJWWdQmzVSB5a3Wfeuu...", "sms_code": "123456"}' Example success response (200): { "status": "success", "type": "success" } Errors (`400`): wrong/expired SMS code, expired or tampered `payment_token`, or `payment_token` issued to a different cash desk than the one authenticating the request. ## Webhooks (payment notifications) When a payment is confirmed, CHECKOUT.UZ sends an HTTP POST request with a JSON body to the `webhook_url` configured for the cash desk (dashboard → cash desk settings). This lets your server react in real time instead of polling `/status_payment`. - Method: POST, `Content-Type: application/json`. - Timeout: your endpoint has 15 seconds to respond (5 second connect timeout); the delivery is considered successful only if you return HTTP `200`. - Retries: delivery is best-effort and is not automatically retried on failure — reconcile periodically via `/status_payment` or `/get_history` if you need guaranteed consistency. - No cryptographic signature is currently attached to webhook requests. Re-verify the payment via `/status_payment` server-side before crediting anything critical, and keep your `webhook_url` private/unguessable. Example webhook payload: { "webhook_type": "version_1_1", "status": "success", "event": "payment_confirmed", "payment_system": "click", "shop_id": 42, "data": { "order_id": 152, "amount": 50000, "currency": "UZS", "status": "paid", "provider_details": { "...": "raw callback payload from the payment provider" }, "merchant_prepare": 998877, "perform_time": 1735689600000 }, "timestamp": 1735689600 } `payment_system` is one of: `click`, `payme`, `plum`, `vmcard` (bank card). The exact shape of `data` varies slightly per payment system, but `order_id`, `amount` and `status` are always present. ## Supported payment systems Depending on what's enabled per cash desk, payments can be accepted via: Click, Payme, Uzcard/Humo bank cards, and Plum. All amounts are currently processed in UZS. ## Limits - Minimum payment amount: 1,000 UZS - Maximum payment amount: 10,000,000 UZS per invoice - Unpaid invoices expire after 1 hour (3,600 seconds) by default ## Related pages - Interactive API docs with a live request console: https://checkout.uz/api-docs - Dashboard (create a cash desk, get an API key, configure webhook URL and IP whitelist): https://checkout.uz/dashboard - Sign up: https://checkout.uz/auth/register