Skip to main content
Instead of redirecting users to an external browser, load the WalletConnect Pay checkout portal inside a native WebView. Supply two query parameters on the gatewayUrl, handle JavaScript bridge messages for the outcome, and intercept wallet deeplinks so the OS can route the user to their wallet app and back. The hosted UI handles wallet selection, payment option display, compliance data collection, and signing orchestration. Your app only needs to render a WebView, respond to the result, and verify it server-side.

How It Works

Prerequisites

  • A gatewayUrl from the Merchant API (POST /v1/merchant/payment)
  • Your app registered to handle its own deep link scheme (so wallets can return after signing)
  • JavaScript and DOM storage enabled in the WebView

URL Construction

Start with the gatewayUrl the API returns and append the two WebView parameters. Never construct the base URL manually.

Bridge Messages

The checkout calls window.ReactNativeWebView.postMessage(json) with a JSON string payload.
The checkout may send either the type field or the success boolean (or both). Treat type === "PAY_SUCCESS" or success === true as a success signal; type === "PAY_FAILURE" or success === false as failure.
Always verify the final payment status server-side via GET /v1/payments/{paymentId}/status after receiving PAY_SUCCESS. Never rely solely on the bridge message to confirm a payment.
The checkout opens the user’s wallet by navigating to a URL that carries a ?uri=wc:… query parameter. WebViews don’t handle these natively, so your app must intercept these navigations and forward them to the OS. This applies to both same-frame navigations and window.open() calls. Only forward URLs that carry a valid wc: URI — block any other non-https: navigation to prevent the page from driving Linking.openURL to arbitrary native schemes (tel:, sms:, intent:, etc.).

Platform Examples

Install the WebView package:
setSupportMultipleWindows must be true for onOpenWindow to receive window.open() calls. Without it, wallet deeplinks opened via window.open() are silently dropped.
Register your returnUrl scheme so the OS routes users back after signing in their wallet.

Verifying Payment Status

After PAY_SUCCESS, confirm server-side before marking the order as paid:
See the Payments Status API for the full response schema.

Best Practices

  • Enable JavaScript and DOM storage — required; the WebView will not render correctly without them.
  • Always intercept wallet deeplinks — URLs with ?uri=wc:… must be forwarded to the OS. Handle both same-frame navigations and window.open() calls.
  • Only intercept wc: deeplinks — block other non-https: navigations to prevent arbitrary native app launches.
  • Handle both message formats — check type === "PAY_SUCCESS" and success === true for forward compatibility.
  • Always verify server-side — treat bridge messages as a trigger to check status, not as proof of payment.
  • Keep the WebView full-screen or modal — the checkout is optimized for full viewport rendering.

Reference Example

PayWebView — React Native example

Full implementation including success animation, wallet deeplink handling, and error recovery.