О насБлогКонтакты
Бизнес и продукт18 июля 2015 г. 4 мин 341Обновлено: 18 мая 2026 г.

Как работать с Halyk Bank API для онлайн-платежей в Казахстане (2015)

AunimedaAunimeda
📋 Содержание

Как работать с Halyk Bank API для онлайн-платежей в Казахстане (2015)

Коротко: EPAY.kz (Halyk Bank эквайринг) работает по redirect-модели: вы создаёте форму с параметрами заказа, клиент переходит на страницу банка для оплаты, банк возвращает клиента на ваш сайт и отправляет postback. Проверяйте подпись postback через RSA публичный ключ банка.


Что такое EPAY.kz в 2015

EPAY - платёжный шлюз Народного Банка Казахстана. Принимал VISA, Mastercard, AmericanExpress. Интеграция через два метода:

  1. Form POST - форма HTML → редирект на страницу банка
  2. XML API - для серверного взаимодействия (более сложный)

В 2015 году для интернет-магазинов обычно использовался Form POST.


Form POST интеграция

<?php
// payment/Epay.php

class Epay {
    private string $merchantId;  // Выдаётся банком
    private string $terminalId;  // Выдаётся банком
    private string $backRefUrl;  // URL возврата после оплаты
    private bool   $testMode;
    private string $gatewayUrl;

    public function __construct(
        string $merchantId,
        string $terminalId,
        string $backRefUrl,
        bool   $testMode = false
    ) {
        $this->merchantId = $merchantId;
        $this->terminalId = $terminalId;
        $this->backRefUrl = $backRefUrl;
        $this->testMode   = $testMode;
        $this->gatewayUrl = $testMode
            ? 'https://epay-test.kkb.kz/jsp/process/logon.jsp'
            : 'https://epay.kkb.kz/jsp/process/logon.jsp';
    }

    /**
     * Сгенерировать HTML-форму для оплаты
     */
    public function createPaymentForm(array $order): string {
        $amount      = number_format($order['total'], 2, '.', '');
        $orderId     = str_pad($order['id'], 6, '0', STR_PAD_LEFT);  // "000042"
        $currency    = '398';  // KZT по ISO 4217
        $description = 'Заказ #' . $order['id'];

        // Создать XML-строку для подписи (специфика EPAY)
        $xml = '<document>'
             . '<merchant cert_id="' . $this->merchantId . '" name="' . $this->merchantId . '">'
             . '<order order_id="' . $orderId . '" currency="' . $currency . '" amount="' . $amount . '">'
             . '<department merchant_id="' . $this->terminalId . '" amount="' . $amount . '"/>'
             . '</order>'
             . '</merchant>'
             . '</document>';

        $signedXml = $this->signXml($xml);

        $params = [
            'Signed_Order_B64' => base64_encode($signedXml),
            'BackRef'          => $this->backRefUrl . '?orderId=' . $order['id'],
            'email'            => $order['email'] ?? '',
            'PostLink'         => 'https://myshop.kz/payment/epay/postback',
            'FailurePostLink'  => 'https://myshop.kz/payment/epay/postback',
            'Language'         => 'rus',  // rus или kaz
        ];

        $html  = '<form method="POST" action="' . $this->gatewayUrl . '" id="epay-form">' . "\n";
        foreach ($params as $name => $value) {
            $html .= '<input type="hidden" name="' . htmlspecialchars($name) 
                  . '" value="' . htmlspecialchars($value) . '">' . "\n";
        }
        $html .= '<button type="submit">Оплатить картой</button>' . "\n";
        $html .= '</form>' . "\n";

        return $html;
    }

    /**
     * Обработка postback от EPAY
     * Bank отправляет POST с response_code
     */
    public function processPostback(array $post): bool {
        // EPAY отправляет XML в поле 'response'
        $responseXml = $post['response'] ?? '';
        if (empty($responseXml)) return false;

        $xml = simplexml_load_string(base64_decode($responseXml));
        if (!$xml) return false;

        // Проверить подпись через RSA открытый ключ банка
        if (!$this->verifySignature($responseXml)) {
            error_log('EPAY postback: invalid signature');
            return false;
        }

        $responseCode = (string)($xml->bank->results->payment['response_code'] ?? '-1');
        return $responseCode === '00';  // '00' = успешная оплата
    }

    private function signXml(string $xml): string {
        // Подпись через приватный ключ магазина (выдаётся банком как .pfx)
        $pfxPath     = '/etc/ssl/epay/merchant.pfx';
        $pfxPassword = EPAY_PFX_PASSWORD;

        $p12 = file_get_contents($pfxPath);
        openssl_pkcs12_read($p12, $certs, $pfxPassword);

        $privateKey = $certs['pkey'];
        openssl_sign($xml, $signature, $privateKey, OPENSSL_ALGO_SHA1);

        // Добавить подпись в XML
        return $xml . '<signature>' . base64_encode($signature) . '</signature>';
    }

    private function verifySignature(string $encodedResponse): bool {
        // Проверить подпись ответа через публичный ключ банка
        $bankCertPath = '/etc/ssl/epay/bank.cer';
        $bankCert     = file_get_contents($bankCertPath);
        $bankPubKey   = openssl_get_publickey($bankCert);

        $xml = simplexml_load_string(base64_decode($encodedResponse));
        if (!$xml) return false;

        $signatureB64 = (string)($xml->signature ?? '');
        $signature    = base64_decode($signatureB64);

        // Убрать тег signature из XML перед проверкой
        $xmlWithoutSig = preg_replace('/<signature>.*?<\/signature>/s', '', base64_decode($encodedResponse));

        $result = openssl_verify($xmlWithoutSig, $signature, $bankPubKey, OPENSSL_ALGO_SHA1);
        return $result === 1;
    }
}

Контроллер оплаты

<?php
// Показать форму оплаты
public function showEpayForm(int $orderId): void {
    $order = OrderRepository::findForUser($orderId, currentUserId());

    $epay = new Epay(
        EPAY_MERCHANT_ID,
        EPAY_TERMINAL_ID,
        'https://myshop.kz/payment/epay/return',
        !IS_PRODUCTION
    );

    $form = $epay->createPaymentForm($order);

    // Сохранить факт инициации
    OrderRepository::update($orderId, ['status' => 'payment_initiated', 'payment_method' => 'epay']);

    // Отобразить промежуточную страницу с формой
    renderView('payment/epay', ['form' => $form, 'order' => $order]);
}

// Postback - вызывается банком
public function postback(): void {
    $epay = new Epay(EPAY_MERCHANT_ID, EPAY_TERMINAL_ID, '...');

    $orderId = (int)($_GET['orderId'] ?? 0);
    $success = $epay->processPostback($_POST);
    $order   = OrderRepository::find($orderId);

    if ($success && $order && $order['status'] === 'payment_initiated') {
        $xml     = simplexml_load_string(base64_decode($_POST['response']));
        $approvalCode = (string)($xml->bank->results->payment['approval_code'] ?? '');

        OrderRepository::markAsPaid($orderId, [
            'payment_method'     => 'epay',
            'payment_approval'   => $approvalCode,
            'paid_at'            => date('Y-m-d H:i:s'),
        ]);
    }

    // Банк ожидает HTTP 200 - иначе повторит postback
    http_response_code(200);
    echo 'OK';
}

Сравнение EPAY vs Kaspi Pay vs наличные (2015)

EPAY (Halyk) Kaspi Pay Наличные курьеру
Комиссия 2-2.5% 1.2-1.8% 0%
Охват 25% аудитории 45% аудитории 100%
Возраст аудитории 30-55 лет 18-40 лет Все
Риск невыкупа 0 0 15-25%
Время интеграции 2-3 дня 1-2 дня 0

Наш рекомендуемый стек 2015 года: Kaspi Pay + EPAY + наличные при доставке. Три метода покрывали 95%+ потенциальных покупателей.

Читайте также

AI в e-commerce Казахстана: персонализация, рекомендации и как не отстать от Kaspi в 2026aunimeda
Бизнес и продукт

AI в e-commerce Казахстана: персонализация, рекомендации и как не отстать от Kaspi в 2026

Kaspi.kz использует AI-персонализацию уже несколько лет. Как независимые интернет-магазины Казахстана могут применить те же принципы без бюджета tech-гиганта? Разбираем доступные AI-инструменты для казахстанского e-commerce.

Как запустить интернет-магазин в Алматы с нуля - пошаговый гайдaunimeda
Бизнес и продукт

Как запустить интернет-магазин в Алматы с нуля - пошаговый гайд

Пошаговый план запуска интернет-магазина для казахстанского бизнеса. Регистрация, платежи через Kaspi, домен, логистика - что нужно сделать до старта.

IT аутсорсинг в Казахстане - почему компании выбирают Алматыaunimeda
Бизнес и продукт

IT аутсорсинг в Казахстане - почему компании выбирают Алматы

Почему казахстанский и международный бизнес выбирает IT аутсорсинг в Алматы. Преимущества, риски и как правильно выстроить работу с аутсорс-командой.

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в Казахстане. Бесплатная консультация.

Получить консультацию Все статьи