Developer Docs · 07

Unified Pricing & Tax

One calculation path turns any sellable into a computed Price value object carrying net, per-rate tax and gross in one operating currency.

Taxes and countries configuration in the admin.
Taxes and countries configuration in the admin.

PriceFactory

There is exactly one way to price something:

from vbwd.pricing import PriceFactory

price = PriceFactory.get_price_from_object(sellable)
price.netto     # net amount (Decimal, never rounded)
price.taxes     # per-rate tax breakdown
price.brutto    # gross amount
price.currency  # the single operating currency

Any object that implements the Priceable protocol can be priced — subscriptions, add-ons, products, bookings.

The Price value object

Price is a computed value object: net, per-rate taxes, gross and currency. Values are never rounded internally (rounding happens once, at the display/charge edge) so totals reconcile to the cent.

Storage & currency

Sellables store a single price float plus a prices_mode_in_db flag that says whether the stored number is net or gross. A single default_currency (exposed at GET /api/v1/config) is the operating currency; everything bills in it. A fe-user display-currency switch converts for display only via the admin rate sheet — it never changes what is charged.

Invoices & discounts

Invoice views aggregate a per-line tax_breakdown (net/gross from invoice totals). A discount therefore carries a negative per-rate tax_breakdown so the generic invoice views reconcile: the discount reduces net and tax is recomputed on the discounted net.