Skip to content

feat(billing): add tax id fields to billing details and contract requests#284

Open
dashed wants to merge 3 commits into
mainfrom
aleal/feat/billing-tax-fields
Open

feat(billing): add tax id fields to billing details and contract requests#284
dashed wants to merge 3 commits into
mainfrom
aleal/feat/billing-tax-fields

Conversation

@dashed
Copy link
Copy Markdown
Member

@dashed dashed commented Jun 3, 2026

Summary

Adds the customer's tax registration number to the platform billing protos so contract invoicing can compute sales tax with the correct treatment (for example, EU reverse charge for tax-registered businesses).

Context

This isn't a new concept — it exposes a value the billing system already stores per customer and already forwards to the tax provider:

  • The customer's tax registration number (VAT / GST / …) is stored on BillingDetails, set and VAT-validated through the billing-details API.
  • At tax-calculation time it is sent to the tax provider as the transaction's businessIdentificationNo (AvaTax), and a present tax id is what drives reverse-charge treatment for tax-registered businesses (e.g. in the EU/UK).

These fields add the two wire hops that were missing:

  • BillingDetails.tax_number exposes the stored value over GetBillingDetails.
  • CreateContractRequest.customer_tax_id / RolloverContractRequest.customer_tax_id let the caller forward it into contract creation and rollover, where tax is computed.

The two names mirror their respective domains: tax_number matches the persisted field, while customer_tax_id matches the tax-calculation input it feeds.

Changes

Message File New field
BillingDetails billing_details/v1/billing_details.proto optional string tax_number = 6
CreateContractRequest contract/v1/endpoint_create_contract.proto optional string customer_tax_id = 7
RolloverContractRequest contract/v1/endpoint_rollover_contract.proto optional string customer_tax_id = 6

GetBillingDetailsResponse already embeds BillingDetails, so it returns tax_number with no further change.

Backwards compatibility

All three are new optional fields with previously-unused field numbers — additive only, with no field reuse, rename, or type change — so the change is backwards-compatible (buf breaking passes against main).

Codegen

Rust bindings are regenerated and committed (rust/src/…billing_details.v1.rs, …contract.v1.rs). Python output is gitignored and regenerated by consumers.

REVENG-15

…ests

Carry the customer's tax registration number across the platform billing service boundary so contract invoicing can compute sales tax with the correct treatment (e.g. EU reverse charge for registered businesses).

- BillingDetails.tax_number (field 6): mirrors the stored billing-details tax number, returned by GetBillingDetails.
- CreateContractRequest.customer_tax_id (field 7) and RolloverContractRequest.customer_tax_id (field 6): let the caller forward the resolved tax id into contract creation and rollover.

All three are optional string fields with new field numbers, so the change is backwards compatible.

REVENG-15
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

The latest Buf updates on your PR. Results from workflow ci / buf-checks (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedJun 3, 2026, 10:22 PM

getsantry Bot and others added 2 commits June 3, 2026 21:48
Add a doc-comment to BillingDetails.tax_number for parity, and note the reverse-charge use on the contract requests' customer_tax_id. Regenerated Rust bindings carry the comments.
@dashed dashed self-assigned this Jun 3, 2026
@dashed dashed marked this pull request as ready for review June 3, 2026 23:12
@dashed dashed requested a review from a team as a code owner June 3, 2026 23:12
Copy link
Copy Markdown
Member

@brendanhsentry brendanhsentry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm; small question

// The customer's tax registration number (e.g. VAT ID), used to determine
// tax treatment for this contract (for example, reverse charge for
// tax-registered businesses). Unset if none is on file.
optional string customer_tax_id = 6;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this for rollover contract? We pass the invoice line items through this request. So doesn't it make more sense to make use of the customer_tax_id when determining the line_items to pass to this request?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brendanhsentry im moving the tax calculation to upstream in the invoicer service rather than at the contract service. this changed the protos a bit. i'm preferring the protos field additions in #286 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants