Modern, typed Python client for the Uzum Checkout API (v1.10.3) and the Uzum Receipt Producer (OFD) API. Built on httpx with pydantic v2 models; ships sync and async clients.
- One HTTP stack (
httpx) for both sync (Client) and async (AsyncClient). - Resource-grouped API:
client.payments.*andclient.acquiring.*. - Typed pydantic v2 request/response models (camelCase on the wire, snake_case in Python).
- ECDSA
X-Signaturesigning as anhttpx.Authflow (key loaded once, async-safe). - Typed exceptions mapped from HTTP status + Uzum
errorCode. - Separate
ReceiptClient/AsyncReceiptClientfor the Receipt Producer service. - Fully type-hinted (
py.typed, PEP 561).
- Python >= 3.12
uv add uzum-payments
# or
pip install uzum-paymentsfrom uzum_payments import Client
from uzum_payments.models import (
OrderPaymentRequest,
AcquiringPaymentParams,
Currency,
PaymentViewType,
)
with Client(
terminal_id="your-terminal-id",
api_key="your-api-key",
signature_private_key="/path/to/merchant_private_key.pem",
) as client:
register = client.payments.register(
OrderPaymentRequest(
view_type=PaymentViewType.REDIRECT,
client_id="client-1",
currency=Currency.UZS,
order_number="order-42",
session_timeout_secs=600,
amount=150_000, # minimal currency units (tiyin)
payment_params=AcquiringPaymentParams(pay_type="ONE_STEP"),
)
)
print(register.order_id, register.payment_redirect_url)
status = client.payments.get_order_status(register.order_id)
print(status.status)
# two-stage payment lifecycle
client.acquiring.complete(register.order_id, amount=150_000)
client.acquiring.refund(register.order_id, amount=50_000)
client.acquiring.reverse(register.order_id, amount=150_000)import asyncio
from uzum_payments import AsyncClient
async def main() -> None:
async with AsyncClient(terminal_id="your-terminal-id", api_key="your-api-key") as client:
status = await client.payments.get_order_status("order-id")
print(status.status)
asyncio.run(main())| Resource | Methods |
|---|---|
client.payments |
register, merchant_pay, get_order_status, get_operation_state, get_receipts |
client.acquiring |
complete, refund, reverse, get_bindings, get_merchant_certificate |
terminal_id— required for every Checkout request (X-Terminal-Id).api_key—X-API-Keyheader.merchant_access_token— UzumID JWT (X-Merchant-Access-Token).signature_private_key— path / PEM bytes of the merchant EC key. Each request is signed with ECDSA-SHA256 over the body and sent asX-Signature.fingerprint— mTLS fingerprint (X-Fingerprint).
from uzum_payments import ReceiptClient
with ReceiptClient(api_key="your-api-key") as receipts:
receipts.fiscal_receipt_generation(
operation_id="op-1",
date_time="2026-06-16T12:00:00",
cash_amount=0,
card_amount=150_000,
phone_number="998901234567",
items=[{"title": "Item", "quantity": 1, "price": 150_000}],
)An async AsyncReceiptClient mirrors the same methods with await.
All errors derive from uzum_payments.UzumError:
BadRequest, AuthenticationError, SignatureError, FingerprintError,
ValidationError, PaymentError, InternalServerError, NotResponding
(timeout), NetworkError, UnexpectedError.
from uzum_payments import PaymentError, NotResponding
try:
client.payments.register(request)
except PaymentError as exc:
print(exc.code, exc.message)
except NotResponding:
... # retryThe old flat ApiClient / ReceiptApiClient (with the is_async flag) is replaced by
dedicated Client / AsyncClient and ReceiptClient / AsyncReceiptClient, with
operations grouped under .payments / .acquiring and typed model returns instead of
raw dicts.
API reference: the OpenAPI spec ships in this repo as
checkout_openapi.yaml (Uzum Checkout v1.10.3).
Distributed under the MIT License. See LICENSE.