О насБлогКонтакты
E-commerce14 мая 2013 г. 5 мин 24

Первый e-commerce в Казахстане: как мы запустили интернет-магазин в 2013 году без нормальных платёжных систем

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

Первый e-commerce в Казахстане: как мы запустили интернет-магазин в 2013 году

Весной 2013 года клиент — оптовый поставщик электроники в Алматы — поставил задачу: запустить интернет-магазин с онлайн-оплатой. Два месяца разработки. Потом ещё два месяца, чтобы разобраться с платёжными системами.

Казахстанский рынок e-commerce в 2013 году был в начале пути. Kaspi.kz уже работал, но как кредитный сервис. Lamoda.kz только появилась. Большинство «интернет-магазинов» принимали заказы через форму и звонок менеджера, оплату — наличными курьеру.


Платёжные системы: реальная картина 2013 года

Казкомерцбанк (Kazkom) — основной банк-эквайер для интернет-платежей. Подключение:

  • Договор на эквайринг: 6–8 недель на согласование и подписание
  • Требования: ООО (не ИП), работающее более 6 месяцев, расчётный счёт в Казкоме
  • Комиссия: 2,5–3% от суммы транзакции
  • Техническая интеграция: API на основе 3DSecure + собственный протокол — документация на русском, 40 страниц PDF

Мы ждали договор 9 недель. Магазин запустили без карточного эквайринга.

WebMoney KZT (WMK) — работало, имело API, но аудитория — только технически грамотные пользователи. У большинства розничных покупателей WebMoney-кошелька не было.

QIWI — терминалы были в каждом торговом центре. Это оказался неожиданно популярный канал: клиент делает заказ на сайте, получает счёт, идёт к QIWI-терминалу и оплачивает.

Наличными курьеру — в итоге оказался основным каналом на первые 3 месяца.


Архитектура заказа под несколько каналов оплаты

// Модель заказа: поддерживает несколько методов оплаты
class Order {
    const STATUS_PENDING    = 'pending';     // Ожидает оплаты
    const STATUS_AWAITING   = 'awaiting';    // Ожидает подтверждения (QIWI/WebMoney)
    const STATUS_PAID       = 'paid';        // Оплачен
    const STATUS_PROCESSING = 'processing';  // В обработке
    const STATUS_SHIPPED    = 'shipped';     // Отправлен
    const STATUS_DELIVERED  = 'delivered';   // Доставлен
    const STATUS_CANCELLED  = 'cancelled';   // Отменён
    
    const PAYMENT_CARD    = 'card';     // Картой (Kazkom) — запустили позже
    const PAYMENT_QIWI    = 'qiwi';
    const PAYMENT_WEBMONEY = 'webmoney';
    const PAYMENT_CASH    = 'cash';     // Наличными курьеру
    const PAYMENT_TRANSFER = 'transfer'; // Банковский перевод для ИП
}
// PaymentRouter: направляет на нужный платёжный шлюз
class PaymentRouter {
    public function process(Order $order): PaymentResponse {
        switch ($order->payment_method) {
            case Order::PAYMENT_QIWI:
                return $this->processQiwi($order);
            case Order::PAYMENT_WEBMONEY:
                return $this->processWebMoney($order);
            case Order::PAYMENT_CASH:
                return $this->processCash($order);
            case Order::PAYMENT_TRANSFER:
                return $this->processTransfer($order);
        }
    }
    
    private function processQiwi(Order $order): PaymentResponse {
        // QIWI API: создаём счёт (bill)
        $billId = 'order_' . $order->id . '_' . time();
        
        $response = $this->httpPost('https://api.qiwi.com/api/v2/prv/' . QIWI_SHOP_ID . '/bills/' . $billId, [
            'user'    => 'tel:+7' . $order->phone,
            'amount'  => $order->total,
            'ccy'     => 'KZT',
            'comment' => 'Заказ #' . $order->id,
            'lifetime' => date('Y-m-d\TH:i:s', strtotime('+3 days')),
        ]);
        
        if ($response['response']['result_code'] == 0) {
            $order->update([
                'status'         => Order::STATUS_AWAITING,
                'payment_ref'    => $billId,
                'payment_expire' => date('Y-m-d H:i:s', strtotime('+3 days')),
            ]);
            return new PaymentResponse('awaiting', 'Счёт выставлен. Оплатите в любом QIWI-терминале.');
        }
        
        return new PaymentResponse('error', 'Ошибка выставления счёта');
    }
    
    private function processCash(Order $order): PaymentResponse {
        $order->update(['status' => Order::STATUS_PENDING]);
        
        // Уведомить менеджера для связи с клиентом
        Mail::send('manager@shop.kz', 'Новый заказ с оплатой курьеру', [
            'order_id' => $order->id,
            'amount'   => $order->total,
            'phone'    => $order->phone,
        ]);
        
        return new PaymentResponse('pending', 'Заказ принят. Менеджер свяжется для подтверждения доставки.');
    }
}

QIWI Callback: подтверждение оплаты

QIWI отправлял POST-запрос на наш сервер при каждом изменении статуса счёта:

// qiwi_callback.php — webhook от QIWI
$billId   = $_POST['bill_id'];
$status   = $_POST['status'];    // 'paid', 'rejected', 'expired'
$amount   = $_POST['amount'];
$sign     = $_POST['sign'];

// Проверка подписи: MD5 от параметров + пароль нотификаций
$expected = strtoupper(md5(
    $_POST['amount'] . '|' . $_POST['ccy'] . '|' . $_POST['bill_id'] . '|' .
    $_POST['site_id'] . '|' . $_POST['user'] . '|' . $_POST['prv_name'] . '|' .
    QIWI_NOTIFICATION_PASSWORD
));

if ($sign !== $expected) {
    http_response_code(403);
    exit('0'); // QIWI ожидает '0' при успехе, иначе повторит
}

$order = Order::findByPaymentRef($billId);
if (!$order) {
    http_response_code(404);
    exit('0');
}

if ($status === 'paid' && (float)$amount >= $order->total) {
    $order->update(['status' => Order::STATUS_PAID]);
    
    // Отправить подтверждение клиенту
    Sms::send($order->phone, "Оплата заказа #{$order->id} получена. Спасибо!");
    
    // Уведомить склад
    Mail::send('warehouse@shop.kz', 'Оплачен заказ #' . $order->id);
}

exit('0'); // QIWI: '0' = успешно обработано

Казком: интеграция когда договор наконец пришёл

Через 9 недель договор с Казкомом подписали. Их API в 2013 году был сложнее современных решений — XML-over-HTTPS с собственной схемой подписи:

// Kazkom Payment Gateway 2013 (упрощённо)
function createKazkomPayment(Order $order): string {
    $orderXml = sprintf(
        '<order order_id="%s" amount="%s" currency="398" merchant="%s">',
        $order->id, 
        number_format($order->total * 100, 0, '', ''), // В тиынах (центах)
        KAZKOM_MERCHANT_ID
    );
    
    // Подпись RSA приватным ключом магазина
    $signature = '';
    openssl_sign($orderXml, $signature, file_get_contents(KAZKOM_PRIVATE_KEY));
    
    $signedXml = $orderXml . '<merchant_sign type="RSA">' . 
                 base64_encode($signature) . '</merchant_sign></order>';
    
    // Передать на форму оплаты Казкома
    return 'https://epay.kkb.kz/jsp/process/logon.jsp?' . 
           http_build_query(['MERCHANT_ID' => KAZKOM_MERCHANT_ID, 
                             'OrderID'     => $order->id,
                             'Signed_Order_B64' => base64_encode($signedXml)]);
}

Цифры первых трёх месяцев

Метод оплаты Доля заказов Средний чек
Наличными курьеру 67% 18,400 тг
QIWI 21% 12,800 тг
WebMoney 8% 9,200 тг
Банковский перевод (ИП) 4% 87,000 тг

Наличными — доминирующий метод. QIWI-терминалы оказались отличным решением для пользователей без карт.

Когда в ноябре 2013 подключили Kazkom, доля карточных оплат за первые 6 недель составила 14% — это был уже заметный сегмент, и он рос с каждым месяцем.

Сегодня Kaspi Pay, Halyk Bank, Forte и другие банки предлагают подключение онлайн-эквайринга за 1–3 дня. В 2013 году 9 недель ожидания договора было нормой. Понимание этого контекста помогает точнее планировать запуск продуктов на казахстанском рынке — бюрократические сроки могут быть фактором в расписании запуска даже сегодня.

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

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

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

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

OWASP Top 10 2025: безопасность веб-приложений для казахстанского разработчикаaunimeda
Разработка

OWASP Top 10 2025: безопасность веб-приложений для казахстанского разработчика

OWASP Top 10 — это стандарт критических рисков безопасности. SQL-инъекции, сломанный контроль доступа, SSRF — каждый пункт с реальной атакой на ваш Node.js/Next.js код и конкретным исправлением. Актуально для проектов на казахстанском рынке.

Node.js vs Bun vs Deno 2026: бенчмарки и выбор runtime для продакшнaunimeda
Разработка

Node.js vs Bun vs Deno 2026: бенчмарки и выбор runtime для продакшн

Bun 1.x стабилен в production. Deno 2.0 поддерживает npm-пакеты. Node.js 22 запускает TypeScript нативно. Реальные бенчмарки производительности, сравнение инструментов и конкретные рекомендации для казахстанских разработчиков.

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

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

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