Первый 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 недель ожидания договора было нормой. Понимание этого контекста помогает точнее планировать запуск продуктов на казахстанском рынке — бюрократические сроки могут быть фактором в расписании запуска даже сегодня.