Embed Widget

Embed the widget directly into your platform

Embed the Unigox buy/sell flow into your site with a single <script> tag. The loader creates a cross-origin <iframe> pointing at https://unigox.com/embed, wires up the required browser permissions, and exposes callbacks for trade and auth events.

Live playground: widgets.unigox.apparrow-up-right

Use it to try every option below in your browser and copy the generated snippet straight into your page.


Quickstart

<div id="unigox-widget"></div>
<script src="https://unigox.com/widget.js"></script>
<script>
  const widget = UnigoxWidget.init({
    container: "#unigox-widget",
    crypto: "USDT",
    fiat: "USD",
    amount: 100,
    onTradeCompleted: function (e) {
      console.log("trade", e.tradeId);
    },
  });
</script>

That's it. The loader injects the iframe with the right sandbox and allow attributes — you do not need to construct the iframe yourself.

No registration, partner agreement or API key is required to embed the widget. All options below are optional unless marked otherwise.

Need a starting point for your stack? Copy one of the examplesarrow-up-right folders — vanilla HTML, React, or WordPress — and tweak from there. Each example mirrors this guide and stays in sync with releases.


Earn referrals from your traffic

If you have a Unigox account and want every signup that goes through the widget on your site to count as your referral, just pass your Unigox username as ref:

That's the entire integration. Anyone who signs up while the widget is loaded on your page is attributed to your account — same mechanism as the unigox.com/?ref=… link, but built into the widget so you can earn off the buy flow directly on your site.


Init options

Pass these to UnigoxWidget.init(options).

Option
Type
Required
Default
Description

container

string | HTMLElement

yes

CSS selector or DOM element. The iframe is appended to it.

partner

string

no

Free-form attribution identifier — any string you want to see in your reports. Not validated. Optional.

ref

string

no

Your Unigox username. New signups initiated inside the widget are credited to this user (referral). Use this for no-integration deployments — paste your username and earn referrals from anyone who signs up via the widget on your site.

type

"buy" | "sell" | "buy-sell" | "buy-with-sendout"

no

"buy-sell"

Which side opens first. "buy-sell" shows the full buy/sell toggle. "buy-with-sendout" adds an automatic sendout step — see below. "both" is still accepted as an alias for "buy-sell" for back-compat.

sendoutAddress

string

conditional

Required when type=buy-with-sendout. Destination address the purchased crypto is sent to after the trade (EVM 0x… or Solana base58).

sendoutNetwork

string

conditional

Required when type=buy-with-sendout. Destination network as a blockchain ticker or name. Accepted values: "ethereum" / "eth", "optimism" / "op", "polygon" / "pol", "unichain" / "uni", "base", "arbitrum" / "arb", "avalanche" / "avax", "hyperevm" / "hype", "solana" / "sol". Numeric chain ids are not accepted.

crypto

string

no

auto

Pre-selected crypto ticker ("USDT", "USDC" are available). Falls back to USDT or the user's balance.

fiat

string

no

auto

Pre-selected fiat code (e.g. "USD", "EUR", "VND"). Falls back to the user's country currency.

amount

number

no

Pre-filled amount. For type=buy this is the fiat side ("You spend"); for type=sell it is the crypto side.

email

string

no

Prefills the login email. Combined with requireLogin it drives the auto-login flow.

theme

"light" | "dark"

no

"light"

Visual theme.

language

"en" | "es"

no

"en"

UI language. Unsupported values fall back to "en". More locales arrive as they are translated.

loginMethods

"email" | "web3" | "ton" | "all" or multiple options

no

"all"

Which login options to show. Pass a single value, "all" for all three, or multiple options separated by commas: "email,web3", "email,ton", "web3,ton".

requireLogin

boolean

no

false

If true, force the login screen before the widget opens even when anonymous trading would otherwise be possible.

applyAttribution

boolean

no

true

Toggles the "Powered by Unigox" footer inside the widget.

width

string

no

"100%"

Iframe width (any CSS length).

height

string

no

"700px"

Iframe height. When omitted, the widget auto-resizes to fit its content.

Callbacks

All callbacks are informational, not authoritative. They are fired from the iframe via window.postMessage — anything running in the top-level page can spoof or replay them. Use callbacks for UX (loading state, redirect after success, fire your own analytics) and for non-financial logging. Do not use them as proof-of-state for business decisions like releasing a product, crediting an account, or paying out funds. For those, verify via the Unigox API (server-to-server) or, when applicable, via independent on-chain confirmation.

Server-signed webhooks are on the roadmap and will be the authoritative channel; until they ship, treat every event below as a hint, not a fact.

Callback
Payload
Fires when
Verifiable?

onReady

The widget finished its initial render.

UX-only

onAuthChange

{ isAuthenticated }

The user signs in or signs out.

UX-only

onTradeStarted

{ tradeId, tradeType }

The user confirmed a trade.

Verify via API

onTradeCompleted

{ tradeId }

A trade reached a terminal success.

Verify via API

onSendoutStarted

{ tradeId, address, chainId }

(buy-with-sendout only) The bridge to the partner address was submitted.

Verify via API

onSendoutCompleted

{ tradeId, address, chainId, txHash? }

(buy-with-sendout only) The bridge confirmed on the destination chain.

txHash independently verifiable on-chain

onSendoutFailed

{ tradeId, code, message }

(buy-with-sendout only) The sendout step failed. code is one of the SENDOUT_* codes — see Error codes.

UX-only

onWidgetError

{ code, message }

A misconfig error fired before any trade existed (e.g. missing/invalid sendoutAddress). code is one of the WIDGET_* codes.

UX-only

Handle methods

init returns a handle for live control:

configure accepts the same shape as the init URL params (type, crypto, fiat, amount, vendor).


Host-page headers

Skip this section if your site does not set a Content-Security-Policy or a Permissions-Policy header. The widget works out of the box on the default browser permissions — these rules only matter if you have already tightened them.

One-block paste (strict-CSP sites)

If your site ships both a strict CSP and a Permissions-Policy, drop these two response headers on every page that loads the widget:

Merge them into your existing directives — do not replace what you already have. Each line below explains what it unlocks and what breaks without it.

Content-Security-Policy

Directive
Why it matters

script-src https://unigox.com

Allows widget.js to execute. Without it the loader silently fails with a CSP-violation error in the console — no iframe is created.

frame-src https://unigox.com

Allows the iframe at unigox.com/embed to load. Without it the iframe stays blank. (child-src on the legacy directive.)

Anything else (connect-src, style-src, img-src) does not need a Unigox entry: all those requests originate inside the iframe, which has its own document and is not constrained by the host page's CSP.

Permissions-Policy

The widget asks for several powerful browser features via the iframe's allow attribute (set automatically by widget.js). If your top-level page also sets a Permissions-Policy, the host's policy wins — you must delegate those features to unigox.com for the allow attribute to take effect:

Feature
What breaks without it

storage-access

Ambient session reuse — users have to log in on every visit instead of reusing their unigox.com session.

publickey-credentials-get/create

Passkey (WebAuthn) sign-in stops working.


Buy with sendout

type="buy-with-sendout" turns the widget into a one-shot fiat → crypto → partner-address flow. The user buys crypto normally, and the widget then automatically opens a sendout step that bridges the funds to a partner-configured external address over our existing bridge relay.

Behaviour

  • The buy/sell toggle is hidden — only BUY is available in this mode.

  • A persistent banner shows the sendout destination on every pre-sendout screen (Sendout to 0xAb…cd on Ethereum).

  • After the trade reaches terminal success and the purchased crypto lands in the user's internal Unigox wallet, the widget auto-navigates to the sendout view (~1.5 s after completion).

  • The sendout view shows a locked amount (matching the trade result), the destination, an expandable quote breakdown, and — if the account has it enabled — inline 2FA fields. The user confirms with a single click.

  • Bridge progress, fees and final tx hash are shown inline. The host is notified via onSendoutStarted / onSendoutCompleted / onSendoutFailed.

Requirements & constraints

  • sendoutAddress must match the chosen network's address format. EVM networks require a 0x… address that passes EIP-55 checksum validation when mixed-case; Solana requires a base58 address. Malformed addresses render a "Widget misconfigured" screen before any trade is created, so the user cannot proceed.

  • sendoutNetwork must be a ticker the widget recognises (ethereum / eth, optimism / op, polygon / pol, unichain / uni, base, arbitrum / arb, avalanche / avax, hyperevm / hype, solana / sol) and the resulting chain must be supported by the Unigox bridge for the chosen crypto. Unsupported combinations render a "Sendout misconfigured" screen inside the widget. Unknown tickers render a "Missing required sendoutNetwork parameter." configuration error.

  • Today the bridge supports USDC and USDT as source assets. If you plan to use other tickers, contact support first.

  • The crypto selector inside the widget is not filtered — the user can still pick any listed token; misconfigurations surface at the sendout step rather than at selection time.


Error codes

Error events carry a stable code field — branch on code for business logic, treat message as a human-readable hint that may be reworded between releases. Codes never change shape or meaning within the v1 loader.

WIDGET_*onWidgetError({ code, message })

These fire before any trade exists. Recovery is always a configuration fix on the partner side; the user cannot continue. The widget also displays a "Widget misconfigured" screen so end-users see something coherent.

Code
When
Recovery

WIDGET_MISSING_SENDOUT_ADDRESS

type=buy-with-sendout was used without sendoutAddress.

Re-init with a non-empty sendoutAddress.

WIDGET_MISSING_SENDOUT_NETWORK

type=buy-with-sendout was used without sendoutNetwork, or the ticker is unknown.

Re-init with a recognised ticker (see sendoutNetwork).

WIDGET_INVALID_SENDOUT_ADDRESS

sendoutAddress does not match the chosen network's format (bad EIP-55 checksum on EVM, or non-base58 on Solana).

Re-init with an address valid for the chosen sendoutNetwork.

SENDOUT_*onSendoutFailed({ tradeId, code, message })

These fire after a trade exists. The user can usually retry from inside the widget; the partner is informed so it can react in its own UI / analytics.

Code
When
Funds moved?
Retryable

SENDOUT_NOT_SUPPORTED

The combination of the user's chosen crypto and sendoutNetwork is not on the bridge. The widget shows a "Sendout misconfigured" screen.

No

No — partner-side fix only (different sendoutNetwork or restrict crypto).

SENDOUT_QUOTE_FAILED

The bridge quote API rejected the request (no liquidity, network down, etc.).

No

Yes — user retries from inside the widget.

SENDOUT_BRIDGE_FAILED

Source-chain transaction submitted but destination did not confirm, or the relay errored mid-flight.

Maybe — funds may be in flight.

Yes inside the widget; if it keeps failing, recovery via unigox.com/walletarrow-up-right and contact support.

SENDOUT_UNKNOWN

Unclassified upstream failure. Treat as SENDOUT_BRIDGE_FAILED for retry purposes.

Maybe

Yes — same recovery path.

Branching example


Versioning & compatibility

The loader at https://unigox.com/widget.js auto-updates — every page load fetches the latest. We commit to the following stability rules within the v1 loader:

  • Init options. No existing option is ever removed or renamed. Accepted types and the required-vs-optional split do not change. New optional options may be added; partners should ignore options they do not recognise.

  • Callbacks. Existing payload fields are not renamed or removed. New optional fields may be added; partners should ignore unknown fields and not rely on absence.

  • postMessage protocol. Existing type values and existing payload fields are stable. New types and new optional payload fields may appear.

  • Direct /embed URL params. Same rules as init options.

The widget UI (visual design, copy, internal step ordering, error wording) is not covered by these rules — it changes continuously. Build your integration on the contract above, not on screen flow or DOM structure.

Breaking changes

When a breaking change is unavoidable we ship it as a new loader URL — https://unigox.com/widget.v2.js — and keep the previous URL serving the previous major for at least 90 days. During that window both URLs work and partners migrate by changing the <script src> and reading the migration notes in CHANGELOG.mdarrow-up-right.

We never publish breaking changes by silently flipping widget.js.

Tracking changes

All partner-visible changes are recorded in CHANGELOG.md. Watch the file on GitHub if you want a notification on every release.


Examples

Stack-specific copy/paste examples live in examplesarrow-up-right . Each folder is self-contained — no build step beyond what your stack already needs.

Stack
What it shows

vanilla-html/

One HTML file, one <div>, one <script>. The minimum integration.

react/

A reusable UnigoxWidget wrapper plus a sample page. SSR-safe.

wordpress/

Snippet for the WordPress "Custom HTML" block, plus notes on caching plugins, AMP and CSP.

The examples track the v1 loader, so they auto-pick up additive changes without edits. When the contract changes (v2), the examples folder is updated alongside.

Last updated