О насБлогКонтакты
Мобильная разработка20 июня 2016 г. 5 мин 153Обновлено: 18 мая 2026 г.

Как сделать мобильное приложение для казахстанского рынка в 2016 году

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

Как сделать мобильное приложение для казахстанского рынка в 2016 году

Коротко: React Native (если кроссплатформа) или нативный Android Java (если только Android, 72% рынка). Обязательно: двуязычность (kk/ru), поддержка Android 4.4+ (покрывает 95% рынка), FCM для Push. Kaspi Pay через Deep Link - пользователи переходят в Kaspi, оплачивают, возвращаются к вам.


Рынок Казахстана в 2016

Платформа Доля Устройства
Android 5.x 38% Samsung, Xiaomi
Android 4.4 28% Бюджетные устройства
Android 6.x 14% Средний сегмент
iOS 9/10 18% iPhone 5s/6/6s/7
Другие 2% -

Минимальный SDK для Android: API 19 (Android 4.4) - покрывает 95% рынка.


React Native Setup (2016)

npm install -g react-native-cli
react-native init KazakhstanApp
cd KazakhstanApp

# Добавить FCM для Push (Android)
npm install --save react-native-fcm
react-native link react-native-fcm

# i18n для kk/ru
npm install --save react-native-i18n

Локализация: kk/ru

// i18n.js - конфигурация переводов
import I18n from 'react-native-i18n';

import kk from './locales/kk.json';
import ru from './locales/ru.json';

I18n.fallbacks = true;
I18n.defaultLocale = 'ru';

I18n.translations = {
  kk,
  ru,
};

export default I18n;
// locales/kk.json
{
  "welcome":        "Қош келдіңіз",
  "login":          "Кіру",
  "register":       "Тіркелу",
  "cart":           "Себет",
  "checkout":       "Тапсырыс рәсімдеу",
  "order_placed":   "Тапсырыс қабылданды",
  "delivery_time":  "Жеткізу уақыты",
  "total":          "Жалпы соммасы",
  "cancel":         "Болдырмау",
  "confirm":        "Растау",
  "search":         "Іздеу",
  "categories":     "Санаттар",
  "my_orders":      "Менің тапсырыстарым"
}
// locales/ru.json
{
  "welcome":        "Добро пожаловать",
  "login":          "Войти",
  "register":       "Регистрация",
  "cart":           "Корзина",
  "checkout":       "Оформить заказ",
  "order_placed":   "Заказ принят",
  "delivery_time":  "Время доставки",
  "total":          "Итого",
  "cancel":         "Отмена",
  "confirm":        "Подтвердить",
  "search":         "Поиск",
  "categories":     "Категории",
  "my_orders":      "Мои заказы"
}
// Использование в компоненте
import I18n from '../i18n';

function CartButton() {
    return <Button title={I18n.t('cart')} onPress={navigateToCart} />;
}

// Смена языка
import { NativeModules } from 'react-native';
I18n.locale = NativeModules.RNI18n.initialLocale || 'ru';
// Или: хранить выбор пользователя в AsyncStorage

Kaspi Pay через Deep Link

// KaspiPayment.js - оплата через Kaspi мобильное приложение

import { Linking, Platform } from 'react-native';

class KaspiPayment {

    static async pay(order) {
        // Kaspi Deep Link URL схема (2016)
        const kaspiUrl = `kaspi://pay?` + this.buildParams({
            merchantId:  'YOUR_MERCHANT_ID',
            amount:      Math.round(order.total * 100).toString(),  // Тиыны
            orderId:     order.id.toString(),
            returnUrl:   `myapp://payment-result?orderId=${order.id}`,
            description: `Заказ №${order.id}`,
        });

        const canOpen = await Linking.canOpenURL(kaspiUrl);

        if (!canOpen) {
            // Kaspi не установлен - открыть браузерную версию
            Linking.openURL('https://kaspi.kz/pay/...');
            return;
        }

        // Открыть Kaspi приложение
        Linking.openURL(kaspiUrl);
    }

    static buildParams(params) {
        return Object.entries(params)
            .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
            .join('&');
    }
}

// В App.js - обработка return URL
Linking.addEventListener('url', ({ url }) => {
    if (url.startsWith('myapp://payment-result')) {
        const params = parseUrlParams(url);
        const orderId = params.orderId;
        const success = params.status === 'success';

        if (success) {
            navigateToOrderSuccess(orderId);
        } else {
            navigateToOrderFailed(orderId);
        }
    }
});

FCM Push-уведомления (Android)

// push.js - Firebase Cloud Messaging

import FCM, { FCMEvent, RemoteNotificationIOS, NotificationType } from 'react-native-fcm';

class PushService {

    static async init() {
        await FCM.requestPermissions();

        const token = await FCM.getFCMToken();
        console.log('FCM Token:', token);

        // Отправить токен на сервер
        await API.post('/devices', {
            fcm_token: token,
            platform:  Platform.OS,
        });

        // Обработка уведомлений
        FCM.on(FCMEvent.Notification, async (notif) => {
            if (notif.local_notification) return;

            if (notif.opened_from_tray) {
                // Приложение было свёрнуто, пользователь тапнул на уведомление
                this.navigateByNotification(notif);
            }
        });

        FCM.on(FCMEvent.RefreshToken, (token) => {
            API.post('/devices', { fcm_token: token, platform: Platform.OS });
        });
    }

    static navigateByNotification(notif) {
        const type = notif.type || notif.data?.type;
        switch (type) {
            case 'order_status':
                Navigation.navigate('OrderDetail', { orderId: notif.data.order_id });
                break;
            case 'promo':
                Navigation.navigate('Promo', { promoId: notif.data.promo_id });
                break;
        }
    }
}

Сервер: отправка Push из PHP

<?php
// FcmService.php - отправка уведомлений через FCM

class FcmService {
    private string $serverKey;  // Firebase Console → Project Settings → Cloud Messaging

    public function send(array $tokens, array $notification, array $data = []): array {
        // FCM поддерживает массовую отправку до 1000 токенов
        $chunks  = array_chunk($tokens, 1000);
        $results = [];

        foreach ($chunks as $chunk) {
            $payload = [
                'registration_ids' => $chunk,
                'notification'     => [
                    'title' => $notification['title'],
                    'body'  => $notification['body'],
                    'icon'  => 'ic_notification',  // В drawable
                    'sound' => 'default',
                ],
                'data' => $data,
                'priority' => 'high',
            ];

            $ch = curl_init('https://fcm.googleapis.com/fcm/send');
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POST           => true,
                CURLOPT_HTTPHEADER     => [
                    'Authorization: key=' . $this->serverKey,
                    'Content-Type: application/json',
                ],
                CURLOPT_POSTFIELDS => json_encode($payload),
            ]);
            $results[] = json_decode(curl_exec($ch), true);
            curl_close($ch);
        }

        return $results;
    }

    public function notifyOrderStatus(int $userId, int $orderId, string $status): void {
        $tokens = DeviceRepository::getTokensByUser($userId);
        if (empty($tokens)) return;

        $statusLabels = [
            'confirmed'  => 'Заказ подтверждён',
            'processing' => 'Заказ собирается',
            'shipped'    => 'Заказ в пути',
            'delivered'  => 'Заказ доставлен',
        ];

        $this->send($tokens, [
            'title' => $statusLabels[$status] ?? 'Статус заказа изменён',
            'body'  => "Заказ №{$orderId}: " . ($statusLabels[$status] ?? $status),
        ], [
            'type'     => 'order_status',
            'order_id' => (string)$orderId,
        ]);
    }
}

Android Build для Google Play (Казахстан)

# Ключ подписи (однократно)
keytool -genkey -v \
    -keystore ~/kz-release.keystore \
    -alias kz-app \
    -keyalg RSA -keysize 2048 \
    -validity 25000

# android/app/build.gradle - подпись релизной сборки
signingConfigs {
    release {
        storeFile     file(System.getenv("KZ_KEYSTORE_PATH"))
        storePassword System.getenv("KZ_KEYSTORE_PASSWORD")
        keyAlias      System.getenv("KZ_KEY_ALIAS")
        keyPassword   System.getenv("KZ_KEY_PASSWORD")
    }
}

# Собрать релиз
cd android && ./gradlew assembleRelease
# APK: android/app/build/outputs/apk/app-release.apk

Результаты после запуска (2016, Казахстан)

Приложение доставки продуктов в Алматы:

Метрика 1 мес 6 мес
Установок 1,200 8,400
MAU 680 4,200
% заказов через app 15% 52%
Средний чек (app vs web) +22% +31%

Пользователи приложения делали заказы чаще и на большую сумму. Push-уведомления об акциях давали 12-18% конверсию в заказ.

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

Разработка мобильного приложения в Алматы - сколько стоит и с чего начатьaunimeda
Мобильная разработка

Разработка мобильного приложения в Алматы - сколько стоит и с чего начать

Стоимость разработки мобильного приложения в Алматы в 2026 году. iOS, Android, Flutter - что выбрать для бизнеса в Казахстане и как запустить приложение правильно.

SMS-платежи до App Store: как работала мобильная коммерция в Казнете в 2012 годуaunimeda
Мобильная разработка

SMS-платежи до App Store: как работала мобильная коммерция в Казнете в 2012 году

В 2012 году в Казахстане не было Kaspi Pay, не было мобильного банкинга в современном понимании. Был USSD, были премиум-SMS, было мобильное приложение Казкома, которое открывалось через WAP. Вот как мы строили мобильные платёжные интеграции в тех условиях.

Supabase vs Firebase 2026: сравнение для казахстанских стартапов и командaunimeda
Веб-разработка

Supabase vs Firebase 2026: сравнение для казахстанских стартапов и команд

Supabase - open-source BaaS на PostgreSQL с возможностью самохостинга. Firebase - зрелая Google-платформа. PocketBase - один бинарник для MVP. Сравниваем по модели данных, цене, realtime и соответствию требованиям казахстанского рынка.

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

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

Мобильные приложения

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