Реалізація єдиного платіжного модуля для всіх міні-програм 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 пройде модерацію з першого разу.







