Skip to main content
Embed the Onramp widget inline in an existing web app using the App Kit SDK. A signed-in user can open your page, complete an onramp inside an iframe, and your page receives a settled deposit event. The Onramp widget integration is framework-agnostic. The server handler uses the Fetch Request / Response standard, and the browser widget only needs a mounted DOM container. The route example uses Next.js App Router wiring, but the same handler works in Fetch-compatible backends such as Hono, Cloudflare Workers, Bun, Deno, and modern Node. For Express or Fastify hosts, see Customize session minting.
Try the live demo at https://onramp-demo.arc.io/ before integrating.

Prerequisites

Before you begin, ensure that you’ve:

Step 1. Set your environment variables

Add your API key to your server environment. Never inline it in client code or commit it to source control.
.env

Step 2. Expose a session route on your server

Create a route that exchanges your API key for a short-lived session token. The App Kit SDK ships createSessionRouteHandler as a drop-in Request → Response handler. The following example uses the Next.js App Router:
app/api/onramp/sessions/route.ts
The handler accepts POST requests, validates the body, calls server.onramp.createSession(), and returns the session as JSON. It maps thrown errors to the appropriate HTTP status codes and sets Cache-Control: no-store so session tokens are never cached.
This route doesn’t perform authentication. Before deploying, add an authorize callback that checks the user’s session. See Customize session minting.

Step 3. Add a container element to your page

The Onramp widget renders inside an <iframe> that fills its container. The container must already be attached to the DOM and must have an explicit, non-zero height, or the iframe collapses to 0px. The snippet shows only the container markup. Step 4 extends this file with the full mounting logic.

Step 4. Mint a session and mount the widget

In your browser code, mint the session by sending a POST request to the route you created in step 2, then mount the widget into the container element.
onramp.ts
Replace USER_WALLET_ADDRESS with the signed-in user’s Arc wallet address before running the flow. Keep the widget controller returned by mountIframe. Call widget.close() when the user leaves this view, closes the modal, or starts a new widget session. In a framework, call stopOnramp() from that framework’s cleanup lifecycle.

Step 5. Allow the widget origin in your Content Security Policy (CSP)

If your site sends a CSP header, the iframe fails to load silently unless you allow the widget and API origins:
See Hosting requirements for the complete list of host-side constraints.

Step 6. Set up a webhook receiver

Browser events such as DEPOSIT_SETTLED are best-effort UX signals only. If a user closes the tab between submitting a deposit and settlement, the browser never receives the settlement event even though the deposit succeeds. Reconcile final deposit state from webhook events delivered to your backend.