Mobile app integration
July 30, 2026
Integrate FlowAlp Pay in iOS and Android apps: create the Gateway server-side, open it in a WebView, handle events and return via deep links.
Native and hybrid apps use the same hosted FlowAlp Pay checkout as the web. The pattern rests on two building blocks: your backend creates the payment and the app displays the payment link in a WebView or in-app browser, while deep links carry the customer back into the app afterwards.
Recommended flow
- Your backend creates a Gateway with amount, currency,
referenceIdand redirect URLs — the API secret never ships inside the app. - The app opens the returned payment link in a WebView or, preferably for wallets and 3-D Secure, in the system browser component (
SFSafariViewControlleron iOS, Custom Tabs on Android). - The customer completes the payment on the hosted page.
- The success, failed or cancel redirect brings the customer back — point these URLs at deep links your app owns.
- The app asks your backend for the order state; the backend has confirmed it through a webhook or an API retrieve.
Create the Gateway with deep-link return URLs
curl --request POST \
--url "https://api.pay.flowalp.com/v1.16/Gateway/" \
--header "Content-Type: application/json" \
--header "x-api-key: ${FLOWALP_API_SECRET}" \
--data '{
"instance": "tenantname",
"amount": 8925,
"currency": "CHF",
"referenceId": "ORDER-975382",
"successRedirectUrl": "https://app.example.com/pay/success",
"failedRedirectUrl": "https://app.example.com/pay/failed",
"cancelRedirectUrl": "https://app.example.com/pay/cancel"
}'Prefer Universal Links (iOS) and App Links (Android) over custom URL schemes: the operating system validates them against your domain and they gracefully fall back to the browser if the app is missing. Treat all three return URLs as pure navigation — reaching the success URL is not proof of payment.
Listen to payment events in a WebView
When the payment page runs inside a WebView-hosted page, it reports progress through postMessage, exactly as described in the iFrame guide. Send the origin handshake once the page has loaded, then watch for the transaction event.
window.addEventListener('message', function (event) {
if (typeof event.data !== 'string') return;
var data = null;
try { data = JSON.parse(event.data); } catch (ignore) { return; }
if (!data || typeof data !== 'object') return;
// Events arrive wrapped under a single vendor namespace key
Object.keys(data).forEach(function (key) {
var events = data[key] || {};
if (events.transaction && typeof events.transaction === 'object') {
if (events.transaction.status === 'confirmed') {
// UI signal only - your backend must confirm via webhook or API
} else {
// Show a failure or retry state
}
}
});
});In React-Native-style WebViews, inject a small listener that forwards window messages to the app shell and process them in the app's message handler. Mind the platform difference for the origin handshake: inject it before the content loads on Android, and post it after loading has finished on iOS.
App-switch methods: TWINT and wallets
Some payment methods leave your app during payment: TWINT hands over to its own app on the same device, and Apple Pay or Google Pay open operating-system sheets. Make sure the browser component you use allows launching external apps and returns cleanly to the checkout. Which methods appear depends on your account configuration — see payment methods.
Confirm server-side before fulfilling
Deep-link returns, WebView events and success screens can be forged or lost. Fulfil an order only after your backend has received the webhook — with signature verification — or has retrieved the transaction through the API. Treat cancel and timeout as separate states, not as failures of the same kind.
Test on real devices
- Run success, failure, cancel and abandoned-checkout scenarios on physical iOS and Android devices.
- Verify the deep-link round trip from every payment method you offer, including app-switch methods.
- Use TEST mode and test cards before charging real money.
Next step: work through the testing guide and the go-live checklist before you release the app.