Recipes
These are complete flows for the most common movements. Each recipe is a real
request to {BASE_URL}/v1. Put in your sk_… key and your amounts.
Stablecoins are the backbone, so the headline recipes are orchestrations: any source to any destination, bridged by USDC. The single-leg recipes (collect-only, payout-only) are at the end.
The shape of every orchestration
SOURCE → USDC → DESTINATIONEach side is
fiat(a local currency) orcrypto(any asset/chain). You initiate, we return pay-in instructions, and once the pay-in settles we fire the payout automatically. PollGET /v1/orchestrate/{id}to follow it.
Every orchestration names the customer paying it. Create them once with
POST /v1/customersand pass the id ascustomer_id— the rails ask who is paying, in more detail than a name. See Customers.
🌍 Pay in local currency, deliver crypto
Naira in → Bitcoin out. A customer pays you in NGN; a supplier receives BTC.
curl {BASE_URL}/v1/orchestrate \
-H "x-api-key: sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_…",
"source": { "kind": "fiat", "amount": 500000, "country": "NG", "currency": "NGN", "customer_name": "Ada Obi" },
"destination": { "kind": "crypto", "asset_id": "btc-bitcoin", "address": "bc1qsupplieraddress" },
"reference": "po_5521"
}'
You get back a bank account for the customer to pay into. When the naira lands, we convert to USDC and send BTC to the supplier — one call.
₿ Accept crypto, pay out local currency
Bitcoin in → Kenyan shillings out (mobile money). Take BTC from a customer, settle to an M-PESA number.
curl {BASE_URL}/v1/orchestrate \
-H "x-api-key: sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_…",
"source": { "kind": "crypto", "amount": 0.01, "asset_id": "btc-bitcoin", "refund_to": "bc1qcustomersendingaddress" },
"destination": {
"kind": "fiat", "country": "KE", "currency": "KES", "method": "momo",
"recipient": { "account_name": "John Doe", "account_number": "+254712345678", "network": "MPESA" }
}
}'
The response gives a deposit address. It also gives a memo if the network
needs one. For a crypto source, always include refund_to. This is an address
your customer can receive at. If the pay-in does not complete, the funds go back
to it.
Ask them for it. Do not assume it is the address they send from — a payment made from an exchange leaves an address they do not control, and a refund sent there is gone.
💶 Crypto in → bank account in Europe
USDT (Tron) in → EUR bank out. Settle a stablecoin to a SEPA account.
curl {BASE_URL}/v1/orchestrate \
-H "x-api-key: sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_…",
"source": { "kind": "crypto", "amount": 250, "asset_id": "usdt-tron", "refund_to": "TRecipientSendingAddress" },
"destination": {
"kind": "fiat", "country": "DE", "currency": "EUR", "method": "bank",
"recipient": { "account_name": "Müller GmbH", "account_number": "DE89370400440532013000" }
}
}'
🔄 Swap one crypto for another
Any asset → any asset. Move value between chains/assets, settled through the stablecoin hub.
curl {BASE_URL}/v1/orchestrate \
-H "x-api-key: sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cus_…",
"source": { "kind": "crypto", "amount": 1, "asset_id": "eth-ethereum", "refund_to": "0xCustomerSendingAddress" },
"destination": { "kind": "crypto", "asset_id": "sol-solana", "address": "RecipientSolanaAddress" }
}'
💱 Price it first
Always optional, never required — get an indicative end-to-end quote before you commit. Rates settle when the pay-in lands.
curl {BASE_URL}/v1/orchestrate/quote \
-H "x-api-key: sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"source": { "kind": "fiat", "amount": 500000, "country": "NG", "currency": "NGN" },
"destination": { "kind": "crypto", "asset_id": "btc-bitcoin" }
}'
{
"pay_in": { "amount": 500000, "unit": "NGN", "country": "NG" },
"usdc": 302.50,
"pay_out": { "amount": 0.0035, "unit": "btc-bitcoin" },
"fees": { "in_fee": 1.2, "out_fee": 0.9, "total_fee": 2.1, "currency": "USD" }
}
Discover which assets are available on either side with
GET /v1/orchestrate/assets.
Single-leg flows
When both sides are the same kind, the focused endpoints are simpler.
Get paid for local sales
Accept NGN. We add the equal amount in USD to your balance.
curl {BASE_URL}/v1/collections \
-H "x-api-key: sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "amount": 50000, "country": "NG", "customer_name": "Ada Obi", "reference": "invoice_1" }'
Pay out from your balance
Fund from your USD balance; the recipient receives local currency.
curl {BASE_URL}/v1/payouts \
-H "x-api-key: sk_test_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"rail": "bank", "country": "NG", "currency": "NGN", "amount": 100,
"recipient": { "account_name": "Ada Obi", "account_number": "0123456789", "bank_code": "058" }
}'
See the Collections and Payouts references for every field.
Put the checkout inside your own page
A session gives you two URLs. url is a page we host — send the payer there.
embed_url is the same checkout without our header, meant to be framed, for
when you would rather your customer never left your site.
<iframe id="figo" src="EMBED_URL" style="width:100%;border:0"></iframe>
<script>
const frame = document.getElementById("figo");
window.addEventListener("message", (event) => {
if (event.data?.source !== "figo-checkout") return;
switch (event.data.type) {
case "checkout.resize":
// The height changes with the country, the rail, and how much you
// asked the payer for. Follow it rather than guessing.
frame.style.height = event.data.height + "px";
break;
case "checkout.completed":
showThankYou();
break;
case "checkout.failed":
showRetry();
break;
case "checkout.done":
// The payer pressed Done. Your page decides what happens next.
closeCheckout();
break;
}
});
</script>
Every message carries session, so a page holding more than one checkout can
tell them apart.
Treat these as a signal to update your interface, not as proof of payment — a
browser can be made to send anything. checkout.session.completed, delivered
to your server and signed, is the one to bill on.