- The order or invoice is the thing you created. It is payable, then terminal.
- A payment attempt is one quote-locked session under it. Several may come and go during a single order’s life.
- A confirmation is a presentation-layer read of how deeply a transfer is buried. Nothing gates on it.
Orders
Invoices
Same machine as orders, withpaid in place of completed and one extra terminal
state, voided, for a merchant cancelling before payment. Voiding is refused while an
attempt is live — see the void guard.
Payment attempts
An attempt is created when the buyer picks a token. It locks a crypto quote, mints a fresh deposit wallet used for that attempt alone, and is watched until it resolves.
Three consequences worth internalising:
At most one live attempt per order or invoice
At most one live attempt per order or invoice
Only one attempt can be
processing at a time. Re-selecting the token that is
already live returns the same attempt — same address, same quote — so reloading
the checkout page is safe and does not mint a second address.Abandoned addresses keep working
Abandoned addresses keep working
Switching tokens marks the old attempt
abandoned, but it stays watched until its
own window ends, and it can still complete. Funds a buyer broadcast just before
switching are not lost.Abandonment emits no webhook. It is a UI affordance, not a lifecycle event.A lapsed empty attempt costs nothing
A lapsed empty attempt costs nothing
An attempt that expires holding zero leaves the parent
pending / open. The
buyer picks a token again, gets a fresh quote on a fresh address, and can keep
doing that until the parent itself expires.Partial payments
While an attempt is live, an insufficient balance simply sits there — Taberna keeps re-reading the deposit address, so the buyer can top it up and the attempt completes the moment the total clears the quote. Nothing is decided until the window closes. At the attempt’sexpiresAt, exactly one rule applies:
Overpayment completes normally. The comparison is
>=, so a buyer who sends more
than quoted gets a completed order; the surplus is part of the swept amount.
Surfacing a partial
partial is terminal on the parent and is not resolved automatically — there is no
automatic refund. What you get:
- An
order.partialorinvoice.partialwebhook. receivedAmountandcryptoAmounton the order, or underpaymenton the invoice, so the shortfall iscryptoAmount − receivedAmountin the token’s smallest unit.transactions[], so you can trace what actually arrived and from where.
partial unless you have decided to honour underpayments.
Confirmations
activeAttempt.confirmation on the public checkout payload
reports how deeply the inbound transfers are buried.
confirmations is clamped to at most required, so it never overshoots. Both are
null when unknown.
Per-chain confirmation depths
These values reach the API through the chain indexers rather than being hardcoded in
it, which is why
required can legitimately be null: no depth has been published
for that chain yet. Treat a null as “unknown”, never as “zero”.Expiry windows
The attempt window is precisely
min(now + 30 minutes, the parent's expiresAt). A
locked quote must never outlive its parent, so an attempt started five minutes before an
order expires gets five minutes, not thirty.
Expiry is swept by a background pass rather than evaluated on read, so a resource can
sit a few seconds past its expiresAt before its status changes. Poll for the status
change; do not compute expiry client-side.
Supported chains and currencies
Fiat pricing currencies:usd and eur.
Thirteen payment methods in total. Which of them a buyer can actually pick is your
store’s
enabledPaymentMethods, readable at any time from GET /v1/store.
Settlement
Each payment lands in the deposit wallet Taberna generated for that attempt, and is then swept on-chain to your store’s payout wallet for that chain — the address you registered in the dashboard. There is no Taberna balance to withdraw from and no payout schedule.The processing fee
The sweep splits the swept balance: the processing fee goes to Taberna, the remainder to your payout wallet. The standard rate is 3%; it is set per store, so check the dashboard for the rate that applies to yours. The deduction happens on-chain, in the sweep transaction itself, so what arrives at your address is already net of it. That is the only deduction Taberna makes:
Because sweep gas is covered by Taberna, the processing fee is the whole cost of
settlement.
Processors that charge a percentage and then bill network or withdrawal fees separately
deduct on more than one line.
What gets swept, and when
A funded deposit wallet is swept once its attempt has settled — the sweepers pick up attempts incompleted, expired or partial. expired and partial are included so
that funds which arrived too late, or fell short of the quote, still reach your payout
wallet rather than being stranded.
An abandoned attempt is not swept while it is abandoned. It stays watched to the
end of its own window and then settles into completed, partial or expired like any
other attempt; the sweep follows from that settled status, not from the abandonment.
Sweep state is internal plumbing. It appears nowhere on the public API — not on
the buyer-facing checkout payload and not on
GET /v1/orders/{id} or
GET /v1/invoices/{id}. Settlement progress is visible only in the dashboard. Your
completion signal is the order or invoice status, never the sweep.