Mobile applications (iOS / Android)
There is no ROKI mobile SDK. A mobile app integrates through the same hosted-checkout flow as the web, with three constraints that are specific to mobile and easy to get wrong.
18.1 The secret key never ships in the app
A mobile binary is decompilable: strings can be extracted from any APK or IPA, and obfuscation only
slows that down. A leaked sk_live_ lets anyone create payments as the merchant and read every
payment they have. The app must never call the ROKI API directly.
The correct topology adds one hop:
Mobile app --> Merchant backend --POST /payments--> ROKI
(holds the secret key)
<-- returns only { payment_id, checkout_url }
The app receives the checkout_url and nothing else. The backend keeps the key, receives the
webhook, and owns the order state.
18.2 Open the checkout in the system browser, not a WebView
Use SFSafariViewController on iOS and Chrome Custom Tabs on Android. Do not use a plain
WKWebView / WebView.
Four reasons this matters on a payment page:
- 3-D Secure challenges are rendered by the issuing bank, and many issuers block or misbehave in embedded WebViews.
- Password managers and autofill do not work in a bare WebView, which raises card-entry friction and abandonment.
- The customer cannot see the URL bar and padlock, so they cannot verify they are on a legitimate payment domain - a real trust problem when typing a card number.
- The system browser shares its cookie jar and its security posture, so the checkout behaves the way ROKI tested it.
18.3 Returning to the app: Universal Links / App Links only
Verified against the live API: success_url and cancel_url accept only http/https URLs.
Custom schemes are rejected:
| Value | Result |
|---|---|
https://yourapp.com/payment-done |
201, accepted |
myapp://payment/ok |
422 on success_url |
com.yourapp://checkout/done |
422 on success_url |
intent://payment#Intent;scheme=myapp;end |
422 on success_url |
So the return path must be an https URL that the app claims through Universal Links (iOS) or App Links (Android). The same URL should render a normal web page for customers who do not have the app installed.
18.4 Confirming the payment inside the app
The rule from 9.3 is even more important on mobile, because the return trip is fragile: the customer may switch apps, lose connectivity, or dismiss the browser sheet before the redirect fires.
The app must never treat the return as confirmation, and must never ask ROKI directly. Instead:
- The backend receives the
payment.approvedwebhook and updates the order. - The app polls its own backend (or receives a push notification from it) for the order status.
- If the browser sheet is dismissed without a redirect, the app still polls - the payment may well have succeeded.
18.5 What does not exist today
No mobile SDK, no native payment sheet, and no documented support for Apple Pay or Google Pay. The embedded card-fields SDK on the roadmap is browser-oriented; a mobile app that wants card entry inside its own UI has no supported path today and must use the hosted checkout.
