Реализация единого платёжного модуля для всех мини-программ Super App

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация единого платёжного модуля для всех мини-программ Super App
Сложный
от 1 недели до 3 месяцев
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Реализация единого платёжного модуля для всех мини-программ Super App

Super App — это оболочка, в которой живут десятки мини-приложений. Каждое мини-приложение хочет принимать платежи, но делать отдельную интеграцию с платёжным провайдером в каждом из них — ошибка по нескольким причинам: PCI scope расширяется на каждую мини-программу, обновление сертификатов или ключей API требует синхронного деплоя всех мини-программ, и у пользователя нет единой истории платежей.

Решение — платёжный модуль как часть хост-приложения (Shell App), который мини-программы вызывают через bridge API.

Архитектура: Shell ↔ Mini-Program Bridge

Типичная Super App строится на WebView (или React Native / Flutter WebView) для мини-программ. Платёжный bridge выглядит так:

// Android Shell App: регистрация bridge-метода
webView.addJavascriptInterface(PaymentBridge(this), "NativePayment")

class PaymentBridge(private val activity: AppCompatActivity) {
    @JavascriptInterface
    fun initiatePayment(requestJson: String) {
        val request = PaymentRequest.fromJson(requestJson)
        activity.runOnUiThread {
            PaymentBottomSheet.show(activity, request) { result ->
                val js = "window.onPaymentResult(${result.toJson()})"
                webView.evaluateJavascript(js, null)
            }
        }
    }

    @JavascriptInterface
    fun getSavedPaymentMethods(): String {
        return paymentRepository.getSavedMethods().toJson()
    }
}
// Мини-программа (JS/React): вызов платёжного модуля
async function checkout(amount, orderId) {
    return new Promise((resolve, reject) => {
        window.onPaymentResult = (result) => {
            if (result.status === 'success') resolve(result);
            else reject(result.error);
        };
        NativePayment.initiatePayment(JSON.stringify({
            amount,
            currency: 'RUB',
            orderId,
            miniProgramId: 'com.yourshop.miniapp'
        }));
    });
}

На iOS аналогичная схема через WKScriptMessageHandler:

class PaymentMessageHandler: NSObject, WKScriptMessageHandler {
    func userContentController(
        _ controller: WKUserContentController,
        didReceive message: WKScriptMessage
    ) {
        guard message.name == "initiatePayment",
              let body = message.body as? [String: Any] else { return }

        let request = PaymentRequest(from: body)
        PaymentCoordinator.shared.present(request: request, from: hostViewController) { result in
            let js = "window.onPaymentResult(\(result.jsonString))"
            webView.evaluateJavaScript(js)
        }
    }
}

// Регистрация в WKWebViewConfiguration
configuration.userContentController.add(PaymentMessageHandler(), name: "initiatePayment")

Единый PaymentCoordinator

Ключевой компонент — PaymentCoordinator в Shell App. Он знает:

  • какие методы оплаты доступны (карты, Apple Pay / Google Pay, SBP, баланс Super App)
  • какие карты сохранены для пользователя
  • какой провайдер обслуживает платёж (один платёжный шлюз или несколько)
// Android: PaymentCoordinator как singleton в Shell
class PaymentCoordinator private constructor() {
    companion object {
        val shared = PaymentCoordinator()
    }

    private val activeProviders = mutableMapOf<String, PaymentProvider>()

    fun registerProvider(id: String, provider: PaymentProvider) {
        activeProviders[id] = provider
    }

    fun initiatePayment(request: PaymentRequest, callback: (PaymentResult) -> Unit) {
        val provider = selectProvider(request)
        provider.process(request, callback)
    }

    private fun selectProvider(request: PaymentRequest): PaymentProvider {
        // Логика маршрутизации: разные мини-программы могут использовать разных провайдеров
        return activeProviders[request.miniProgramId]
            ?: activeProviders["default"]
            ?: throw IllegalStateException("No payment provider registered")
    }
}

Маршрутизация по miniProgramId позволяет одному Super App работать с несколькими эквайерами — один для маркетплейса, другой для сервиса доставки, третий для финансовых услуг.

Сохранённые методы оплаты (Saved Payment Methods)

Пользователь добавляет карту один раз — она доступна во всех мини-программах. Хранить токены карт нужно централизованно:

data class SavedPaymentMethod(
    val id: String,
    val type: PaymentMethodType, // CARD, SBP, APPLE_PAY
    val displayName: String,     // "Visa •••• 4242"
    val providerToken: String,   // токен конкретного провайдера (не PAN!)
    val isDefault: Boolean
)

providerToken — это токен от Stripe (pm_xxx), CloudPayments или другого провайдера. PAN никогда не хранится на устройстве.

Синхронизация между устройствами: токены хранятся на сервере, привязаны к userId. При первом открытии Super App после установки — загружаем список методов для пользователя.

UI единого платёжного экрана

Bottom Sheet с платёжными методами должен быть консистентным для всего Super App. Разные мини-программы не могут менять его внешний вид — это важно для доверия пользователя.

Что должен уметь единый платёжный экран:

  • Показать список сохранённых карт с возможностью выбора
  • Добавить новую карту (через SDK провайдера или собственный card input)
  • Apple Pay / Google Pay в одно нажатие
  • SBP с deeplink в банковское приложение
  • Отобразить сумму и название мини-программы (откуда пришёл запрос)
// PaymentBottomSheet получает PaymentRequest и показывает нужные методы
data class PaymentRequest(
    val amount: Long,           // в копейках
    val currency: String,
    val orderId: String,
    val miniProgramId: String,
    val miniProgramName: String, // "Доставка YourShop" — для отображения пользователю
    val allowedMethods: List<PaymentMethodType>? = null // null = все доступные
)

Обработка ошибок и retry

Платёж — критичная операция. Shell App должен правильно обрабатывать частичные отказы:

  • Таймаут провайдера → показать «Статус платежа уточняется», запустить polling статуса
  • 3DS редирект → открыть WebView внутри bottom sheet, не уводить пользователя из приложения
  • Дублирование запроса → идемпотентный orderId на стороне сервера

Ориентиры по срокам

3–6 недель: проектирование bridge API, реализация PaymentCoordinator, интеграция с провайдером(ами), единый UI bottom sheet, тестирование в нескольких мини-программах. Стоимость рассчитывается индивидуально после анализа архитектуры Super App и количества мини-программ.