Skip to content

Fiat on/off-ramp API

Five providers, all under /api/defi. Blazpay charges nothing here; each provider's own spread applies and the UI compares them.

Product page: buy / sell.

Unified quote comparison

MethodPathController
POST/defi/on-off-ramp-quotesservices/buy.js → buyQuotes

Queries every integrated ramp in parallel and returns the resulting crypto amount from each. Per-provider failures are caught and logged rather than failing the whole comparison — the user sees fewer options, not an error.

Chain and country maps live in bz-backend/utils/onRampConst.js (onRampChain, onrampCountries).

OnRamp.money

The India rail — INR via UPI, IMPS and bank transfer, with no international card needed.

MethodPathPurpose
POST/defi/onramp/quotesQuote
GET/defi/onramp/save-cryptoAdmin — refresh the crypto catalogue into onRampCrypto
GET/defi/onramp/save-fiatAdmin — refresh fiat types
GET/defi/onramp/assignAssign a reference for webhook correlation
POST/defi/onramp/setWebhookRegister the webhook URL with OnRamp
POST/defi/onramp/webhookReceive status callbacks

SECRET_KEY_ONRAMP. Controller: onRampController.js.

Changelly (fiat)

MethodPathPurpose
POST/defi/changelly/quotesQuote
POST/defi/changelly/crypto-listCurrency list
POST/defi/changelly/webhook-urlRegister webhook
GET/defi/changelly/save-cryptoAdmin — refresh changellyCrypto
GET/defi/changelly/save-fiatAdmin — refresh changellyFiat
GET/defi/changelly/assignAssign a crypto reference
GET/defi/changelly/assign-fiatAssign a fiat reference

CHANGELLY_PRIVATE_KEY / PRIVATE_KEY_CHANGELLY for request signing. Controller: changellyFiat.js.

Changelly's instant crypto-to-crypto endpoints are separate (POST /defi/changelly, POST /defi/changelly/transaction) and documented under provider proxies.

AlchemyPay

MethodPathPurpose
POST/defi/alchemy/quotesQuote
POST/defi/alchemy/signSign a payload for AlchemyPay's checkout
GET/defi/alchemy/save-cryptoAdmin — refresh alchemyCrypto
GET/defi/alchemy/save-fiatAdmin — refresh alchemyFiat
GET/defi/alchemy/assignAssign a crypto reference
GET/defi/alchemy/assign-fiatAssign a fiat reference
GET/defi/alchemy/webhookStatus callback

SECRET_KEY_ALCHEMY. Controller: alchemyController.js.

Transak

MethodPathPurpose
GET/defi/transakCurrency list; also refreshes transacCrypto / transacFiat
GET/defi/transak/assignAssign a reference (transaction.controller.js → assignTokensTransac)

Controller: transak.js. The frontend also uses @transak/transak-sdk directly for the widget.

MoonPay

MethodPathPurpose
GET/defi/moonpayCurrency list

Controller: moonPay.js.

Patterns worth knowing

Reference assignment

Every provider needs a reference so its webhook can be correlated back to a Blazpay order. Hence the assign* endpoint pairs above. Without one, a completed purchase cannot be attributed.

Catalogue caching

Provider catalogues (which tokens on which chains, which fiat currencies) are cached in Mongo rather than queried live:

CollectionRefreshed by
alchemyCrypto, alchemyFiatGET /defi/alchemy/save-crypto, /save-fiat
changellyCrypto, changellyFiatGET /defi/changelly/save-crypto, /save-fiat
onRampCryptoGET /defi/onramp/save-crypto
transacCrypto, transacFiatGET /defi/transak

There is no refresh cron

A newly listed token on a provider does not appear in Blazpay until someone calls the corresponding save-* endpoint. "Provider X supports token Y but Blazpay does not offer it" is almost always a stale catalogue, not a missing integration.

These are GET requests that mutate

GET /defi/alchemy/save-crypto writes to the database. They are administrative endpoints with no auth. Do not infer safety from the verb — see conventions.

Order records

Orders are persisted in models/buySellOrders.js. The Blazpay-side record is created through POST /defi/order/create or POST /defi/order, and read with GET /defi/order/:walletAddress.

Currency coverage

20+ fiat currencies:

INR  USD  EUR  GBP  AED  TRY  MXN  VND  NGN  BRL
PEN  COP  CLP  PHP  IDR  KES  ZAR  THB  MYR  ARS

The emerging-market entries — VND, NGN, KES, IDR, PHP, COP, PEN, CLP — are the differentiated ones. Off-ramp coverage is narrower than on-ramp for several of these corridors.

In BlazAI

The BUY intent returns action buy_sell, rendered by swapAI/buy/BuyQuoteContainer. So a user can say "buy 10000 rupees of bitcoin" and get the same provider comparison inline. See intent catalogue.

Failure modes

SymptomCause
A provider missing from the comparisonIts quote call failed; errors are caught and logged per provider
A token the provider supports is not offeredStale catalogue — call the relevant save-crypto endpoint
A completed purchase not reflectedReference not assigned, or webhook not registered
KYC stuckProvider-side. Blazpay holds no identity documents and cannot resolve it
Off-ramp unavailable for a currencyThat provider does not support that direction for that corridor

Internal + developer documentation. Usage figures are point-in-time snapshots — re-verify before publishing them.