0Bit Documentation

Lock an on-ramp flow

Build a hosted 0Gate buy flow that locks the user into on-ramp without exposing headless rails or API-reference details.

Use an on-ramp flow when the customer wants to buy crypto with fiat inside the hosted 0Gate experience. Your server creates the intent, the session is locked to buy, and fulfillment still waits for a verified backend event.

Kit blocks are still the hosted 0Gate iframe

An on-ramp kit block is not a custom ramp UI builder. KYC, payment-method collection, quote confirmation, and compliance screens remain inside the 0Gate hosted experience.

Flow boundary

BoundaryOwned byWhat to lock
Buy intentYour appAccount, amount intent, target asset, wallet destination if you already collected it.
Session0GateFlow set to on-ramp, return URLs, reference ids, and any allowed constraints.
BrowserYour app + 0Gate iframeBrowser-safe session values and the on-ramp presentation only.
Settlement recordYour backendTerminal status from verified backend state.

Implementation shape

  1. Create a buy intent before you start 0Gate.
  2. Create a server-side 0Gate session with the flow locked to on-ramp.
  3. Store the 0Gate session id next to your buy intent.
  4. Mount the on-ramp kit block or the full hosted widget with the session-bound flow.
  5. Treat browser success as processing, then fulfill from signed backend state.
async function startOnRamp(input: OnRampIntent) {
  const intent = await buyIntents.create({
    accountId: input.accountId,
    fiatAmount: input.fiatAmount,
    fiatCurrency: input.fiatCurrency,
    targetAsset: input.targetAsset,
    walletAddress: input.walletAddress,
    status: 'pending_session',
  });

  const session = await gateSessions.createForAttempt({
    attemptId: intent.id,
    flow: 'on_ramp',
    userReference: intent.id,
    idempotencyKey: `on-ramp:${intent.id}`,
  });

  await buyIntents.attachGateSession(intent.id, session.id);
  return { intentId: intent.id, clientSecret: session.clientSecret };
}

State model

StateMeaningUser-facing copy
pending_sessionYour app has a buy intent but no 0Gate session id yet.Preparing checkout.
requires_actionThe hosted buy flow is ready.Continue in 0Gate.
processingThe customer finished the hosted flow, but your backend has not fulfilled yet.Confirming payment.
fulfilledA verified terminal event closed the ledger update.Crypto purchase complete.
failedThe hosted buy flow failed or could not complete.Payment failed. Try again or contact support.
expiredThe session timed out before completion.Session expired. Start again.
cancelledThe customer or backend cancelled the attempt.Checkout cancelled.

Browser behavior

Keep the browser path deliberately thin.

Browser eventRecommended actionReason
Mount readyEnable the checkout area and stop loading placeholders.The iframe can accept user input.
Success callbackSwitch to a processing view and read your own attempt status.Settlement is not proven client-side.
Close callbackShow retry, continue later, or support options.The attempt may still be open or processing.
Return URLRender a status page backed by your server.Query strings and redirects are not authoritative.

Webhook and reconciliation

The on-ramp terminal path is the same as the generic payment flow: verify the signature, dedupe by event id, and fulfill once. Reconciliation should read trusted server state only when webhook delivery is delayed, dead-lettered, or a support agent needs to resolve a stuck attempt.

async function applyOnRampEvent(event: GateSessionEvent) {
  const intent = await buyIntents.findByGateSession(event.data.id);
  if (!intent) return;

  if (event.type === 'gate_session.completed') {
    await fulfillBuyIntentOnce(intent.id, { sourceEventId: event.id });
  }

  if (event.type === 'gate_session.failed') {
    await buyIntents.markFailed(intent.id, { sourceEventId: event.id });
  }
}

Production checklist

  • Lock the flow on the server, not only in browser UI.
  • Store your intent id, 0Gate session id, and event ids.
  • Redact browser session values and webhook payloads from logs.
  • Keep support screens generic: do not expose provider, treasury, or compliance internals.
  • Test refreshes, double-clicks, closed iframes, delayed webhook delivery, and duplicate events.

On this page