Cross-Border Fintech
Accept a USD card charge, settle to a BRL account, issue the fiscal document. One transaction, explicit FX surcharge, LGPD-ready audit trail.
Accept USD from a foreign buyer, settle to a BRL account in Brazil, and issue a Nota Fiscal de Servicos — the full cross-border flow. One charge = one settled transaction. The 0.5% cross-border FX surcharge applies to the converted amount on top of the base $0.10.
What the billing looks like
A $100 USD charge settled to BRL at R$5.00:
| Component | Amount |
|---|---|
| Base transaction fee | $0.10 |
| Cross-border FX (0.5% × R$500 converted) | R$2.50 (~$0.50) |
| Your total | ~$0.60 per settled charge |
Invoicing (NF-e / NFS-e) and audit trail are included.
See Billing for the full surcharge rules. Only the leg that crosses currencies attracts the 0.5% — domestic-only transactions stay at the flat $0.10.
Prerequisites
npm install @codespar/sdkAccounts required: EBANX (or Circle for USDC), Nuvem Fiscal for the NFS-e.
The flow
import { CodeSpar } from "@codespar/sdk";
const codespar = new CodeSpar({ apiKey: process.env.CODESPAR_API_KEY! });
interface CrossBorderCharge {
buyer_email: string;
card_token: string; // from a tokenization frontend
usd_amount: number; // cents, e.g. 10000 = $100.00
service_description: string;
service_code: string; // municipal NFS-e service code
customer_country: "US" | "MX" | "AR" | "CO";
}
async function collectCrossBorder(charge: CrossBorderCharge) {
const session = await codespar.create(charge.buyer_email, {
servers: ["ebanx", "nuvem-fiscal"],
metadata: { flow: "cross_border_v1", country: charge.customer_country },
});
try {
const result = await session.loop({
steps: [
// 1. Charge USD card via EBANX — settles to your BRL account at EBANX's spot rate
{
tool: "codespar_pay",
params: {
method: "card",
amount: charge.usd_amount,
currency: "USD",
settle_currency: "BRL",
card_token: charge.card_token,
customer_email: charge.buyer_email,
provider: "ebanx",
description: charge.service_description,
},
},
// 2. Issue NFS-e for the BRL amount the merchant received
{
tool: "codespar_invoice",
params: (prev) => ({
type: "nfse",
amount_brl: prev[0].data.settled_amount_brl,
fx_rate: prev[0].data.fx_rate,
service_code: charge.service_code,
customer: {
name: prev[0].data.customer.name,
tax_id_country: charge.customer_country,
},
reference_payment_id: prev[0].data.payment_id,
}),
},
],
abortOnError: true,
});
return {
charge_id: result.results[0].data.payment_id,
settled_brl: result.results[0].data.settled_amount_brl,
fx_rate: result.results[0].data.fx_rate,
nfse_access_key: result.results[1].data.access_key,
nfse_pdf: result.results[1].data.pdf_url,
};
} finally {
await session.close();
}
}Why step 2 passes fx_rate explicitly
The NFS-e is issued in BRL, but the revenue came from a USD charge. Tax authorities (SEFAZ, some municipal) require the original foreign amount + the exchange rate used for settlement on the invoice. CodeSpar surfaces both values in the codespar_pay result so you can forward them verbatim.
USDC alternative via Circle
For buyers who want to pay in stablecoin, swap EBANX for Circle:
{
tool: "codespar_pay",
params: {
method: "usdc",
amount: charge.usd_amount,
currency: "USD",
settle_currency: "BRL",
provider: "circle",
wallet_address: charge.payer_wallet,
},
}Same pricing model — one settled transaction + the 0.5% FX surcharge on the BRL leg.
Handling the 0.5% transparently
If you want to pass the FX cost to the buyer explicitly (not absorb it), inspect the settlement metadata before issuing the receipt:
const settlement = result.results[0].data;
const receiptAmountUsd = charge.usd_amount;
const receiptAmountBrl = settlement.settled_amount_brl;
const fxSurchargeBrl = settlement.fx_surcharge_bps
? (receiptAmountBrl * settlement.fx_surcharge_bps) / 10000
: 0;
// Your app shows: "Total: $100.00 USD · R$500.00 · FX fee R$2.50"Compliance notes
- LGPD: the buyer email + card metadata are stored in CodeSpar's audit ledger encrypted at rest (AES-256) and retained for 5 years (Brazilian SOX-equivalent requirements). You can export or delete on subject request via the dashboard.
- SPB: if the settlement destination is a Brazilian bank, CodeSpar routes through the EBANX SPB rails; no DOC/TED fee applies.
- Receipt language: for non-BR buyers, the NFS-e XML includes the translated service description if you pass
customer.language. The legal document stays in PT-BR.
Next steps
Last updated on