Skip to main content

Overview

A fee is money added to an order that isn’t the price of a product and isn’t tax. Gift wrapping. A handling charge. The surcharge for paying cash on delivery. An import duty on a parcel crossing a border. Fees are their own kind of row, separate from tax and discounts, so a merchant can answer “what did we charge in handling this quarter” without untangling a mixed list.

Fee attributes

When neither ID is set, the fee applies to the whole order. The list is open — an extension can add its own kind.
Fees are always positive. To take money off, create a discount instead. This isn’t pedantry: when a refund is worked out later, it has to know whether a row was a charge or a credit, and a negative fee makes that ambiguous.

Adding a fee

Fees are visible to the storefront on the cart and the order, so a customer sees what they’re being charged before they pay:

Fees and tax

Fees are taxable by default — a handling charge in a VAT country is itself subject to VAT, and Spree writes tax lines against the fee accordingly. Customs duties are the exception, described next.

Customs duties

When a parcel crosses a border, the destination country may charge import duty. Whether the customer pays that at checkout or gets a bill from the courier later is a commercial decision — and quoting it up front is what avoids parcels being refused at the door. A duty is recorded as a fee with kind: 'duty'. Two things make it different from every other fee.

Duties aren’t taxed

A duty is an import charge levied by the destination country, not a sale that domestic tax applies to. Charging tax on top of it would invent tax the merchant never owed, so Spree leaves duties out of the taxable set. Where import VAT genuinely applies, whoever calculated the duty records that tax itself.

Duties remember what they were calculated from

A duty fee keeps a copy of its inputs — the commodity code, the country of origin, the rate — in its metadata. This matters more than it sounds. A product’s classification can be corrected next month; a supplier can change. What the customer was actually charged must not move when that happens. The snapshot is the authoritative record, and a duty is never re-derived from today’s catalogue.

Customs classification

For any of this to work, the goods have to be described in the language customs authorities use. Three fields on each variant do that:
country_of_origin is where the item was manufactured, not the warehouse it leaves from. Duty rates and trade agreements turn on origin, so getting this wrong produces the wrong charge — and can hold a parcel at the border.
These fields are editable per variant and in the bulk product editor. They’re also what a carrier integration puts on the customs declaration for an international label — required for cross-border parcels, ignored for domestic ones.
Spree records classification and charges duties; it does not itself estimate them. A landed-cost provider calculates the numbers and writes the duty fees. See Providers.