← Overview

Transak

Developer-first ramp with the widest local rails.

What it is

Transak is a fiat-to-crypto on/off-ramp built around a white-label, embedded developer experience. Apps drop in a widget or SDK and Transak handles KYC, payment acceptance, fraud, fiat settlement, and the on-chain payout. Beyond plain buy/sell it offers Transak One (fund a smart-contract interaction with fiat in a single transaction) and Stream (send crypto to a personal deposit address and get auto fiat payout). It covers 100+ countries, 70+ fiat currencies, 130+ cryptocurrencies, and 75+ blockchains.

How it works

  1. A developer registers for an API key, then calls the Create Widget URL API server-side with widget params to mint a short-lived, single-use widgetUrl (sessionId).
  2. The @transak/ui-js-sdk renders that widgetUrl as a hosted/embedded iframe; the user completes KYC once and pays via a local rail.
  3. Pay-in rails: UPI (India), PIX (Brazil), SEPA Instant (EU), ACH + card (US), Faster Payments (UK), PayID (AU) — Transak sources crypto liquidity and pays out to the user's wallet.
  4. Off-ramp: the reverse via the widget, or via Stream — a one-time setup provisions a per-asset/per-network deposit address; any crypto sent there auto-pays fiat to the registered bank/card.
  5. Transak One: the partner passes a smart-contract address + calldata; Transak converts fiat to the source token and executes the contract call (mint, deposit, swap, stake) in one transaction, delivering receipt tokens to the user.
  6. Order state flows back to the partner via the SDK events, the Get Order(s) REST API, webhooks (JWT-encrypted), and WebSockets.

Differentiators

  • Widest local payment-method coverage of any ramp — deep emerging-market rails (UPI, PIX) plus EU/US/UK/AU instant rails.
  • White-label + server-side widget-URL model keeps the API key off the client and lets partners pre-configure the entire flow.
  • Transak One turns a ramp into a payments primitive: fiat straight into an arbitrary smart-contract call, not just a wallet balance.
  • Broad multi-jurisdiction licensing (US FinCEN MSB, UK FCA, EU VASP, Canada, Australia, India) underpins 100+ markets and 75+ chains across 450+ integrations.

Business model

Spread + fee on each on/off-ramp transaction (card typically ~3.5–5.5%, lower for bank/local rails by region) [verify exact tiers]; revenue share with partners on volume.

Depends on

  • Local payment rails (UPI, PIX, SEPA, ACH, Faster Payments, PayID)
  • Card networks & banking partners
  • Liquidity / market makers for crypto pricing + FX
  • Supported chains and stablecoin issuers (USDC, USDT, EURC, USDG)

Risks

  • Compliance overhead across 100+ countries with divergent VASP/MSB regimes (MiCA in the EU, MTLs in the US).
  • Card fraud + chargebacks on the on-ramp; FX/liquidity volatility in emerging-market corridors.
  • Fee pressure as ramps commoditize (e.g. Coinbase zero-fee USDC).
  • Reliance on a single-use, 5-minute widget URL adds a server round-trip that partners must wire up correctly.
Product breakdown

The product lines

On-Ramp

Buy crypto with local fiat rails.

An embeddable widget/SDK that lets a partner's users buy 130+ cryptocurrencies across 75+ chains with cards or local bank rails, after a one-time KYC. The differentiator is breadth of local pay-in methods.

  • User picks asset + amount; pays via UPI, PIX, SEPA Instant, ACH, Faster Payments, PayID, or card.
  • Transak sources crypto liquidity, charges a fee/spread, and pays out on-chain to the user's wallet.
  • Partner pre-configures asset/network/amount/wallet via widget params; KYC is reused across sessions.
Pay-in railsCard + UPI / PIX / SEPA Instant / ACH / Faster Payments / PayID
Assets130+ crypto, 75+ chains
Markets64+ on-ramp countries [verify], 70+ fiat

Off-Ramp

Sell crypto to fiat via the widget.

The reverse flow — users sell crypto and receive fiat to a bank account or card, handled in the same embedded widget with KYC and payout compliance built in.

  • User sends crypto to Transak; fiat is paid out to a registered bank/card.
  • SEPA Instant and fast-funds-eligible cards settle quickly; standard rails take longer.
  • Live in 40+ countries with 20+ networks supported. [verify]
Coverage40+ countries
Networks20+

Transak One

Fiat straight into a smart-contract call, in one transaction.

A single-transaction product where fiat is converted to a source token and used to execute an arbitrary smart-contract interaction — mint an NFT, deposit to Aave, stake, swap, borrow/lend — with receipt tokens delivered to the user's wallet. Removes the 'buy crypto, then do the thing' two-step.

  • Partner passes the target smartContractAddress + calldata for the contract function.
  • Transak converts fiat to the required source token, executes the call, and delivers any receipt tokens (e.g. LSTs) back to the user.
  • Gas + source token amounts are estimated via params like estimatedGasLimit and sourceTokenData. [verify param names]
Use casesNFT mint, deposit/stake/swap, lending
PatternFiat → token → contract call in one tx

Stream

Address-based automatic off-ramp.

A 'one-click crypto-to-fiat' off-ramp: after a one-time KYC + payout-details setup, the user gets a unique deposit address per crypto/network. Any crypto sent to that address triggers an automatic fiat payout — no widget needed per transaction.

  • One-time setup: KYC + register payout bank/card.
  • User is provisioned a persistent per-asset/per-network deposit address.
  • Crypto sent to the address auto-converts and pays out fiat (SEPA Instant / fast-funds cards near-instant).
ModelPer-asset deposit address → auto fiat payout
SetupOne-time KYC + payout details
Deep dive

Architecture & mechanics

Integration flow (server-minted widget URL)

Transak's current model splits work between backend and frontend so the API key never reaches the browser. The result is a slightly heavier integration than a pure publishable-key widget, but a more secure one.

  • Backend exchanges API key (+ secret) for an access token via refresh-access-token.
  • Backend calls Create Widget URL with widgetParams → receives a single-use widgetUrl (sessionId), valid ~5 minutes.
  • Frontend mounts the widgetUrl with @transak/ui-js-sdk into a containerId via new Transak(config).init().
  • Order tracking layered: client events (TRANSAK_ORDER_CREATED/SUCCESSFUL) for UX, plus webhooks / WebSockets / Get Order By ID for truth.

Local rails & coverage

Transak's edge is the breadth of local pay-in/pay-out methods — particularly in emerging markets where card rails are weak — layered on top of standard card and instant-bank rails in developed markets.

  • India: UPI; Brazil: PIX; EU: SEPA Instant; US: ACH + card; UK: Faster Payments; Australia: PayID.
  • On-ramp across 64+ countries / 115+ overall, 70+ fiat currencies, 130+ crypto, 75+ chains. [verify exact counts]
  • Off-ramp narrower: 40+ countries, 20+ networks, expanding.
  • Stablecoin breadth includes USDC, USDT, EURC (Circle) and USDG (Paxos) for MiCA-aligned EU flows.

Compliance & licensing

A multi-jurisdiction license stack is the real moat — it's what lets partners switch on a market by changing a config rather than acquiring their own licenses.

  • US: FinCEN-registered MSB; UK: FCA-registered; EU: VASP registration (migrating toward MiCA/CASP). [verify MiCA CASP status]
  • Canada: FINTRAC; Australia: AUSTRAC; India: FIU-IND.
  • KYC is collected once per user and reused across partner sessions; sanctions screening + fraud handled in-platform.
  • Webhook payloads are JWT-encrypted with the partner's access token so order data isn't exposed in transit.

Fees & risk

  • Card on-ramp fees typically ~3.5–5.5% by region; bank/local rails cheaper. [verify current tiers]
  • Revenue = fee + spread on each transaction, with partner revenue-share on volume.
  • Chargeback/fraud risk on card on-ramps; FX + liquidity risk in emerging-market corridors.
  • Fee-compression pressure from zero-fee USDC rivals (Coinbase Onramp) and aggregators routing for best quote.
Builder's track

How it's built

Architecture

Transak sits between local payment rails / card acquirers / banks and the chains. Unlike a pure publishable-key model, the current flow is server-assisted: the partner backend calls the Create Widget URL API (authenticated with the API key) to encapsulate all widget params into a single-use, 5-minute widgetUrl carrying a sessionId. The frontend SDK only ever sees that opaque URL, so the API key never touches the client. Transak runs KYC, payment acceptance, fraud, liquidity sourcing, and the on-chain payout (and the reverse for off-ramp). For Transak One, Transak additionally executes a partner-supplied smart-contract call after converting fiat to the source token. Order state is pushed back via SDK events, webhooks (JWT-encrypted with the partner's access token), WebSockets, and the Get Order(s) REST API.

Integration shape

Primary path: the @transak/ui-js-sdk (successor to the legacy @transak/transak-sdk) renders the widgetUrl as a hosted or embedded iframe; one Transak instance = one widget mounted to a containerId. Native iOS, Android, React Native, and Flutter SDKs exist, plus a REST/Whitelabel API for headless flows. apiKey and referrerDomain are mandatory; productsAvailed selects BUY/SELL; the rest of the flow (asset, network, fiat, amount, wallet, payment method, partnerOrderId, redirectURL, theme) is configured via widget params.

API surface

POST Create Widget URL
Server-side: pass widgetParams (apiKey, referrerDomain, productsAvailed, cryptoCurrencyCode, network, walletAddress, fiatCurrency, fiatAmount…) → returns a single-use widgetUrl + sessionId, valid 5 minutes.
POST refresh-access-token
Exchange the API key + secret for an access token used to sign widget URLs and decrypt webhook payloads; issuing a new token invalidates the prior one.
GET Get Orders / Get Order By ID
Poll order objects and current status (e.g. AWAITING_PAYMENT_FROM_USER → PROCESSING → COMPLETED / FAILED / EXPIRED).
Webhooks
Real-time order lifecycle callbacks to the partner backend; the data field is a JWT you decrypt with your access token — treat as source of truth.
WebSockets
Live order-status stream as an alternative to polling for in-session UI updates.
new Transak(config) + transak.init()
Client SDK: mount the widget from a widgetUrl into a containerId; configure widgetHeight/widgetWidth.
transak.on(Transak.EVENTS.*)
Subscribe to TRANSAK_ORDER_CREATED, TRANSAK_ORDER_SUCCESSFUL, and TRANSAK_WIDGET_CLOSE to advance your own UI.

Minimal integration

Two-step flow: mint a widgetUrl server-side, then render + listen for the order client-side.

// 1) SERVER: mint a single-use widgetUrl (keeps the API key off the client)
const res = await fetch('https://api.transak.com/api/v2/widget-url', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    apiKey: TRANSAK_API_KEY,            // secret — server-side only
    referrerDomain: 'rails.app',
    widgetParams: {
      productsAvailed: 'BUY',           // or 'SELL' for off-ramp
      cryptoCurrencyCode: 'USDC',
      network: 'base',
      fiatCurrency: 'EUR',
      fiatAmount: 50,
      walletAddress: '0xabc...def',
      partnerOrderId: 'order_123',
    },
  }),
});
const { widgetUrl } = await res.json(); // valid ~5 min, single use

// 2) CLIENT: render the widget and react to order events
import { Transak } from '@transak/ui-js-sdk';

const transak = new Transak({ widgetUrl, containerId: 'transak-mount' });
transak.init();

transak.on(Transak.EVENTS.TRANSAK_ORDER_SUCCESSFUL, (order) => {
  console.log('paid', order);          // confirm via webhook server-side too
  transak.close();
});
transak.on(Transak.EVENTS.TRANSAK_WIDGET_CLOSE, () => transak.cleanup());

Build notes

  • The legacy @transak/transak-sdk (apiKey + environment passed on the client) is deprecated — new integrations use @transak/ui-js-sdk with the server-minted widgetUrl. [verify the exact widget-url endpoint path/version against current docs]
  • widgetUrl/sessionId is single-use and expires in ~5 minutes; mint a fresh one per user flow rather than caching it.
  • Treat webhooks (JWT-decrypted with your access token) or Get Order By ID as the source of truth for settlement — the client TRANSAK_ORDER_SUCCESSFUL event only means payment was initiated.
  • Use the STAGING environment + staging API key first; switch to PRODUCTION by swapping credentials.
  • Transak One uses extra widget params (smartContractAddress, sourceTokenData, calldata, estimatedGasLimit, cryptoCurrencyData) to fund and execute a contract call in one transaction. [verify exact param names against docs]