net::ERR_UNKNOWN_URL_SCHEME — are in
Checkout integration steps,
and the per-payment-method exceptions are in
Payment method integration notes.
Read those first. This page answers the questions that come up around them.
Is there a checklist I can run before I ship the WebView integration?
Yes — these are the capabilities a payment flow can depend on. Each one that your App blocks removes payment methods rather than degrading gracefully.Can I detect from the checkout whether I am inside a WebView? Does Waffo warn the customer?
The checkout does not attempt to detect App WebViews in general, and it does not show a “please open in a browser” prompt for them. There is one exception: when the checkout is opened inside a messaging app’s built-in browser where the payment flow is known not to work, it shows a blocking dialog that asks the customer to open the link elsewhere, displays the full link, and offers a copy button. The dialog cannot be dismissed, because continuing on that page would fail anyway. For your own App, detection belongs on your side: you control the WebView, so you already know. Use that knowledge when you create the order — see the question on hiding a method in the App environment below.Which domains do I have to allow in my WebView?
Allow the Waffo checkout domain, and do not use a domain allowlist as your control on the payment flow. The checkout URL is HTTPS on a Waffo domain, but the payment step afterwards navigates to the payment method’s own domain, and for wallet launches to a non-HTTP(S) scheme that the payment page decides at runtime. That downstream set is a property of each payment method and changes without any change on your side, so there is no list you can pin. An App that only permits a fixed set of hosts will pass integration testing and then fail on a method you did not test. The supported shape is the one in Steps → custom schemes: keep HTTP(S) navigation in the WebView, hand validated non-HTTP(S) navigation to the operating system.The customer left my WebView to pay in a wallet App. How does my App learn the result?
Through your server, not through the WebView. The order of reliability is fixed and does not change in an App context:
A practical App pattern: when your App returns to the foreground, ask your own
backend for the order state (which it knows from the notification, or by
inquiring) rather than reading anything out of the WebView. This is also the
pattern that survives the customer switching back to your App by hand instead of
following the redirect.
For the full reasoning on why a redirect is not a result, see
Payment results.
The customer switched straight back to my App without going through the redirect. What do I do with that order?
Nothing special — and specifically, do not treat it as a failure. From the platform’s point of view the order is in exactly the state the payment method left it in, and the redirect being skipped tells you nothing about that state.- Query the order, or wait for the notification. Both give the real state.
- Do not close, cancel or re-create the order because the customer did not come back. That is how duplicate payments happen.
- If the payment is still pending, the customer may well complete it later, in the wallet App, inside the order’s validity window.
The customer came back into the WebView. Does the checkout page refresh the result by itself?
Yes. While the checkout is on any pending state — waiting on a redirect, waiting on an instruction such as a QR code, or processing — it polls the order state on a backing-off interval and advances the page on its own when a result lands. Certain QR-code methods, where customers typically pay very quickly, are polled more aggressively right after the code is shown. The redirect page also carries an explicit re-check action. Pressing it queries the order immediately; if the payment still has not gone through, the page says so rather than pretending to be finished. So the customer does not have to reload anything, and your App should not force-reload the WebView on resume — that can restart a flow that was fine.Can the same payment redirect link be opened twice? Will it stop working if the customer taps pay again?
It depends on the payment method, and you cannot control it. Some payment methods issue a redirect URL that is single-use — once consumed, opening it again does not work. Others allow it to be reopened. The hosted checkout knows which case applies and reflects it: where reopening is allowed, the page keeps offering a Pay button so the customer can go back out to the wallet; where it is not, the page offers only the re-check action, so the customer is not sent to a URL that will fail. Two consequences:- On the hosted checkout you do not have to do anything — the page already handles both cases.
- On a merchant-built checkout, treat the redirect URL as single-use. This
property is deliberately not part of the merchant-facing
orderAction, so there is nothing for you to branch on. Present the redirect once, then fall back to querying the order.
The customer tapped pay in the WebView and nothing happened. What do I capture before contacting support?
Capture these five things at the moment of failure. Without them the report cannot be separated from a normal “customer changed their mind”.- The last navigation URL the WebView received, complete and unmodified — including its scheme and every query parameter
- Whether your WebView navigation callback fired at all for that URL
- Whether any installed App on the device can handle that scheme
- The order ID and the timestamp
- Whether the customer was in your App’s WebView, an external browser, or an in-app browser of another App
Why can I not reproduce the wallet App launch in sandbox?
Because the sandbox does not connect to real payment methods. The sandbox checkout is a simulator: you press a button to declare the outcome, and there is no real payment-method selection, no card entry and no wallet App handover. See Sandbox simulator. So the App-launch part of your integration — scheme interception, handing the URL to the operating system, coming back — has to be verified in production with a small real payment. What sandbox is good for is everything around it: order creation, notification handling, App resume logic, and your own order-state-on-resume flow. Plan a production smoke test per payment method that involves an App handover, and budget for the fact that it needs a real wallet account.Can I hide a payment method only in my App environment?
Not through a setting, and there is no “environment” parameter on the checkout. What you can do — and what the platform is designed around — is decide per order:- Your App knows it is your App. Have your server pass
payMethodTypeand, for a specific wallet,payMethodNameon/api/v1/order/createso the order only ever offers what works in that environment. - Send
userInfo.userTerminaltruthfully. Methods that do not support the terminal type you sent are not offered at all.
Should I just open the checkout in an external browser from the start?
It is a legitimate design, and for some payment methods it is the only one that works — the per-method notes list the cases where a method’s own flow cannot run inside a merchant App WebView. The trade-offs to weigh:
A middle path many integrations settle on: keep the WebView for the flows that
work in it, and open the external browser only for the orders whose payment
method requires it — which you know at create time, because you chose the method.
Note that
successRedirectUrl, failedRedirectUrl and cancelRedirectUrl
accept deeplinks as well as HTTPS URLs, so an external-browser flow can still
hand the customer back to your App.
Is there an SDK that wraps the App-side launch for me?
The Waffo front-end SDK covers the web surface — rendering card fields, and embedding the checkout in your page. The App-side pieces — intercepting a non-HTTP(S) navigation in your WebView and handing it to the operating system — are platform APIs in your own App, and there is no Waffo library that replaces them. The platform documentation links for both Android and iOS are in Steps → custom schemes.Can I send the checkout link to the customer directly, by SMS or email?
That is what a payment link is for, and it is a separate product surface with its own expiry and reuse rules — see Payment links. Do not repurpose a checkout URL from an API-created order as a link you send out: it belongs to one order, it expires with that order, and once the order reaches a final state the link shows the expired screen.Hitting a WebView failure you cannot place? Contact support with the five items from the capture list above.