PolyPay

Native Android and iOS SDKs

Embed PolyPay payment-method selection and payment pages as native Android views or SwiftUI. No checkout WebView is used.

Native checkout flow

  1. Your authenticated server creates checkout without currency or network and returns only checkout_url.
  2. The SDK validates the HTTPS host and extracts the opaque trade ID from /pay/{tradeId}.
  3. The native selection page loads merchant-enabled currencies, networks, and fee estimates.
  4. After selection, Android opens compatible EVM wallets and otherwise shows exact manual payment details; iOS currently keeps its address QR and copy flow.
  5. Your server fulfills only after a verified webhook or authenticated reconciliation query.

1. Create a selectable checkout on your server

Keep X-API-Key on the server. Omit currency and network so the order starts in payment-method selection state.

// Trusted merchant server only. Never return the API Key to the app.
const response = await fetch('https://api.polypay.ai/api/v1/pay/order/checkout', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.POLYPAY_API_KEY!
  },
  body: JSON.stringify({
    mch_order_id: order.id,
    amount: order.amount,
    notify_url: 'https://merchant.example.com/webhooks/polypay'
    // Omit currency and network: the native SDK shows the selector.
  })
});

return { checkoutUrl: (await response.json()).data.checkout_url };

2. Install a native SDK

Android (Kotlin)

Register the Activity Result contract and launch the checkout URL returned by your server. Android API 24 or newer is supported.

dependencies {
  implementation("ai.polypay:checkout:0.1.1")
}
private val checkout = registerForActivityResult(PolyPayCheckoutContract()) { result ->
  // PAYMENT_DETECTED is not a fulfillment decision.
  viewModel.reconcileOnMerchantServer(result.tradeId)
}

checkout.launch(
  PolyPayCheckoutOptions(checkoutUrl = checkoutUrlFromYourServer)
)

iOS (SwiftUI or UIKit)

Add the Swift Package, create a validated configuration, then present the SwiftUI view or UIKit hosting controller. iOS 15 or newer is supported.

https://github.com/PolyPayAi/ios-sdk.git
let configuration = try PolyPayCheckoutConfiguration(
  checkoutURL: checkoutURLFromYourServer
)

PolyPayCheckoutView(configuration: configuration) { outcome in
  // paymentDetected is not a fulfillment decision.
  merchantAPI.reconcile(outcome)
}

Included native pages

Payment methodCurrency chips, compatible networks, merchant default, and server-provided fee estimates.
PaymentExact amount, currency, network, receiving address, copy actions, Android EVM wallet launch, and live observed status.
Terminal statesConfirming, detected, expired, cancelled, retryable network error, and safe close behavior.

Result and fulfillment authority

SDK results deliberately do not contain paid. PAYMENT_DETECTED on Android and paymentDetected on iOS mean the public order state changed; send the trade ID to your server and reconcile before fulfillment.

Security requirements

  • Never place API Keys, checkout signing secrets, webhook keys, or settlement credentials in an app.
  • Accept only HTTPS /pay/{tradeId} URLs from exact checkout-host allowlists.
  • Use server-provided amounts, addresses, networks, and fee quotes; never calculate payment destinations in the app.
  • Use verified Webhook v2 or an authenticated server query as the final order authority.
  • Cancel replaced unpaid attempts on the server and never overwrite a verified paid state.

Release verification

  • Build the Android release AAR, sample APK, unit tests, and lint checks.
  • Run Swift tests and build the package for an iOS Simulator on macOS.
  • Test Android wallet launch, manual copy actions, iOS QR scanning, expiry, cancellation, confirmation, and app dismissal on real devices.
  • Inspect app artifacts and logs to prove no merchant secret is present.
  • Verify no client event fulfills an order without server reconciliation.