Реалізація єдиного платіжного модуля для всіх міні-програм Super App
Ми розробляємо єдиний платіжний модуль для Super App, який централізує обробку транзакцій для всіх міні-програм. Кожен міні-додаток хоче приймати платежі, але розрізнені інтеграції з провайдерами створюють проблеми: розширюється scope PCI DSS, оновлення сертифікатів або ключів API вимагає синхронного деплою всіх міні-програм, у користувача немає єдиної історії платежів. Наш підхід вирішує ці завдання за допомогою bridge-архітектури, яка ізолює платіжну логіку в shell-додатку.
Досвід нашої команди в розробці платіжних систем — понад 5 років, ми реалізували централізовані платіжні модулі для 10+ Super App у ритейлі та фінтехі. Результат: скорочення часу інтеграції кожної нової міні-програми до 3 днів (що в 5-10 разів швидше за децентралізований підхід) і зниження витрат на підтримку платіжного скоупу на 60%. Наприклад, наш клієнт з маркетплейсом зекономив $120 000 на рік після впровадження модуля. Замовте аудит архітектури вашого 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 дні |
Централізація скорочує трудозатрати в 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 тижнів — від аналізу до релізу в двох міні-програмах. Вартість — від $15 000 під ключ. Щоб отримати попередній план та оцінку, пишіть на [email protected] або заповніть форму на сайті. Наші інженери мають сертифікати з iOS та Android розробки, забезпечуючи відповідність останнім вимогам App Store Review Guidelines та Google Play політик. Ми гарантуємо, що ваш Super App пройде модерацію з першого разу.







