Breaking (pre-GA): Merchant-scoped resources no longer expose
organization_id. Scope children by merchant_id (and env when
applicable). Storefront realtime topics are sf:{merchant}:{env}. Merchants
and organization endpoints still include organization_id.Reopen a cancelled order
- Storefront
POST /orders/:id/reopenalso accepts an order alreadyVOIDED,REVERSED, or legacyCANCELLEDthat was never fulfilled, once every real tender isCANCELLED,FAILED, or fullyREFUNDED. A kiosk can return to checkout after a failed injection whose card was reversed on the device. Nothing is voided again and no webhook is sent. APAIDtender (reversal in flight) is still400ORDER_PAYMENT_CAPTURED; anIDLEorPENDINGone is422ORDER_NOT_REOPENABLE.REFUNDEDorders stay rejected: a refund only happens after delivery.
SDK 0.6.0 — virtualized category scroll-spy and checkout release
@fire-spark/rn-uiuseActiveCategoryaccepts an index mode for virtualized lists (FlashList, FlatList, LegendList). PassrowSectionIds,headerIndex, andlistRef.onScrollreadsgetFirstVisibleIndex. FlatList can useonViewableItemsChanged.selectCategorycallsscrollToIndex. The offset mode (categoryIds,offset,scrollRef,registerCategory) is unchanged.@fire-spark/react-uistays on offset mode.@fire-spark/storefrontaddsbuildMenuRows,menuRowKey,menuRowType, andspanMenuRow. They turn flattened sections into header, product, and empty rows for those lists.- See Displaying menus.
@fire-spark/realtimeaddswatchCheckoutRelease. It subscribes toorder.changedand settles whencheckout_stateisreleasedorfailed, so place order can stay loading until the fulfillment releases checkout. Callarmonce place order is in flight to start the timeout (60 s by default,timeoutMs),considerto feed a payload you already have, andstopon unmount. Passcurrentto settle at once on a known state. Exports theCheckoutReleaseWatchandCheckoutReleaseResulttypes.
SDK 0.5.0 — one redeem model (breaking)
- Breaking: every redeem (order or line) requires
payment_id, an activeREDEMPTIONpayment of the merchant, andamount> 0. A redeem without them is rejected (REDEEM_PAYMENT_REQUIRED); an unknown, inactive or non-REDEMPTIONpayment returnsREDEEM_PAYMENT_METHOD_NOT_CONFIGURED. - Line money, taxes and
totalsstay full.redeem[].amountis shown as the discount and itsREDEMPTIONtender pays it; the customer’s method pays the rest.before_taxes(defaulttrue) caps the redeem at the pre-tax value, so taxes stay for another method. Example: 10 + 15% tax with a redeem of 10 givesREDEMPTION10 +CASH1.50; withbefore_taxes: falsethe redeem can cover 11.50 andREDEMPTIONpays everything. - Tender
amountis{ currency, total }.allocation.amounts[]is{ line_uid, units?, total, children }with gross line money. Old breakdown keys (subtotal,discount_total,tax_total,fees,tip,delivery,redemptions_applied) are dropped on read. - Order validation returns
REDEEM_AMOUNT_MISMATCHfor a redeem above its cap. redemption_stepsfollow the same model: one step per redeem, in application order (root-line redeems, then order redeems), withpayment_id,before_taxesanddiscount_amount= the cappedamount. The steps of apayment_idadd up to itsREDEMPTIONtender; a step never lowers line money or totals, andafter.valueis what the customer’s method still pays. The server recomputes and stores them, and validate/place still reject client steps that differ:REDEMPTION_STEPS_MISMATCH(other redeems or order) andREDEMPTION_MISMATCH(other money). NewredemptionSteps().- Renamed:
groupPaymentRedeems→groupRedeems,orderPaymentRedeems→orderRedeems,paymentRedeemsCoverTotal→redeemsCoverTotal,clampPaymentRedeems→cappedRedeems.isPaymentRedeemis removed. NeworderPayableTotalgives what real tenders must pay. - Stored redeems without
payment_idare skipped on read; they are never written. - Breaking: a rejected cart sync (POST/PATCH) is no longer swallowed.
The draft still rolls back to the last synced order, and the next
placeOrder/setTendersthrowsOrderSyncRejectedError(aStorefrontHttpErrorwith the APIstatus,codeanddetails) instead of placing the stale order. - Breaking: place has no cash default. Without
intent_idorpayment.type,POST /orders/{id}/placereturns422PAYMENT_REQUIRED, unless the redeems cover the whole total (then onlyREDEMPTIONtenders).order.placeOrder()throwsOrderPaymentRequiredError(code: PAYMENT_REQUIRED) before calling the API. Send the picked method, with its merchantpayment.id. - Release with
pnpm sdk:release minor.
SDK 0.4.0 — redemption amounts (breaking)
- Breaking: redeems and
REDEMPTIONtender details carry money only.pointsandprogramare gone fromorder.applyRedeem,orders.redeemanddetails.details.points_valueandrewards[].points_valueare nowamount. - Details stored with the old keys are still read:
points_valuebecomesamountandpoints/programare dropped. They are never written. order_payment_operations.pointsand the Tinybirdorder_payments_metrics.pointscolumn are removed.- Release with
pnpm sdk:release minor.
SDK 0.3.2 — reopen
- Storefront
POST /orders/:id/reopenvoids unpaid tenders, cancels the source order asVOIDED, and returns a newOPENorder. The link ismetadata.reopen(as_order_idon the source,from_order_idon the new order). A captured real tender returns400ORDER_PAYMENT_CAPTURED. Integrations receiveorder.voided. - SDK
order.reopen(). On a kiosk, Cancel during the checkout-release wait calls it. - All 15
@fire-spark/*packages are0.3.2.
SDK 0.3.1 — redemption tenders
- Redeems that share a
payment_idare oneREDEMPTIONtender.details.rewards[]lists them.pointsandpoints_valueare the sums.amountandpointson the redeem are totals for the entry. services.payments.listhidesREDEMPTIONunless{ includeRedemptions: true }.
SDK 0.3.0 — tenders
- An order’s payments are
payment_intents[].tenders[]: method, amount, status,collect_at, andallocation.is_mixedis true when there are two or more real tenders. - Storefront:
PUTandDELETE /orders/:id/payment-intent,POST /orders/:id/payments, and tendervoid,replace, andrefund. Place locks a saved draft withintent_id, or builds one real tender frompayment. - SDK:
setTenders,payIntent,retryTender,replaceTender,voidTender,refundTender.order.paycallspayIntent.
Payments SDK
- New payments packages:
@fire-spark/payments(shared contract) and@fire-spark/payments-cash. Register them withorder.setPaymentAdaptersand charge withorder.pay. See Use payments in the SDK. - Split payments: an order is paid when the sum of its
PAIDintents covers the total. - Provider webhooks land on
/api/webhooks/payments/{provider}. - Kiosk devices accept
settings_overrides.payment_settings, with secret fields masked on read. - New monitoring trigger: Payment terminal failures.
- New supported payment methods page.