API
Confirm payment
Records the payment for an open order and settles it. Accepts several tenders in one charge, and declined attempts too.
POST
Closes the deferred payment cycle: the order was born open, the kitchen already worked, and the
payment arrives here. The order becomes
COMPLETED and invoicing starts when the approved amount
reaches the order total exactly.
One charge with several tenders, in a single call. If you split the bill between cash and card,
send both pieces in the same call: the approved tenders must add up to the order total exactly.
A charge that does not add up is rejected in full and nothing is recorded — consolidate your
partials before sending them.Retrying is safe and expected: resend the whole batch and idempotency by
transaction_id takes
care of the rest.Authentication
string
required
Your Fire API key with the
orders:write scope. The key must be vendor-scoped — keys without
a vendorId are rejected with 403.Path parameters
string
required
Any of the order’s three public references:
This is the same set accepted by Get order and
Cancel order.
Body
object[]
required
The tenders you charged the order with. Between 1 and 20 pieces. Each object is stored exactly as
you sent it; only the fields Fire reads are listed below.
string
required
Outcome of the attempt. These count as charged:
APPROVED, AUTHORIZED, CAPTURED, PAID,
SUCCESS, SUCCEEDED (case-insensitive).Any other value is treated as a decline, even one we do not recognise. That is deliberate:
invoicing a charge that never happened cannot be undone, while failing to settle one that did is
fixed by sending it again.string
required
Transaction identifier. This is the idempotency key: resending the same one does not charge or
invoice twice. If your tender does not produce one, Fire falls back to
payments[].uid.number
required
Amount for this tender, decimal. Must be greater than zero. If it is absent, Fire falls back to
the top-level
payments[].total.string
required
Currency of the tender. All approved tenders must share the same one — including tenders sent
in earlier calls for the same order. If it is absent, Fire falls back to the top-level
payments[].currency_code.string
Reason for the decline, using a code from Decline reasons.
Only applies when
transaction_status is not approved.Your acquirer’s code (51, do_not_honor) must be translated on your side to the catalog’s:
Fire does not store each provider’s codes. If you send one that is not there it is accepted and
stored, but it comes back with resolvedTo: null and stays out of your grouped metrics.string
Payment method (
CASH, CREDIT, DEBIT, PIX…). Used for invoicing and metrics.Request
What Fire does with it
Only approved tenders add up and settle. Declined ones are recorded for your metrics; they never add up and never block the charge.What happened to each decline
Every declined tender comes back indeclines[], with what you sent and whether we found it in the
catalog.
exceedsOrderTotal: true means the amount you attempted is larger than the order total. We do
not require each tender to equal the total —in a split charge, $20 on $35.90 is legitimate— but
exceeding it never is: it almost always means the wrong order is being charged. The decline is your
free warning, because if the next attempt is approved it would settle an amount that does not belong.
resolvedTo: null means that code does not exist in the catalog — in the example, the acquirer’s
raw code was sent instead of Fire’s. The decline was still recorded and the value is kept, but it
shows up in nothing grouped by reason.
A closed order takes nothing else
An order takes tenders while it is open. Once closed it is closed, however it got there. A tender it has never seen is rejected and nothing is recorded — approved or declined alike. The error code tells you why it is closed, and the two call for different actions:
What separates a rejection from a retry is the
transaction_id, not the state of the order:
When the charge settles
Settling is what completes the order, so that is when Fire emitsorder.completed — the order was born OPEN and only
now has it finished. The response reports it as flowsTriggered.
flowsTriggered: 0 is not a payment error. It means one of three things:
That last row is deliberate. If Fire answered with an error because an event could not
be queued, you would retry a charge that already went through. The money wins over the
notification.
An order with deferred payment already issued its fiscal document when it opened, and
it passes through the fiscal step again on
order.completed. Fire detects the
existing document and skips the second issuance — you do not get two invoices.Idempotency
Each tender is identified by itstransaction_id within the order. Retry without fear:
- Resending the whole charge →
duplicate. Nothing is settled or invoiced again. - Resending after a timeout → resend the whole batch. An incomplete charge was never
recorded, and any tender that did land is ignored by its
transaction_id.
Validations
All return400 unless stated otherwise. Every rejection carries a code on top of the message:
branch on the code, not on the text — the message is written to be read and may be reworded, the code
is contract.
Fields Fire does not know about are accepted and stored: you can send your full payment object
without trimming it. The currency of a declined tender never invalidates the batch, because it does
not add up.
Responses
Related
Decline reasons
Grouped catalog used to classify declined attempts.
Get order
Check the status and total before charging.

