Skip to main content

halyk-epay

Async Python SDK for Halyk Bank ePay (Kazakhstan) — hosted page, cryptogram, webhooks. Type-annotated, Pydantic-v2 models, zero magic.

CI PyPI Python License: MIT

🇰🇿 Перейти к русской версии ↓


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 --strict in 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:

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 (usercred scope), 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

Передайте 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)

Source distribution for halyk-epay 0.1.0
File Size Uploaded
halyk_epay-0.1.0.tar.gz 17.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for halyk-epay 0.1.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page