Skip to main content

Host Bridge And Return Behaviour

The widget can tell your app what is happening, and it needs to know how to leave when the customer is done. Both are optional: the widget is fully usable when no bridge exists.

Events​

The widget sends four events. Each is a JSON object:

{
"type": "transaction.completed",
"transactionId": "c2a9d3f0-5b7e-4c1a-8e21-0d6f4a9b7c33",
"timestamp": "2026-09-30T10:04:12.345Z"
}
FieldDescription
typeOne of the event types below.
transactionIdPresent on transaction.completed and transaction.failed. It is the same id returned by the partner transactions API.
merchantReferenceReserved. Not populated in this release.
timestampISO 8601 time the widget emitted the event.
typeSent when
readyThe session was accepted and branding applied. Show the widget and hide your own loading indicator.
transaction.completedA purchase succeeded and the receipt is showing.
transaction.failedA purchase failed (for example insufficient funds), and the failure screen is showing.
closeThe customer chose Close. Dismiss the widget.

Treat events as notifications. The transaction record held by Pagamio is the source of truth: confirm outcomes with the transactions API before crediting or fulfilling anything on your side.

A purchase still pending after about 30 seconds shows "still processing" and emits no transaction event until the customer looks again. Reconcile such purchases through the transactions API.

Transports​

The widget picks the first transport it finds, in this order.

1. Android web-view​

Register a JavaScript interface named PagamioHost. The widget calls PagamioHost.postMessage(json) with the event as a JSON string.

webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.addJavascriptInterface(object {
@JavascriptInterface
fun postMessage(json: String) {
val event = JSONObject(json)
when (event.getString("type")) {
"close" -> finish()
"transaction.completed" -> refreshBalance()
}
}
}, "PagamioHost")

2. iOS WKWebView​

Add a script message handler named pagamioHost. The widget posts the event object (not a string).

final class Bridge: NSObject, WKScriptMessageHandler {
func userContentController(_ c: WKUserContentController, didReceive message: WKScriptMessage) {
guard let event = message.body as? [String: Any], let type = event["type"] as? String else { return }
if type == "close" { dismissWidget() }
}
}
webView.configuration.userContentController.add(Bridge(), name: "pagamioHost")

3. iframe (window.parent.postMessage)​

When the widget is framed, it posts the event object to the parent window.

window.addEventListener("message", (e) => {
if (e.origin !== "https://vas-widget-sandbox.pagamio.tech") return; // the widget origin
const event = e.data;
if (event.type === "close") closeModal();
});

Target origin. The widget never posts with *. It picks the target origin from your allowed origins: the referrer's origin if it is on the list, otherwise your only allowed origin if there is exactly one. With several allowed origins and no matching referrer, no event is sent. Verify event.origin on your side too.

Closing And Returning​

When the customer taps Close, the widget sends a close event. What happens next depends on whether a host can act on it:

SituationResult
Android or iOS bridge presentThe widget relies on your app to dismiss the web-view.
iframe with a trusted target originThe widget relies on your page to remove the frame.
No bridge, and the session came from a partner-initiated launch with a valid return_urlThe widget navigates the browser to your return_url.
No bridge, and no return_urlThe widget returns to its start screen, so the customer is never stranded.

Notes:

  • return_url applies to partner-initiated launches only. It must be https on an allowed host, or it is dropped at launch.
  • A session created through POST /partner/v1/sessions ignores returnUrl in this release.
  • Add your own return_url query parameters (for example a status hint) only if your page treats them as untrusted input.

Web-View Checklist​

  • JavaScript and DOM storage enabled.
  • Handle the Android hardware back button in your app; the widget has its own back navigation.
  • Allow the soft keyboard to resize the viewport (adjustResize on Android).
  • Do not intercept or rewrite navigation to the widget origin.

Last updated: September 2026