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"
}
| Field | Description |
|---|---|
type | One of the event types below. |
transactionId | Present on transaction.completed and transaction.failed. It is the same id returned by the partner transactions API. |
merchantReference | Reserved. Not populated in this release. |
timestamp | ISO 8601 time the widget emitted the event. |
type | Sent when |
|---|---|
ready | The session was accepted and branding applied. Show the widget and hide your own loading indicator. |
transaction.completed | A purchase succeeded and the receipt is showing. |
transaction.failed | A purchase failed (for example insufficient funds), and the failure screen is showing. |
close | The 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:
| Situation | Result |
|---|---|
| Android or iOS bridge present | The widget relies on your app to dismiss the web-view. |
| iframe with a trusted target origin | The widget relies on your page to remove the frame. |
No bridge, and the session came from a partner-initiated launch with a valid return_url | The widget navigates the browser to your return_url. |
No bridge, and no return_url | The widget returns to its start screen, so the customer is never stranded. |
Notes:
return_urlapplies to partner-initiated launches only. It must behttpson an allowed host, or it is dropped at launch.- A session created through
POST /partner/v1/sessionsignoresreturnUrlin this release. - Add your own
return_urlquery 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 (
adjustResizeon Android). - Do not intercept or rewrite navigation to the widget origin.
Last updated: September 2026