Реалізація єдиного платіжного модуля для всіх міні-програм 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, не виводити користувача з додатку
  • Дублювання запиту → idempotent orderId на стороні сервера

Ориентири по терміне

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