Webhooks: taxes
Snipcart has a built-in tax management system in the merchant dashboard. If you need full control over how taxes are calculated, the taxes webhook lets you return the applicable taxes for each cart programmatically.
During checkout, Snipcart sends the current cart to your endpoint, and your application is responsible for returning the taxes to apply. Configure your endpoint in your dashboard under Store configurations → Taxes → Providers → Webhooks.
Request
Snipcart makes an HTTP POST request with a JSON body. The top-level envelope is the same as every Snipcart webhook:
| Field | Type | Notes |
|---|---|---|
eventName |
string | Always taxes.calculate. |
mode |
string | Live or Test. |
createdOn |
datetime | When the request was raised. |
content |
object | The current cart - see below. |
The content
Unlike the order events and shipping webhooks - which both send an Order-shaped object - the taxes webhook sends the live cart. A couple of things to note about this payload: dates inside it (creationDate, modificationDate, item addedOn, …) are Unix timestamps, not ISO strings, and paymentMethod is serialized as a number. Commonly-used fields:
| Field | Type | Notes |
|---|---|---|
token |
string | Cart id. |
email |
string | Customer email. |
currency |
string | ISO currency code. |
lang |
string | Cart language. |
status |
string | Typically InProgress during checkout. |
shipToBillingAddress |
boolean | Whether shipping uses the billing address. |
billingAddress |
object | name, company, address1, address2, city, province, country, postalCode, phone. |
shippingAddress |
object | Same shape as billingAddress. |
shippingInformation |
object | fees and method of the selected shipping option. |
items |
object[] | Cart line items. Each carries quantity, unitPrice, totalPrice, totalPriceWithoutTaxes, and taxable. |
discounts |
object[] | Applied discounts. |
customFields |
object[] | Cart custom fields. |
metadata |
object | Merchant metadata. |
itemsTotal |
number | Items total. |
totalWeight |
number | Total weight of the cart. |
total |
number | Cart total. |
taxesTotal |
number | Sum of taxes already applied. |
Example
{
"eventName": "taxes.calculate",
"mode": "Test",
"createdOn": "2017-05-01T19:05:18.1321539Z",
"content": {
"ipAddress": "127.0.0.1",
"lang": "en",
"token": "5af47604-61ef-454b-92c9-37f64684e5e5",
"email": "geeks@snipcart.com",
"mode": "Test",
"status": "InProgress",
"shipToBillingAddress": true,
"billingAddress": {
"name": "Geeks at Snipcart",
"company": "Snipcart",
"address1": "226 rue St-Joseph E",
"address2": "",
"city": "Québec",
"country": "CA",
"postalCode": "G1K3A9",
"province": "QC",
"phone": ""
},
"shippingAddress": {
"name": "Geeks at Snipcart",
"company": "Snipcart",
"address1": "226 rue St-Joseph E",
"address2": "",
"city": "Québec",
"country": "CA",
"postalCode": "G1K3A9",
"province": "QC",
"phone": ""
},
"completionDate": null,
"invoiceNumber": "",
"shippingInformation": {
"fees": 10,
"method": "Shipping"
},
"paymentMethod": 0,
"metadata": {},
"items": [
{
"uniqueId": "abb5bd38-ae77-4feb-8d05-c674e302f986",
"token": "",
"id": "1",
"name": "An item",
"price": 300,
"description": "Item description",
"url": "/",
"image": "http://placehold.it/50/50",
"quantity": 1,
"minQuantity": null,
"maxQuantity": null,
"stackable": true,
"shippable": true,
"taxable": true,
"taxes": [],
"customFields": [],
"duplicatable": false,
"metadata": null,
"unitPrice": 300,
"totalPrice": 300,
"totalPriceWithoutTaxes": 300,
"addedOn": 1493665299,
"initialData": "",
"modificationDate": 1493665299
}
],
"discounts": [],
"customFields": [],
"refunds": [],
"taxes": [],
"currency": "usd",
"totalWeight": 3000,
"total": 310,
"discountsTotal": 0,
"itemsTotal": 300,
"taxesTotal": 0,
"taxProvider": null,
"modificationDate": 1493665318,
"creationDate": 1493665299
}
}Response
Respond with a 2XX status code and a JSON body containing a taxes array. Content-Type must be application/json.
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | Tax name, shown to the customer and on the invoice. |
amount |
decimal | yes | The tax amount, in the cart's currency (rounded to 2 decimals). Not in cents. |
rate |
decimal | no | The tax rate, as a fraction (0.05) or a percentage (5) - both are read as 5%. |
numberForInvoice |
string | no | Tax or registration number shown on the invoice. |
includedInPrice |
boolean | no | See Taxes included in price. |
appliesOnShipping |
boolean | no | See Taxes on shipping. |
{
"taxes": [
{
"name": "Tax1",
"amount": 10.00,
"rate": 0.05,
"numberForInvoice": "TAX-001"
},
{
"name": "Tax2",
"amount": 20.00,
"rate": 0.10,
"numberForInvoice": "TAX-002"
}
]
}Taxes included in price
If your taxes are already included in your prices, set includedInPrice to true. The customer still sees the taxes in the order summary, but they won't be added on top of the cart total.
{
"taxes": [
{
"name": "Tax1",
"amount": 10.00,
"rate": 0.05,
"numberForInvoice": "TAX-001",
"includedInPrice": true
},
{
"name": "Tax2",
"amount": 20.00,
"rate": 0.10,
"numberForInvoice": "TAX-002",
"includedInPrice": true
}
]
}Taxes on shipping
When a tax is included in price, you can also indicate whether it applies to shipping costs with appliesOnShipping.
{
"taxes": [
{
"name": "Tax1",
"amount": 10.00,
"rate": 0.05,
"numberForInvoice": "TAX-001",
"includedInPrice": true,
"appliesOnShipping": true
},
{
"name": "Tax2",
"amount": 20.00,
"rate": 0.10,
"numberForInvoice": "TAX-002",
"includedInPrice": true,
"appliesOnShipping": false
}
]
}