Skip to content
Ask the docs

Find answers across the QairoPay docs.

Type a question and we'll synthesize an answer from the docs with citations back to the source pages.

USDC settlement

QairoPay settles eligible flows in USD Coin (USDC) on the Aptos blockchain. For tenants, this means same-day USDC liquidity, on-chain payouts, and the float economics that drive the volume-tied platform-fee discount.

For your code, settlement is a webhook event you reconcile against. You don’t usually broadcast on-chain transactions directly — QairoPay does that under a typed OnRampAdapter contract.

The flow

flowchart TD
A[Cardholder spend USD] --> B[Sponsor bank<br/>authorize and capture]
B --> C[QairoPay accrues<br/>settlement payable USD]
C --> D{Daily netting cycle<br/>T+0}
D --> E[On-ramp via Bridge<br/>USD to USDC]
E --> F[USDC delivered to<br/>tenant treasury wallet<br/>on Aptos]
F --> G[settlement.completed<br/>webhook fires]
G --> H[Your reconciler<br/>records inflow]
D -. failure .-> X[settlement.failed<br/>manual review]
classDef bridge fill:#F4ECD8,stroke:#B88A2E,color:#7A5A1B;
classDef onchain fill:#E6F1EC,stroke:#1F7A5A,color:#115540;
classDef webhook fill:#E2E6EE,stroke:#2A3A5E,color:#0F172A;
class E bridge
class F onchain
class G,X webhook
USD-in → USDC-out, with the Bridge on-ramp boundary highlighted. Every step is observable via webhook or treasury report.

On-ramp partners

Per Constitution Principle XIV, all fiat-to-USDC conversion goes through a typed OnRampAdapter. The Phase 2 implementation is BridgeOnRampAdapter, which uses Bridge (by Stripe) under the hood.

The adapter is an internal contract — you don’t call Bridge directly. You ask QairoPay to settle, QairoPay routes through Bridge, USDC lands on Aptos. If we ever swap the adapter (e.g., to a second provider for redundancy), your code doesn’t change.

1. Configure your treasury

Before settlement can run, configure where USDC should land. You can use the QairoPay-managed treasury (default — we hold USDC under qualified custody, you withdraw via the API or dashboard) or bring your own Aptos wallet.

await qp.treasury.update({
mode: "self_custodied",
aptos_address: "0x4cba...",
reconciliation_email: "[email protected]",
});

Self-custody requires the wallet to be a QairoPay-allowlisted address — usually a multisig with signers identified in your KYB. Set this up via the dashboard once; the API just confirms it.

2. Inspect a settlement

const settlement = await qp.settlements.retrieve("set_01HZX");
{
"id": "set_01HZX",
"status": "completed",
"currency": "USD",
"amount_cents": 218043,
"usdc_amount": "2180.43",
"fee_cents": 2180,
"net_cents": 215863,
"on_ramp": {
"provider": "bridge",
"reference": "bridge_tx_abc123",
"rate": "0.99999500"
},
"on_chain": {
"network": "aptos",
"tx_hash": "0xa1b2...",
"block_height": 234820001
},
"lines": [
{ "type": "card_transaction", "txn_id": "txn_01HZX", "amount_cents": 12000 },
{ "type": "card_transaction", "txn_id": "txn_01HZY", "amount_cents": 206043 }
],
"completed_at": "2026-05-19T10:14:22Z"
}

Reconcile your books from the lines array — each line points back to the original transaction or top-up that contributed.

3. Listening for completion

The reliable way to know a settlement landed:

// In your webhook handler
if (event.type === "settlement.completed") {
const settlement = event.data.settlement;
await db.settlements.upsert(settlement);
await ledger.recordUSDCInflow({
amount: settlement.usdc_amount,
txHash: settlement.on_chain.tx_hash,
settlementId: settlement.id,
});
}

We also fire settlement.failed if the on-ramp leg fails (rare; usually a Bridge-side compliance hold). The settlement enters manual_review; our treasury ops team contacts you within one business day.

4. Paying out from USDC

To convert USDC back to fiat (off-ramp), create a payout:

const payout = await qp.payouts.create(
{
amount_cents: 1000000, // $10,000
destination: { bank_account_id: "ba_01HZX" },
speed: "next_business_day",
},
{ idempotencyKey: crypto.randomUUID() },
);

Off-ramps settle T+1 to U.S. bank accounts and T+2 internationally. payout.completed fires when the wire lands.

5. On-chain payouts

To pay another Aptos address directly (e.g., paying a vendor in USDC), use an on-chain payout:

await qp.payouts.create({
amount_usdc: "1500.00",
destination: { aptos_address: "0xbeef..." },
});

This is screened against sanctions and the Travel Rule before broadcast. Counterparties on the OFAC SDN list or other restricted lists are blocked at the application layer.

Treasury reporting

Daily reconciliation reports land in the dashboard and via email at the address on your treasury config. The API exposes the same data:

const report = await qp.treasury.reports.retrieve({ date: "2026-05-18" });

The report covers opening balance, settlements in, payouts out, fees, and closing balance — denominated in both USD and USDC.