Documentation
Chains and finality
Why finality, not block time, decides when a payment is truly done.
Every disbursement JuicePay makes ends up on a specific network. Choosing well is mostly about finality, and finality is not the same thing as speed.
Block time is not finality#
A network can include your transaction in a block within a second and still reorganise that block away ten seconds later. If you credit a customer on inclusion, you have lent them money against a promise.
Finality is the point at which reverting the transaction would cost more than it is worth. Some networks give you a probabilistic answer that improves over time; others give you an explicit signal from the consensus layer.
| Network | Typical inclusion | Practical finality | Notes |
|---|---|---|---|
| Base | ~2s | ~12s | L2 with fast soft confirmation, L1-anchored finality |
| Arbitrum | ~1s | ~13s | Same L2 caveat as Base |
| Solana | ~0.4s | ~13s | Optimistic confirmation, then hardened |
| Ethereum | ~12s | ~15 min | Treat as a settlement rail, not an interaction rail |
| Polygon | ~2s | ~30s | Checkpoint interval dominates |
| Tron | ~3s | ~1 min | Very cheap for high-volume small payments |
JuicePay tracks both the inclusion event and the finality event internally. The status you receive reflects the one your configuration cares about.
What "settled" means here#
By default a resource becomes succeeded at finality, not at inclusion. You can opt into earlier announcement for use cases where speed matters more than reorg safety:
{
"settlement_confidence": "included"
}With included, you will receive payment_intent.succeeded early. If the transaction is later reorganised away, you receive payment_intent.reverted and the ledger entries are reversed. This is a deliberate trade: it is appropriate for digital goods delivered instantly, and inappropriate for anything you ship physically.
If you cannot describe how your system would undo a delivered order, do not use
included.
Route selection#
When you ask for a payout, JuicePay picks a route. The inputs are:
- the recipient's declared chain, if any;
- current network cost for the transfer in question;
- the asset's availability on each candidate chain;
- your own chain preferences and blocklists.
You can influence the decision without taking it over entirely:
{
"routing": {
"prefer_chains": ["base", "arbitrum"],
"avoid_chains": ["ethereum"],
"max_network_fee": "1.25",
"allow_bridging": true
}
}allow_bridging: false restricts you to chains where the asset is already held, which removes bridge exposure at the cost of sometimes paying more in consolidation later.
Gas and fee sponsorship#
Recipients should not need a native token to receive value. JuicePay sponsors network fees on outbound legs, so a payout arrives whole. The cost appears as a separate debit ledger entry, which keeps fee accounting clean and auditable.
Confirmations you can trust#
Every transfer carries its transaction hash and the chain it landed on. Verify independently if you want to:
curl -s "$JUICEPAY_URL/v1/payouts/po_4bW9xK" \
-H "Authorization: Bearer $JUICEPAY_KEY" | jq '.legs[] | {chain, tx_hash, confirmations}'