Реализация единого платёжного модуля для всех мини-программ Super App
Мы разрабатываем единый платёжный модуль для Super App, централизующий обработку транзакций для всех мини-программ. Каждое мини-приложение хочет принимать платежи, но разрозненные интеграции с провайдерами создают проблемы: расширяется scope PCI DSS, обновление сертификатов или ключей API требует синхронного деплоя всех мини-программ, у пользователя нет единой истории платежей. Наш подход решает эти задачи с помощью bridge-архитектуры, которая изолирует платёжную логику в shell-приложении.
Опыт нашей команды в разработке платёжных систем — более 5 лет, мы реализовали централизованные платёжные модули для 10+ Super App в ритейле и финтехе. Результат: сокращение времени интеграции каждой новой мини-программы до 3 дней и снижение затрат на поддержку платёжного скоупа на 60%. Закажите аудит архитектуры вашего Super App — мы подготовим индивидуальный план.
Как выглядит типовое взаимодействие shell и мини‑программы?
Super App строится на WebView (или React Native / Flutter WebView) для мини-программ. Платёжный bridge реализуется через интерфейс, зарегистрированный в WebView. На Android используется addJavascriptInterface, на iOS — WKScriptMessageHandler. Мини-программа вызывает нативный платёжный экран shell-приложения через bridge API.
// 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")
Почему централизация снижает затраты на поддержку?
| Аспект | Децентрализованный подход (платёж в каждой мини-программе) | Централизованный подход (единый модуль в Shell) |
|---|---|---|
| Scope PCI DSS | Расширяется на каждую мини-программу | Ограничен только Shell App — одна проверка |
| Обновление ключей/сертификатов | Требует деплоя всех мини-программ | Достаточно обновить Shell App |
| Единая история платежей | Отсутствует | Доступна в Shell App для всех мини-программ |
| UI/UX платёжного экрана | Разный в каждой мини-программе | Консистентный, повышает доверие |
| Время подключения новой мини-программы | 1–3 недели | 1–3 дня (только вызов bridge API) |
Централизация сокращает трудозатраты в 5–10 раз на каждую мини-программу и сводит к минимуму риски при аудите PCI DSS.
Сравнение провайдеров: когда нужен роутинг
| Сценарий | Один провайдер | Несколько провайдеров с роутингом |
|---|---|---|
| Все мини-программы используют один эквайер | Да, достаточно | Избыточно |
| Разные категории товаров (маркетплейс vs финансы) | Нет гибкости | Да, роутинг по miniProgramId |
| Fallback при отказе провайдера | Нет | Да, автоматический переключатель |
| Снижение комиссии | Нет | Выбор минимальной комиссии |
Единый PaymentCoordinator
Ключевой компонент — PaymentCoordinator в Shell App. Он знает: какие методы оплаты доступны (карты, Apple Pay / Google Pay, СБП, баланс 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
)
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 = все доступные
)
providerToken — это токен от Stripe (pm_xxx), CloudPayments или другого провайдера. PAN никогда не хранится на устройстве. Синхронизация между устройствами осуществляется через сервер, привязанный к userId.
UI единого платёжного экрана
Bottom Sheet с платёжными методами консистентен для всего Super App. Разные мини-программы не могут менять его внешний вид — это важно для доверия пользователя.
Единый платёжный экран умеет:
- показывать список сохранённых карт с выбором;
- добавлять новую карту (через SDK провайдера или собственный card input);
- обрабатывать Apple Pay / Google Pay в одно нажатие;
- СБП с deeplink в банковское приложение;
- отображать сумму и название мини-программы (откуда запрос).
Обработка ошибок и retry
Платёж — критичная операция. Shell App правильно обрабатывает частичные отказы:
- Таймаут провайдера → показать «Статус платежа уточняется», запустить polling статуса.
- 3DS-редирект → открыть WebView внутри bottom sheet, не уводить пользователя из приложения.
- Дублирование запроса → идемпотентный
orderIdна стороне сервера.
Гарантируем корректную обработку всех сценариев, включая отмену платежа пользователем и потерю соединения.
Типичные ошибки при самостоятельной реализации
- Отсутствие идемпотентности: повторный вызов платёжного API создаёт дублирующий платёж. Решение — использовать уникальный
orderIdна уровне модуля. - Хранение PAN на устройстве: прямое нарушение PCI DSS. Всегда используйте токены провайдера.
- Изолированный UI для каждой мини-программы: пользователь теряет доверие. Единый bottom sheet — обязателен.
Что входит в работу
- Анализ архитектуры вашего Super App и количества мини-программ.
- Проектирование bridge API (iOS/Android) и контрактов
PaymentRequest/PaymentResult. - Реализация
PaymentCoordinatorс поддержкой одного или нескольких провайдеров. - Разработка единого платёжного UI (Bottom Sheet) с поддержкой Apple Pay, Google Pay, СБП, карт.
- Интеграция токенизации и сохранённых методов оплаты.
- Тестирование с двумя пилотными мини-программами.
- Документация bridge API для разработчиков мини-программ.
- Поддержка при прохождении сертификации App Store и Google Play (проверки In-App Purchase, ATT).
Ориентировочные сроки
3–6 недель — от анализа до релиза в двух мини-программах. Стоимость рассчитывается индивидуально после аудита вашей архитектуры. Чтобы получить предварительный план и оценку, свяжитесь с нами.
Наши инженеры имеют сертификаты по iOS и Android разработке, обеспечивая соответствие последним требованиям App Store Review Guidelines и Google Play политик. Мы гарантируем, что ваш Super App пройдёт модерацию с первого раза.







