Unofficial Python SDK for the Paylov payment gateway (Uzbekistan): card tokenization, charges, holds, P2P, A2C, service payments, fiscalization
Project description
paylov-uz
Unofficial Python SDK for Paylov — the Uzbekistan payment gateway. Covers the Subscribe API (card tokenization, on-demand charges, holds, P2P, A2C payouts, service payments, split payments, OFD fiscalization) and the hosted-checkout Merchant API link builder.
This is a community SDK, not an official Paylov product. API docs: https://developer.paylov.uz/, sandbox: https://sandbox.paylov.uz/.
Install
pip install paylov-uz
Quickstart — save a card and charge it (pay-as-you-go)
from paylov import PaylovClient, PaylovError
client = PaylovClient(
consumer_key="app_...",
consumer_secret="...",
username="...",
password="...",
sandbox=True, # False (default) for production gw.paylov.uz
)
# 1. Tokenize the card — Paylov sends an OTP to the cardholder
result = client.create_user_card(
user_id="42", card_number="8600001234567878", expire_date="2909",
)
card_id = result["cid"] # temporary card id
print("OTP sent to", result["otpSentPhone"])
# 2. Confirm with the OTP — card becomes chargeable
card = client.confirm_user_card(card_id, otp="456799")["card"]
# 3. Charge it whenever you want (amount in UZS)
try:
txn_id = client.charge(amount=5000, card_id=card["cardId"], user_id="42",
account={"invoice": "INV-1"})
print("paid:", txn_id)
except PaylovError as exc:
print("declined:", exc.code) # e.g. insufficient_funds
Hosted checkout link (Merchant API)
from paylov import build_checkout_url
url = build_checkout_url(
merchant_id="1b13c46f-...",
amount=25000, # UZS
return_url="https://example.uz/done/",
account={"order_id": 42},
)
# -> https://my.paylov.uz/checkout/create/<base64>
Token storage
Access tokens live 1 hour (refresh tokens ~7–30 days). By default they're
cached in-process; when you run several workers, implement TokenStorage so
they share one token pair:
from paylov import TokenStorage
class RedisTokenStorage(TokenStorage):
def __init__(self, redis):
self.redis = redis
def load(self):
raw = self.redis.get("paylov:token")
return json.loads(raw) if raw else None
def save(self, token):
self.redis.set("paylov:token", json.dumps(token))
client = PaylovClient(..., token_storage=RedisTokenStorage(redis))
API coverage
| Group | Methods |
|---|---|
| OAuth2 | automatic (password + refresh grants, retry on 401), revoke_token |
| User cards | create_user_card, confirm_user_card, delete_user_card, get_card, get_all_user_cards, check_phone_match, check_pinfl_match, create_official_profile |
| Charges | create_receipt, pay_receipt, charge (create+pay), get_transactions, cancel_transaction, get_card_history |
| Guest checkout | payment_without_registration, confirm_payment |
| Holds | hold_create, hold_charge, hold_dismiss, hold_status |
| A2C payouts | a2c_perform, a2c_perform_by_pan, a2c_check, a2c_check_by_external_id, a2c_balance |
| P2P | p2p_receiver, p2p_receiver_list, p2p_create, p2p_confirm |
| Service payments | service_list, service_fields, service_info, service_create, service_pay, service_status, service_transactions |
| Split | split_payment, split_status |
| Fiscalization | fiscal_register, fiscal_status, fiscal_refund, fiscal_activity_types |
| Sub-merchants | sub_merchant_create, sub_merchant_transfer |
| Checkout | build_checkout_url |
Every API error raises PaylovError with .code, .message, .data, and
.http_status.
Amount units
- Receipts / holds / service payments: integer UZS (som).
- A2C and P2P: tiyin (1 UZS = 100 tiyin).
expire_dateis YYMM (e.g.2909= September 2029).
Sandbox test cards
| Card number | Expiry | OTP | Type |
|---|---|---|---|
| 9860090101059377 | 2803 | 456788 | Humo |
| 9860090101999903 | 2803 | 456789 | Humo |
| 8600001234567878 | 2909 | 456799 | Uzcard |
| 8600001234678989 | 2912 | 456719 | Uzcard |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file paylov_uz-0.1.0.tar.gz.
File metadata
- Download URL: paylov_uz-0.1.0.tar.gz
- Upload date:
- Size: 12.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c813a9d307284dc4e856aca219ff28c048a99b42bf16d875eb6324ad5b254d03
|
|
| MD5 |
0e8a3b04c8aac3142a8ff4c07220a42b
|
|
| BLAKE2b-256 |
cb04831e3579f6a847b77392e0e4d68deccfcac68346ac7a1e0e54ae8df3359a
|
File details
Details for the file paylov_uz-0.1.0-py3-none-any.whl.
File metadata
- Download URL: paylov_uz-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea8e94a5862add5fde357a7b8121f8dc6714e36748bcbf1698bc2e648a37f10e
|
|
| MD5 |
b7138bfe7bac7320d3fe250b4956b5ad
|
|
| BLAKE2b-256 |
4dac0f4772e22a8b0cb24d937fc70e85b33c3e5bdded6b8c6c761f2faa604ff9
|