Skip to main content
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.
All or nothing. A charge whose approved tenders do not add up to the order total is rejected in full — not even a decline that travelled in the same batch is kept.The reason is not accounting, it is operational: money accepted on an order that does not settle leaves it with cash inside and no way out. Fire does not process refunds and there is no way for you to tell us you refunded. Consolidating partial charges is yours to do — and you are the only one who can refund, so you carry that state anyway.Charging more than the total is rejected for a different reason: it would invoice an amount that was not the one collected, and an invoice cannot be un-issued. Both messages give you the two amounts so you can fix and resend.Declines are the exception: a batch with no approved tenders is recorded and the order stays open. No money means no state to resolve, and that is where your decline metrics live.

What happened to each decline

Every declined tender comes back in declines[], 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.
Check this block on your first integration. A mistranslated code breaks nothing: the charge works, the response is 200, and your declines land unclassified. You would find out months later with an empty reasons dashboard.

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:
A retry is never rejected, on purpose. You charged once and our answer never reached you; replying with an error there would push the operator to run the card again — the double charge we are trying to prevent. Send the same transaction_id and you get the original outcome back.

When the charge settles

Settling is what completes the order, so that is when Fire emits order.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 its transaction_id within the order. Retry without fear:
  • Resending the whole chargeduplicate. 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 return 400 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

Decline reasons

Grouped catalog used to classify declined attempts.

Get order

Check the status and total before charging.