@fire-spark/payments-<provider>-<method>. Packages that need native code end in -rn and only run in React Native or Expo apps. You install only the methods your channel offers.
Install
@fire-spark/payments, the shared contract. You only import it for helpers such as formatPaymentError.
Register the adapters
Register every installed package on the order. Fire spark matches each merchant payment to its adapter by provider and method.Show the methods
getPaymentOptions keeps only the merchant payments that have an installed adapter.
services.payments.list leaves out REDEMPTION payments (vouchers, rewards or balance): they are applied through the order’s redeem entries, not picked as a method. Pass { includeRedemptions: true } as the second argument when a redeem flow needs them, or filter a list you already have with selectablePayments(payments).
For kiosks, getMissingPaymentFields(payment) lists the device settings that are still empty. Hide or disable the method until they are set.
Charge the order
Save the tenders, then charge the device ones.payIntent places the order the first time and runs each real DEVICE tender in sequence.
order.pay(payment) still works and calls payIntent({ payment }). That shortcut places one real tender. Prefer setTenders when the checkout has more than one method.
- The first call places the order and locks the intent. Later calls charge the tenders already on that intent.
- Each method’s package talks to the terminal, shows the QR, or asks Fire spark to charge on the server.
- Each result is saved on its tender. Retries, unknown results, and QR expiry follow the error rules.
PAID means every live tender is settled. PENDING means in-person tenders are still open. The fulfillment PAYING step advances when the tenders in its scope are settled.
Mixed payments
Put every method on the draft before place.allocation: null on a single real tender means it covers the rest. With two or more real tenders, name the lines (and optional units) each one covers. The server fills amount and allocation.amounts.
getRemainingAmount() is the order total minus settled tenders (and tenders that wait for injection). Some methods hold the first charge until the rest succeeds. Call order.confirmPaymentsAfterInject() after the order reaches the kitchen to confirm them. If the order cannot be completed, order.reversePayments() voids or refunds every paid tender. When a provider doesn’t allow it, the tender is flagged for manual reversal and appears in monitoring.
To back out before anything is captured, call order.reopen(). It voids the tenders and returns a new OPEN order. Pass genOrderId(storeId) or any genId() when the new order should use that id; omit it to keep the generated id. genId().hash(length, format) sets the hash length (at least 8, default 12) and format (alphanumeric, numeric, or alphabetic). genOrderId always keeps the ord-<store>- prefix. genId().literal("BB21921").hash(8, "numeric").build() is an id like BB2192100000001. A hash shorter than 12 characters warns, and a numeric hash shorter than 16 digits warns; both are still returned. Shorter hashes collide more often. The request body field is order_id. A bad format is 400 ORDER_ID_INVALID. An id that already exists is 409 ORDER_ID_EXISTS.
Pay with rewards
Vouchers, rewards or stored balance are a redeem.payment_id (the merchant’s REDEMPTION payment) and amount are required. Pass line_uid to redeem a product line, or omit it for the whole order:
amount is the money total for the whole entry, not per unit: two combos worth 3 each are amount: 6. quantity is informational. When you remove some units with removeRedeem, the kept units keep their share of amount.
The redeem shows as the line (or order) discount. Line and order totals keep their full value. before_taxes (default true) caps the redeem at the pre-tax value, so with a burger of 10 + 15% tax the redeem covers 10 and the customer pays 1.50. With before_taxes: false it may cover the full 11.50. redeemedTotal(line.redeem) and orderPayableTotal(order) give what to show: the discount and what is left for the customer.
The SDK adds one REDEMPTION tender per payment_id for the capped amount, and getTenders(method) adds the customer’s method for the rest. In the example that is REDEMPTION 10 and CASH 1.50, or REDEMPTION 11.50 alone. Redeems that share a payment_id go in the same tender, which lists each reward in details.rewards and sums their amount in details.amount. Redeems with different payment_ids get separate tenders.