Handle widget callbacks
Wire 0Gate browser callbacks for UX while keeping fulfillment, ledger updates, and support state on verified backend events.
Widget callbacks are browser events from the hosted 0Gate iframe to your page. Use them to update the screen, measure availability, and route the user. Do not use them to fulfill value.
Callbacks are UX hints
Browser callbacks can be missed, replayed, blocked, or seen before webhook delivery. Your backend should close attempts from signed events or trusted reconciliation reads.
Callback sequence
Callback matrix
| Callback | Meaning | Page action | Backend action |
|---|---|---|---|
onReady | Iframe mounted and can receive config. | Stop loading state. | Optional health/analytics event only. |
onSuccess | Hosted flow reached a success UX state. | Show processing and refresh your status endpoint. | Wait for signed event before fulfillment. |
onError | Hosted flow reported a recoverable or terminal error. | Show generic failure or retry UI. | Wait for event/reconciliation before closing final state. |
onClose | User dismissed or session closed in browser. | Offer retry, resume, or support. | Do not mark failed without trusted state. |
onUnavailable | Embed bootstrap says the partner/session is unavailable. | Show neutral unavailable UI. | Do not create uncontrolled retry loops. |
onMountError | React wrapper caught mount/bootstrap failure. | Fall back to redirect or show support. | Keep the existing attempt open unless trusted state says otherwise. |
Browser implementation
import { GateRamp } from '@0bit/gate/browser';
const ramp = new GateRamp({
publishableKey,
clientSecret,
environment: 'sandbox',
});
await ramp.mount('#gate-checkout', {
onReady: () => setView('ready'),
onSuccess: ({ sessionId }) => {
setView('processing');
refreshStatus({ gateSessionId: sessionId });
},
onError: ({ code }) => {
setLastSafeCode(code);
setView('recoverable_error');
},
onClose: ({ reason }) => {
setCloseReason(reason);
setView('retry_or_support');
},
onUnavailable: () => setView('unavailable'),
});React implementation
import { RampCheckout } from '@0bit/gate/react';
<RampCheckout
publishableKey={publishableKey}
clientSecret={clientSecret}
environment="sandbox"
onReady={() => setView('ready')}
onSuccess={() => setView('processing')}
onError={({ code }) => setSafeErrorCode(code)}
onClose={() => setView('retry')}
onUnavailable={() => setView('unavailable')}
onMountError={() => setView('redirect_fallback')}
/>;Status refresh pattern
After any terminal-looking browser callback, fetch your own status endpoint.
async function refreshStatus(attemptId: string) {
const status = await fetch(`/api/checkouts/${attemptId}/status`).then((res) => res.json());
if (status.view === 'success') showSuccess();
else if (status.view === 'failed') showFailure();
else if (status.view === 'expired') showExpired();
else if (status.view === 'cancelled') showCancelled();
else showProcessing();
}Safe event handling
| Rule | Reason |
|---|---|
Let the SDK own postMessage filtering. | The SDK checks iframe origin and message shape before firing callbacks. |
| Do not attach broad payment listeners globally. | Multiple widgets, browser extensions, or unrelated frames can emit messages. |
| Store only safe callback fields. | Codes and reasons are useful; raw payloads and secrets are not. |
| Keep fulfillment in backend workers. | Webhooks are retryable, signed, and dedupable. |
| Unmount on route or modal close. | Prevent stale listeners and duplicate browser states. |
Related pages
Embed the 0Gate widget
Mount the iframe and wire lifecycle handlers.
Configure return URLs and outcome pages
Render user-facing status from backend state.
Verify webhook signatures
Process the backend events that actually close attempts.
Handle failed or cancelled flows
Build recovery paths for callback failures and delayed events.