Currency, buyer presentation, and SeatLayer’s hold record are related but separate decisions. Define the authority your checkout uses before adding a custom price book.
Currency precedence
| Source | Purpose |
|---|---|
| Event or organization currency | Normal order currency; travels with event data |
SDK currency |
Formatting fallback when event data has no currency |
USD |
Built-in fallback |
One hold or booking uses one ISO 4217 currency. SeatLayer does not convert amounts between currencies, and a locale change affects formatting rather than the amount or currency.
const picker = new seatlayer.SeatPicker({
container: "#picker",
event: "ev_9f3a",
currency: "EUR", // event/org data wins when present
});Default: charge the inspected hold
For the simplest and safest checkout, inspect the hold from your backend and
calculate the payment from its unitPrice, currency, and quantity.
const hold = await inspectHold(eventKey, holdId);
const total = hold.items.reduce(
(sum, item) => sum + item.unitPrice * item.quantity,
0,
);
assertOneCurrency(hold.items);
await createPayment({ amount: total, currency: hold.items[0].currency });This makes the chart price snapshot, SeatLayer reports, and your charged amount agree.
Host price books
SeatPicker.pricing can make your application price-authoritative for the
buyer presentation and SDK checkout handoff:
const picker = new seatlayer.SeatPicker({
container: "#picker",
event: "ev_9f3a",
pricing: {
prices: {
vip: 150,
standard: {
base: 60,
tiers: {
early: 45,
door: 75,
},
},
},
formatter: (amount, currency) => `${amount} ${currency}`,
},
onCheckout: (_hold, _seats, handoff) => {
startCheckout({
holdId: handoff.holdId,
displayedTotal: handoff.total,
});
},
});prices accepts a flat category amount or a base amount plus tier overrides.
formatter changes rendered money text. The picker applies the override to
displayed totals and the CheckoutHandoff it gives your callback.
Choose one server policy
Ignore browser-posted totals. Inspect the hold and charge its recorded line items. This keeps SeatLayer’s amount reporting aligned with payment.
Resolve the same category and tier ids against your own server-side price book. Validate eligibility, currency, discounts, and tax there. Record both your charged amount and SeatLayer’s inspected amount because SeatLayer reports will continue to reflect the chart snapshot.
Never trust a custom amount posted from the browser—even if it matches the
CheckoutHandoff. Send the opaque holdId plus your own authenticated cart or
price-context identifier. Recompute the intended amount on the server.
Prevent mismatches
- Keep category keys and tier ids stable across the chart and host price book.
- Version promotional and membership rules so checkout can reproduce them.
- Reject mixed currencies before creating a payment.
- Store the hold id, booking reference, price-book version, and charged amount.
- Decide how refunds and reports reconcile when host and chart prices differ.
- Test resumed and extended holds; a client refresh must not change eligibility.
- Display taxes and fees separately unless they are intentionally part of unit price.
Money units
SeatLayer chart and hold examples use major units, such as 45 for 45.00.
Payment providers often require minor units. Convert once on your server using a
currency-aware library; do not assume every currency has two decimal places.
Continue to holds and checkout, ticket tiers, or the complete checkout example.