> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.taxcloud.com/api-v-3/guides/workflows/real-time-api/handling-discounts/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.taxcloud.com/_mcp/server. # Handling Discounts with TaxCloud TaxCloud's API provides native support for discounts at both the line-item and order level. You can apply discounts directly through the API, there's no need to pre-calculate discounted prices in your integration code. > **Migration Note:** If you previously handled discounts by submitting pre-discounted prices or using negative line items, see [Migrating from Manual Discount Handling](#migrating-from-manual-discount-handling) at the end of this guide. ## How Discounts Work TaxCloud applies discounts before calculating tax, distributes order-level discounts proportionally across eligible items, and preserves original prices for audit and refund purposes. ## Discount Types TaxCloud supports two levels of discounts, each available as either a percentage or a fixed dollar amount. Send discounts in a `discounts` object next to `lineItems` on a cart or an order. It holds `lineItemDiscounts`, a list of discounts for specific lines, and `orderDiscount`, a single discount for the whole order. When you send `discounts`, each line item's `price` must be the original, pre-discount price. ### Line-Item Discounts A line-item discount applies to a specific item in the cart or order. Use this when a coupon or promotion targets a particular product. Each entry in `lineItemDiscounts` names the line by its `itemId`. If the same `itemId` appears on more than one line, add `cartItemIndex` with that line's `index`. **Percentage discount:** Reduces the item's price by a percentage. Percentage values are expressed as decimals from 0 to 1 (e.g., 0.20 for 20%). ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "price": 50.00, "quantity": 2, "tic": 0 } ], "discounts": { "lineItemDiscounts": [ { "itemId": "SKU-1001", "type": "percentage", "value": 0.20 } ] } } ``` In this example, each unit's price is reduced from \$50.00 to \$40.00 before tax is calculated. **Fixed amount discount:** Reduces the item's price by a specific dollar amount per unit. ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "price": 50.00, "quantity": 2, "tic": 0 } ], "discounts": { "lineItemDiscounts": [ { "itemId": "SKU-1001", "type": "amount", "value": 10.00 } ] } } ``` Here, each unit's price is reduced from \$50.00 to \$40.00. **Multiple discounts on the same item:** If the same item has multiple line-item discounts, they are applied sequentially. Each discount operates on the result of the previous one. ```shell Item: $100.00 First discount: 10% → $100.00 × 0.90 = $90.00 Second discount: 20% → $90.00 × 0.80 = $72.00 ``` ### Order-Level Discounts An order-level discount applies to the entire order. TaxCloud distributes the discount proportionally across all eligible line items based on their share of the order subtotal. Shipping and excise tax items are excluded from both the subtotal calculation and the discount application. **Percentage discount on the order:** ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "price": 80.00, "quantity": 1, "tic": 0 }, { "index": 1, "itemId": "SKU-1002", "price": 20.00, "quantity": 1, "tic": 0 }, { "index": 2, "itemId": "SHIPPING", "price": 10.00, "quantity": 1, "tic": 11010 } ], "discounts": { "orderDiscount": { "type": "percentage", "value": 0.10 } } } ``` The 10% discount applies to the two product items (\$80 and \$20), but **not** to the shipping item (TIC 11010). The \$80 item is reduced to \$72.00, and the \$20 item is reduced to \$18.00. Shipping remains at \$10.00. **Fixed amount discount on the order:** ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "price": 80.00, "quantity": 1, "tic": 0 }, { "index": 1, "itemId": "SKU-1002", "price": 20.00, "quantity": 1, "tic": 0 } ], "discounts": { "orderDiscount": { "type": "amount", "value": 15.00 } } } ``` A \$15 order-level discount is distributed proportionally across eligible items. If the eligible subtotal is \$100, an item priced at \$80 receives \$12.00 of the discount (80% of \$15), and an item priced at \$20 receives \$3.00 (20% of \$15). **Discount exceeding subtotal:** If an order-level amount discount exceeds the eligible subtotal, it is capped at 100%. All eligible items are reduced to $0.00; no error is returned. ### Combining Line-Item and Order-Level Discounts You can apply both line-item and order-level discounts on the same request. When both are present: 1. **Line-item discounts are applied first**, reducing each item's price individually. 2. **The order-level discount is then calculated** based on the post-line-item-discount subtotal of eligible items. 3. **The order-level discount is applied to all eligible items**, including those that already received line-item discounts. ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "price": 100.00, "quantity": 1, "tic": 0 }, { "index": 1, "itemId": "SKU-1002", "price": 50.00, "quantity": 1, "tic": 0 } ], "discounts": { "lineItemDiscounts": [ { "itemId": "SKU-1001", "type": "percentage", "value": 0.10 } ], "orderDiscount": { "type": "amount", "value": 10.00 } } } ``` #### How the Discounts Were Applied | Parameter | SKU-1001 | SKU-1002 | | --- | --- | --- | | Original Price | $100.00 | $50.00 | | Line-Item Discount (10%) | −$10.00 | — | | After Line-Item Discount | $90.00 | $50.00 | | Order Discount (share of $10.00) | −$6.43 | −$3.57 | | **Final Price (for tax)** | **$83.57** | **$46.43** | **How the order discount was split:** Since SKU-1001 (\$90) and SKU-1002 (\$50) together make up \$140, each item absorbs a proportional share of the \$10.00 order discount — 64.3% and 35.7% respectively. ## Exclusion Rules Not all items are eligible for every type of discount. TaxCloud enforces the following rules automatically to ensure tax compliance. ### Shipping and Handling (Order-Level Exclusion) Items with the following TICs are **excluded from order-level discounts** but can receive line-item discounts (on the assumption that a line-item discount on shipping is intentional). These items are also excluded from the subtotal calculation used to distribute order-level discounts. | TIC | Description | | ----- | ----- | | 11010 | Transportation, shipping, postage, and similar charges | | 11011 | Transportation, shipping, postage, and similar charges by USPS | | 11012 | Transportation, shipping, postage, with pick-up option | | 11013 | Transportation, shipping, postage, and similar charges where the charge is marked up | | 11014 | Inbound freight | | 11015 | Delivery charges involving or related to the sale of electricity, natural gas, or artificial gas by a utility | If you need to discount shipping, apply a line-item discount directly to the shipping line item. ### Excise Tax Items (All Discounts Excluded) Items with the following TICs are **excluded from both line-item and order-level discounts**. Order-level discounts skip these items automatically. A line-item discount on one of these items is rejected with a `400 Bad Request` error, so do not send one. | TIC | Description | | ----- | ----- | | 10061 | Trade-ins of like-kind property | | 10062 | Trade-ins of non-like kind property | | 10063 | Trade-ins of motor vehicles | | 10064 | Trade-ins of watercraft on watercraft | | 10065 | Trade-ins of watercraft and trailer or outboard motor | | 10080 | Employee discounts reimbursed by a third party on sales of motor vehicles | | 10085 | Manufacturer rebates on motor vehicles | | 10090 | Manufacturer coupons | | 11097 | Minnesota Retail Delivery Fee | | 11098 | Colorado Retail Delivery Fees | | 11110 | Seller State Responsible | | 11120 | Seller Tribal Responsible | | 91020 | Voluntary Gratuity | | 91021 | Mandatory Gratuity (≤20% of sales price) | | 91022 | Mandatory Gratuity (\>20% of sales price) | | 91030 | Donations | | 99987 | Oklahoma Excise Tax on Mobile Homes | | 99988 | Disposable bag fee | | 99990 | Colorado Excise Tax on Firearms and Ammunition | | 99994 | Core Charges | | 99995 | Tire Fees | | 99996 | CA eWaste Fees | | 99997 | Specialized | | 99998 | Use Tax Reporting | > **Colorado Retail Delivery Fee**: Note that it is non-refundable. ## Understanding the Response When your request is processed, each line item in the response includes both `originalPrice` and `price` fields. These are always present, regardless of whether a discount was applied. ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "originalPrice": 100.00, "price": 83.57, "quantity": 1, "tax": { "amount": 5.85, "rate": 0.07 }, "tic": 0 } ] } ``` * `originalPrice` — The price submitted in your request, before any discounts. If no discount applies, this will match price. * `price` — The final price after any discounts have been applied. This is the amount tax is calculated on. The original items in your request are never modified. The response returns a new representation with these fields always populated. ## Discounts and Refunds When processing a refund on a discounted order, TaxCloud uses the **discounted price** (not the original price) to calculate the refund amount. You do not need to re-apply discount logic when submitting refund requests, this is handled automatically. Key refund behaviors with discounts: * **Refunds reflect discounted prices.** If a 10% discount reduced a \$100 item to \$90, refunding 1 unit returns \$90. * **Order-level discounts are distributed proportionally.** Each unit receives its proportional share of the discount, and refunds return that proportional amount. * **Multiple partial refunds work correctly.** Each partial refund uses the discounted unit price, and the sum of all partial refunds matches the total discounted order amount. * **Stacked discounts use the final price.** If both line-item and order-level discounts were applied (e.g., \$100 → \$90 → \$72), the refund uses the final $72. * **Shipping can be refunded at full price.** Shipping items are excluded from discounts but can still be refunded at their original price. * **100% discounts refund at \$0.** If an item was fully discounted, the refund amount is \$0. For details on processing returns, see [Processing Returns](https://docs.taxcloud.com/guides/workflows/processing-returns/overview). ## Validation and Error Handling TaxCloud validates discount inputs and returns a `400 Bad Request` error with a message describing the problem. ### Validation Errors The API will return an error in the following cases: | Scenario | Behavior | | ----- | ----- | | Negative percentage value | Invalid discount value | | Percentage value greater than 1.0 | Invalid discount value | | Negative amount value | Invalid discount value | | Unknown discount type (not `percentage` or `amount`) | Invalid discount type | | Line-item discount references a non-existent item ID | Item not found | | Line-item discount references an `itemId` that appears on more than one line, without `cartItemIndex` | Item appears on multiple lines | | Line-item discount applied to an excise tax item | Excise tax items cannot be discounted | | Amount discount would make a price negative | Price cannot be negative after discount | | All items are excluded (shipping or excise tax only) and an order-level `amount` discount is applied | No eligible items for discount | ### Capping Behavior In some cases, TaxCloud adjusts the discount rather than returning an error: * **Order-level amount exceeds subtotal:** The discount is capped at 100% of the eligible subtotal. All eligible items are set to $0.00. * **100% percentage discount:** Valid. All eligible items are set to $0.00. ## Migrating from Manual Discount Handling If your integration previously handled discounts by pre-calculating discounted prices before sending them to TaxCloud, or by using negative line items as implicit discounts, here's what you need to know from the January 2026 release: ### Negative Line Items Are No Longer Supported The API now enforces a minimum price of `0` on all line items. Requests containing negative prices will be rejected with a validation error. If you previously used negative line items to represent order-level discounts, replace them with `discounts.orderDiscount`. **Before (no longer supported):** ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "price": 100.00, "quantity": 1, "tic": 0 }, { "index": 1, "itemId": "DISCOUNT", "price": -10.00, "quantity": 1, "tic": 0 } ] } ``` **After (use the discounts field):** ```json { "lineItems": [ { "index": 0, "itemId": "SKU-1001", "price": 100.00, "quantity": 1, "tic": 0 } ], "discounts": { "orderDiscount": { "type": "amount", "value": 10.00 } } } ``` ### Pre-Calculated Discounts Still Work If you prefer to continue pre-calculating discounted prices in your integration code and submitting the reduced price directly, that approach still works. Simply send the already-discounted price in the `price` field and leave out the `discounts` field. In that case, `originalPrice` in the response matches the discounted price you sent, and you are responsible for maintaining your own pre-discount price records. Using the native discount fields is recommended because: * TaxCloud automatically handles TIC-based exclusion rules * Original prices are preserved for audit trails * Refund calculations are handled correctly without additional logic on your side * Discount distribution for order-level discounts uses banker's rounding for precision ## Best Practices * **Use the native discount fields** rather than pre-calculating discounted prices, especially for order-level discounts where proportional distribution and TIC exclusions apply. * **Apply line-item discounts for shipping** if you need to discount shipping costs. Order-level discounts automatically skip shipping items. * **Don't send line-item discounts on excise tax items.** Order-level discounts skip them automatically, but a line-item discount on one is rejected with a `400` error. * **Check the `originalPrice` field** in the response if you need to display or record the pre-discount price for customer receipts or accounting. * **No special handling needed for refunds** — submit the refund normally and TaxCloud will use the correct discounted amounts. * **Be aware of rounding on very small prices.** Banker's rounding on items priced at \$0.01 or \$0.02 can cause small discounts to round away. This is expected behavior. * **Handle the all-excluded error case** if your orders could contain only shipping or excise tax items. Applying an order-level `amount` discount when no eligible items exist returns an error. ## Rounding and Precision All discount calculations are performed with high precision, and final prices are rounded to 2 decimal places (cents) using banker's rounding (round half to even). Banker's rounding differs from standard rounding when a value falls exactly on the halfway point. Instead of always rounding up, it rounds to the nearest even number, which reduces cumulative rounding bias across many transactions. **Examples:** | Calculation Result | Rounded Price | Reason | | ----- | ----- | ----- | | $66.6633 | $66.66 | Not halfway, rounds normally | | $0.004 | $0.00 | Not halfway, rounds down | | $0.005 | $0.00 | Exactly halfway, rounds to even ($0.00) | | $0.006 | $0.01 | Not halfway, rounds up | | $0.015 | $0.02 | Exactly halfway, rounds to even ($0.02) | | $0.025 | $0.02 | Exactly halfway, rounds to even ($0.02) | **Minimum price rules:** * Prices that round to \$0.00 are allowed when the result comes from a legitimate discount calculation (e.g., a 50% discount on a \$0.01 item) or from a 100% discount. * In rare cases, a very small discount may effectively disappear due to rounding. For example, a 40% discount on a \$0.01 item calculates to \$0.006, which rounds back up to \$0.01.