@voyant-travel/commerce) owns the narrow commercial decision: given a Catalog Item or vertical item, a date, a party, a market, a channel, a buyer, and a currency, can it be bought, and at what price? It is the layer that turns catalog (what exists) into something buyable (what this customer can purchase right now). It owns the quote-time markets, pricing, promotions, and sellability runtime sources behind a single root call.
Commerce is deliberately thin and adapter-driven. It does not depend on Product or inventory schemas; operated inventory and every sourced vertical enter commerce the same way, through an item reference resolved by a registered price-availability adapter. The decision is the resolved answer to Sellability: it combines availability, pricing, allotments, and policies into one verdict, and it does so without side effects.
Key concepts
The result of
evaluateCommercialDecision. It carries status and buyable (buyable, unbuyable, or error), a canonical reason code, full pricing, fx, promotions, availability, sellability, rule traces, adapter/source handles, and validFrom / validUntil bounds.A Supplier’s per-unit tariff:
per_person, per_night, per_vehicle, or flat. The pricing input, not the customer-facing number. See Rate.The customer-facing sell amount. Commerce returns it in minor units with components, tax and fee facts, and source price facts. See Price.
A geographic and economic region (for example “EU” or “US East Coast”) that anchors currency and pricing. The decision input carries the requested market and the requested sell currency separately; FX resolves one to the other. See Market.
A timestamped snapshot of exchange rates used to resolve prices in a non-native currency. The decision’s
fx block records the requested currency, source currency, rate, rate set, and provider handle when a conversion was applied. See FX Rate Set.A discount applied at decision time. The
promotions block reports applied and rejected promotions, the requested codes, the total discount, and the stacking facts that explain why each promotion did or did not apply.The unit of extensibility. An adapter declares
id, kind, supports(input), and evaluate(input, context). Inventory is just one adapter kind; cruise, accommodation, and sourced verticals each register their own. The evaluator selects the adapter that supports the item and delegates pricing and availability to it.What it owns
- The commercial decision Interface:
createCommercialDecisionEvaluator,evaluateCommercialDecision, and the decision, trace, pricing, promotion, FX, and snapshot types, all exposed from the package root. - Markets and FX: the market definitions and rate sets that anchor currency and resolve cross-currency pricing.
- Pricing: the rule engine that assembles components, taxes, fees, and surcharges into a sell price from the selected adapter’s source facts.
- Promotions: the promotion catalog and the stacking and eligibility logic, with a dedicated admin surface.
- Sellability: the runtime that folds availability and policy facts from the adapter into the buyable verdict.
- The adapter registry:
createCommerceAdapterRegistryand the boot-time registration of price-availability adapters. - Snapshot recording:
recordCommercialSnapshot, the explicit persistence command for decision evidence.
evaluateCommercialDecision is side-effect-free from commerce’s perspective: it may call adapters that read operational or source state, but it must never create offers, orders, reservations, holds, snapshots, ledgers, or audit records. Persisting evidence is a separate, explicit step.
Working with it
You build an evaluator at boot, register the adapters your deployment uses, and call the root decision for each priced surface.idempotencyKey to replay the same decision deterministically.
The decision distinguishes error modes precisely. An item with no registered adapter returns an
unbuyable decision with unsupported_item; duplicate adapter ids throw at registration; an adapter that fails at evaluation returns an error decision with adapter_failed and an error trace; a buyable decision that lacks pricing facts is rejected as adapter_invalid_result. A buyable decision must always carry real pricing.Links to other modules
- catalog supplies the item reference. Commerce reads the catalog plane to know what is being priced; for sourced items, the catalog source adapter’s
liveResolvefeeds the price-availability adapter. - inventory registers the operated price-availability adapter, reporting Product pricing and Slot availability into the decision.
- distribution supplies channel and commission context. A decision is scoped to a Channel, and what the channel earns (its commission rule) is reconciled and settled in distribution.
- bookings is where a decision becomes a commitment. The booking captures the commercial snapshot evidence alongside its own per-line transactional state.
- finance consumes the priced components, taxes, and fees when it issues invoices.
React package
The@voyant-travel/commerce-react family owns the reusable commercial UI under owner-path subpaths: @voyant-travel/commerce-react/markets, @voyant-travel/commerce-react/pricing, @voyant-travel/commerce-react/promotions (with an /admin surface), and @voyant-travel/commerce-react/sellability. Prefer these for any commerce-owned admin or storefront wiring.
Next steps
Catalog
The sellable plane commerce prices, owned and sourced alike.
Inventory
The operated availability and pricing the commercial decision reads.
Distribution
Channels and commission rules that scope the commercial decision.
Glossary
Cost, Rate, Price, Market, and Sellability defined precisely.