Skip to main content

Async Python SDK for Halyk Bank ePay (Kazakhstan) — hosted page, cryptogram, webhooks.

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

halyk_epay-0.1.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

halyk_epay-0.1.0-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file halyk_epay-0.1.0.tar.gz.

File metadata

  • Download URL: halyk_epay-0.1.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for halyk_epay-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f4837c5d7e8f019cf5d2891309ca82e55d2dd0af3db8fb572d8963cc448cac07
MD5 11d614a1893e048ffeb0f18f8df0c29d
BLAKE2b-256 191b36522c01c17f4faea6905ef28e6a014162134b60bc4e51d68f460f09511b

See more details on using hashes here.

Provenance

The following attestation bundles were made for halyk_epay-0.1.0.tar.gz:

Publisher: publish.yml on Medeeet/halyk-epay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file halyk_epay-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: halyk_epay-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for halyk_epay-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9ba08f64fb831cbba1e3b5fa6e0833c84d8d7a1390af9cd0fc5777cf1a441531
MD5 8f665139c02d4a880668b700f3cc1b19
BLAKE2b-256 f3cdbf039b6e46cb913b33b0e32f6b20ba578b4b2d58ce9a5724c113c07476b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for halyk_epay-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Medeeet/halyk-epay

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page