halyk-epay
Async Python SDK for Halyk Bank ePay (Kazakhstan) — hosted page, cryptogram, webhooks. Type-annotated, Pydantic-v2 models, zero magic.
Why
Every Kazakhstani marketplace, e-commerce shop, and fintech app eventually integrates Halyk ePay — and ends up with the same ad-hoc httpx.post(...) blobs scattered across the codebase. This library extracts the well-trodden pattern into a small, well-tested package.
- One client, three flows: hosted page, cryptogram (direct), webhooks.
- Async by default. Drop into FastAPI / Starlette / aiohttp without a thread pool.
- Typed everything. Pydantic v2 models for requests and responses;
mypy --strictin CI. - Production-grade auth. OAuth tokens cached with leeway, auto-refreshed on 401, retried on 5xx with exponential backoff.
- Honest webhook security. Optional HMAC-SHA256 verification with constant-time compare; documented for the prevalent-but-undocumented case where merchants don't have signed callbacks.
Install
pip install halyk-epay
Requires Python 3.10+.
Quick start
Hosted payment page (most common)
import asyncio
from halyk_epay import HalykClient, InvoiceCreate
async def main():
async with HalykClient(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET",
shop_id="YOUR_SHOP_ID",
environment="test", # or "prod"
) as halyk:
invoice = await halyk.invoices.create(
InvoiceCreate(
invoice_id="ord-001",
account_id="user-42",
amount=10_000, # KZT, in tenge
currency="KZT",
description="Order #001",
back_link="https://shop.kz/return",
failure_back_link="https://shop.kz/failure",
post_link="https://shop.kz/halyk-webhook",
)
)
print(invoice.invoice_url) # redirect the user here
asyncio.run(main())
Cryptogram (direct API)
For in-app card forms where you collect card data yourself. Note: your environment must be PCI-DSS compliant to handle raw PAN.
from halyk_epay import CryptogramBuilder, HalykClient
from halyk_epay.models.payment import CardData
builder = CryptogramBuilder(terminal_id="...", environment="test")
cryptogram = builder.build(
CardData(pan="4405639704015096", exp_month="01", exp_year="27", cvc="321")
)
async with HalykClient(...) as halyk:
charge = await halyk.payments.charge(
invoice_id="ord-001",
amount=10_000,
currency="KZT",
cryptogram=cryptogram,
)
print(charge.status)
Webhook (FastAPI)
from fastapi import FastAPI, Header, HTTPException, Request
from halyk_epay import HalykSignatureError, WebhookVerifier
app = FastAPI()
verifier = WebhookVerifier(secret="...")
@app.post("/halyk-webhook")
async def webhook(request: Request, x_signature: str = Header(alias="X-Signature")):
body = await request.body()
try:
event = verifier.parse_and_verify(body, signature=x_signature)
except HalykSignatureError:
raise HTTPException(status_code=401)
if event.is_success:
# mark order event.invoice_id as paid
...
return {"status": "ok"}
If your merchant agreement doesn't include signed callbacks, use WebhookParser.parse(body) directly and validate against your stored invoice (amount, currency, status).
See the examples/ directory for runnable scripts.
Test sandbox
Halyk publishes a sandbox at testepay.homebank.kz with these credentials:
- Test card:
4405639704015096, expiry01/27, CVC321 - Test terminal id:
67e34d63-102f-4bd1-898e-370781d0074d - Public RSA key:
https://test-epay-api.epayment.kz/public.rsa
Pass environment="test" to HalykClient and CryptogramBuilder and you're on the sandbox.
API surface
| Resource | Method | Notes |
|---|---|---|
client.invoices.create(InvoiceCreate) |
POST /invoice |
Hosted page flow. |
client.invoices.get(halyk_uid) |
GET /invoice/{id} |
Status lookup. |
client.payments.charge(...) |
POST /payment/cryptopay |
One-shot cryptogram charge. |
CryptogramBuilder(terminal_id, ...).build(CardData) |
local | RSA-PKCS1v15, base64. |
WebhookParser.parse(body) |
local | snake_case + camelCase. |
WebhookVerifier(secret).parse_and_verify(body, signature) |
local | HMAC-SHA256, hex or base64. |
Roadmap
- v0.1 (now) — invoice CRUD, cryptogram charge, webhooks.
- v0.2 — refunds, partial refunds, two-step auth/capture.
- v0.3 — saved cards (
usercredscope), marketplace split payouts. - v0.4 — sync (blocking) client mirror for non-async codebases.
Contributing
Bug reports, feature requests, and PRs welcome — especially from anyone who has integrated Halyk and seen edge cases this SDK doesn't yet cover.
git clone https://github.com/Medeeet/halyk-epay
cd halyk-epay
pip install -e '.[dev]'
pytest && ruff check . && mypy src
Disclaimer
This is an unofficial community library. Not affiliated with or endorsed by Halyk Bank JSC. Endpoint URLs and request schemas are based on publicly observed integrations; verify against your merchant cabinet before going to production.
License
MIT — see LICENSE.
Русская версия
Асинхронный Python SDK для Halyk Bank ePay — hosted page, криптограмма, вебхуки. Полностью типизирован, модели на Pydantic v2, без магии.
Зачем
Каждый KZ-маркетплейс, интернет-магазин и финтех-проект рано или поздно интегрирует Halyk ePay — и каждый раз заново пишет одни и те же блоки httpx.post(...). Эта библиотека выносит проверенный паттерн в маленький, протестированный пакет.
- Один клиент, три сценария: hosted page, криптограмма (direct API), вебхуки.
- Асинхронный по умолчанию. Встраивается в FastAPI / Starlette / aiohttp без thread pool.
- Всё типизировано. Pydantic v2 модели для запросов/ответов,
mypy --strictв CI. - Production-grade auth. OAuth-токены кэшируются с leeway, обновляются при 401, ретраи на 5xx с экспоненциальным backoff.
- Честная безопасность вебхуков. HMAC-SHA256 верификация с constant-time compare; задокументирован и распространённый кейс, когда у мерчанта подпись не включена.
Установка
pip install halyk-epay
Требуется Python 3.10+.
Быстрый старт
Hosted Payment Page
import asyncio
from halyk_epay import HalykClient, InvoiceCreate
async def main():
async with HalykClient(
client_id="...",
client_secret="...",
shop_id="...",
environment="test",
) as halyk:
invoice = await halyk.invoices.create(
InvoiceCreate(
invoice_id="ord-001",
account_id="user-42",
amount=10_000,
currency="KZT",
description="Заказ №001",
back_link="https://shop.kz/return",
failure_back_link="https://shop.kz/failure",
post_link="https://shop.kz/halyk-webhook",
)
)
print(invoice.invoice_url) # редирект пользователя сюда
asyncio.run(main())
Тестовая песочница Halyk
- Карта:
4405639704015096, срок01/27, CVC321 - Terminal id:
67e34d63-102f-4bd1-898e-370781d0074d - Публичный RSA-ключ:
https://test-epay-api.epayment.kz/public.rsa
Передайте environment="test" в HalykClient и CryptogramBuilder — попадёте на песочницу.
Дисклеймер
Это неофициальная community-библиотека, не аффилирована с АО «Народный Банк Казахстана». URL'ы эндпоинтов и схемы запросов основаны на наблюдаемых интеграциях; перед продом сверьтесь с вашим личным кабинетом мерчанта.
Лицензия
MIT.
Metadata
Release files for halyk-epay 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| halyk_epay-0.1.0.tar.gz | 17.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| halyk_epay-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.5 kB
Release files / halyk_epay-0.1.0.tar.gz
| Download URL | halyk_epay-0.1.0.tar.gz |
|---|---|
| Size | 17.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f4837c5d7e8f019cf5d2891309ca82e55d2dd0af3db8fb572d8963cc448cac07
|
|
BLAKE2b-256 checksum How to use checksums |
191b36522c01c17f4faea6905ef28e6a014162134b60bc4e51d68f460f09511b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.
Transparency logRelease files / halyk_epay-0.1.0-py3-none-any.whl
| Download URL | halyk_epay-0.1.0-py3-none-any.whl |
|---|---|
| Size | 19.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9ba08f64fb831cbba1e3b5fa6e0833c84d8d7a1390af9cd0fc5777cf1a441531
|
|
BLAKE2b-256 checksum How to use checksums |
f3cdbf039b6e46cb913b33b0e32f6b20ba578b4b2d58ce9a5724c113c07476b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.
Transparency log