Skip to content

Calculation Modes

Space Invoices supports two standardized document calculation modes.

  • b2b_standard keeps the traditional tax-exclusive flow used for most business invoicing
  • b2c_gross_discount treats discounts as reductions of the customer-facing gross amount, then derives net base and VAT afterward

Use the entity setting when one business should always calculate the same way. Use the request field calculation_mode when a specific document needs to override the entity default.

B2B Standard

Use b2b_standard for classic B2B invoicing where discounts reduce the line amount before VAT is calculated.

Typical flow:

  1. compute the line subtotal from the net unit price
  2. apply discounts to that net subtotal
  3. calculate VAT on the discounted net amount
  4. sum net, VAT, and gross totals at document level

This is the default mode when nothing is specified.

Exact semantics:

  • If you send price, the line starts from price × quantity
  • Percentage discounts are calculated from the original line subtotal, not from a running balance
  • Fixed amount discounts are treated as fixed net amounts
  • All discount amounts are summed, then subtracted once
  • The discounted net line amount is rounded to 2 decimals using half-up rounding
  • VAT is then calculated from the rounded net amount

If you send gross_price in b2b_standard:

  1. start from gross_price × quantity
  2. calculate discounts from that original gross subtotal
  3. round the discounted gross result to get total_with_tax
  4. derive total by dividing by (1 + tax_rate)

Example:

  • price = 100
  • quantity = 2
  • discount 10%
  • VAT 22%

Result:

  • subtotal = 200.00
  • discount = 20.00
  • total = 180.00
  • total_with_tax = 219.60

B2C Gross Discount

Use b2c_gross_discount when the final payable gross amount is the primary value and discounts should reduce that consumer-facing gross total.

Typical flow:

  1. start from the gross line subtotal
  2. apply discounts to the running gross subtotal
  3. round the discounted gross line total
  4. derive the net base and VAT from that discounted gross amount

This mode is useful for retail and consumer invoicing where prices are typically shown including VAT.

Exact semantics:

  • If you send gross_price, the line starts from gross_price × quantity
  • If you send price, the line first derives a gross subtotal as price × quantity × (1 + tax_rate)
  • Discounts are applied in request order to the running gross subtotal
  • Percentage discounts use the current running gross subtotal
  • Fixed amount discounts are treated as gross discounts
  • The final discounted gross line amount becomes total_with_tax
  • total is then derived as round_2(total_with_tax / (1 + tax_rate))
  • total_discount is still exposed as a net-equivalent compatibility field, even though the discounts were applied on gross amounts

Example:

  • gross_price = 122
  • quantity = 1
  • discount 10%
  • VAT 22%

Result:

  • gross subtotal = 122.00
  • gross discount = 12.20
  • total_with_tax = 109.80
  • total = 90.00
  • total_discount = 10.00

Sequential-discount example:

  • gross_price = 122
  • quantity = 1
  • discounts: 10%, then 5
  • VAT 22%

Result:

  1. start from 122.00
  2. apply 10% on 122.00 = 12.20, running gross = 109.80
  3. apply fixed 5.00 on 109.80, running gross = 104.80
  4. total_with_tax = 104.80
  5. total = 85.90

Choosing The Mode

  • Use the entity setting settings.calculation.default_mode for the normal behavior of a business
  • Use request calculation_mode on create endpoints or POST /documents/calculate when a single document should use a different mode
  • The resolved mode is stored on the document, so rendering and later updates stay consistent

Rounding

All monetary amounts are rounded to 2 decimals using half-up rounding.

  • line totals are rounded at line level
  • tax amounts are calculated from the rounded line net amount
  • document tax totals are aggregated from those rounded line values

Custom Create Endpoints

/custom endpoints still accept caller-supplied totals as authoritative.

  • If you omit calculation_mode, Space Invoices preserves the current pass-through behavior
  • If you provide calculation_mode, Space Invoices validates the totals you send against that mode and returns a 422 error when they do not match

For integrations that need exact alignment before document creation, use POST /documents/calculate with the intended calculation_mode, then send the returned totals to the corresponding /custom endpoint.

For /custom, send these values exactly as calculated:

  • items[].total
  • items[].total_with_tax
  • document total
  • document total_with_tax
  • document total_discount
  • document taxes

If you provide calculation_mode, those supplied values must match the selected mode exactly or the request fails with 422.