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.
category string no EN 16931 VAT category, for e-invoicing. Defaults to Standard. See E-invoicing fields.
exemptionReason string no VAT exemption reason shown on the e-invoice. See E-invoicing fields.
taxableBase decimal no Net amount the tax was computed on, for e-invoicing. See E-invoicing fields.
{
  "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
    }
  ]
}

E-invoicing fields

If you use e-invoicing, each tax can also carry three optional fields controlling how it is reported in the VAT breakdown of the generated e-invoice. They have no effect on how the tax is calculated or charged at checkout, and omitting them is fully backward-compatible: the tax defaults to the Standard category and its taxable base is derived from the order.

  • category - the EN 16931 VAT category (BT-118). One of Standard (the default), ZeroRated, Exempt, ReverseCharge, IntraCommunity, Export, OutOfScope, CanaryIslands, CeutaMelilla.
  • exemptionReason - free text justifying the exemption, shown on the e-invoice for any category other than Standard - for instance, the legal article that applies. If omitted, Snipcart emits a standard default.
  • taxableBase - the net amount the tax was computed on, in the cart's currency.
{
  "taxes": [
    {
      "name": "Tax1",
      "amount": 10.00,
      "rate": 0.05,
      "numberForInvoice": "TAX-001",
      "category": "Standard",
      "taxableBase": 200.00
    },
    {
      "name": "Reverse charge",
      "amount": 0,
      "rate": 0,
      "category": "ReverseCharge",
      "exemptionReason": "VAT reverse charge under Article 196 of the VAT Directive",
      "taxableBase": 100.00
    }
  ]
}

Was this article helpful?