Comparison to Calculations endpoint
Our endpoints are very similar to the Calculations endpoint, but they have a couple more fields:type (enum)
status (enum)
parent_transaction_id (string, optional)
Represents the ID of the parent transaction in case of a credit memo/refund.
It must be one of your own transactions: any other ID returns 422.
reference_id (string, optional)
Represents the ID of the transaction in an external billing system, like in Stripe you might have INV-123. These must be globally unique in your account. Creating a second transaction with the same reference_id returns 400.
tax_amount (decimal string, optional)
Represents the tax amount for the transaction. If not provided, we will calculate it and set it ourselves.
If your billing system puts the tax on a line item instead, mark that line with SALES_TAX and Taxwire adds its amount here; the transaction then has a provided tax even if you send no tax_amount. The tax_amount in a response includes those lines, so don’t send it back on an update. See Tax on a line item.
API endpoints
We have a small set of REST-style endpoints which can be used to create sale and credit transactions.Creating sale transactions
There are two ways of handling payments.Draft invoice method
A “draft” invoice is an invoice which will be finalized soon.- Call our
POST /transactionsendpoint (with the same payload as thePOST /calculationscall), but also include a field"status": "draft". This will create a draft transaction in our system, and then return to you a transaction ID, and the tax due. - Create the actual invoice/payment in the billing system, with that tax amount.
- We recommend, but do not require, associating the Taxwire Transaction ID in the metadata of that billing system.
- When the external transaction is created, you can call our
POST /transactions/{id}field with{ "status": "finalized" }to signal that the sale has been completed. You also might want to also include"reference_id": <external_id>to the payload so it is easy to find the relevant Taxwire Transaction for that reference ID.
Calculation estimate method
Instead of creating a draft transaction and then finalizing it, you can also usePOST /calculations first to get the tax amount, and then later create a finalized invoice using POST /transactions (including all line items + tax collected). Send the tax collected in one place only: in tax_amount, or as a SALES_TAX line (see Tax on a line item).
Create credit transactions
To create a refund, we treat this as a separate transaction of typecredit. It has all the same line items and tax amounts (all positive amounts), but it just has the credit type.
As a utility, if a parent_transaction_id is provided, and no line_items are provided, we will pull in all the line items for the original transaction. This is for full refunds or credit memos. You can also just provide us the full line items again instead if there is no parent transaction yet.
Leave line_items out for this: an empty list copies nothing. The credit’s tax is calculated on the copied line items, so it reverses the tax Taxwire calculates on them. Tax the sale carried in tax_amount or as SALES_TAX lines is not copied; to reverse it, also send the credit’s tax_amount.
If instead line_items are provided (even if a parent_transaction_id is present), we use those line items instead. This can be useful for partial refunds or partial credit memos.
What this looks like is very similar to the payment workflow:
- For a full refund, you simply wait for the refund event, and then do
POST /transactionswith a body of{ "type": "credit", "parent_transaction_id": "txn_123…", "status": "finalized", "transaction_date": "2025-03-01T00:00:00Z" }. If the sale’s tax came fromtax_amountorSALES_TAXlines, add the credit’stax_amountto that body, as described above. - For a partial refund, you need to know how much tax to refund, so you can do a very similar approach as the payment workflow
- First do a calculation, either with
POST /calculations, or by creating a draft transaction. This outputs the tax. - Then, you refund the line items, plus the tax, in the payment system.
- Then, you either create a finalized transaction with the updated line items (and optional
parent_transaction_id), or you update the transaction with{ "status": "finalized" }.
- First do a calculation, either with