Skip to main content

Incentives in order data

When an incentive rule fires, the result is written into the order's items array rather than into a separate discounts block. A discount on a line arrives as its own order line with a negative amount. An integration that books only product lines, or that treats every entry in items as a purchasable product, gets the order wrong.

Line classes​

Every order item carries a class:

ClassWhat it isCounts toward the order total
productA real line. Either something the customer added or a product a rule addedYes, at its price before any incentive
incentiveThe adjustment a rule made to one product line, as a negative amountYes, it lowers the total
surchargeAn additional fee such as handling or a small order feeYes

An incentive line always has productId: null and a parentOrderItemId pointing at the product line it adjusts. A product line has at most one incentive line.

A product added by a rule keeps class: product. It is a real, orderable line at its normal price. What marks it as given rather than chosen is isBonus: "Y", and its incentive line brings it down to what the customer pays.

What a rule produces​

Take an order where a rule gives 20% off two of the three products the customer added. The order has five items:

idclassparentOrderItemIdquantitypricepriceTotalWhat it is
14810productnull32060A product the rule covers
14811incentive148103-4-12The 20% off line 14810
14812productnull21530A second product the rule covers
14813incentive148122-3-6The 20% off line 14812
14814productnull144A product the rule does not cover

The lines add up to 76: 94 for the products and -18 for the incentives. The order total is that amount plus shipping and payment costs.

A rule that adds a free product produces two lines:

idclassparentOrderItemIdisBonusquantitypricepriceTotalWhat it is
14821productnullY13030The product the rule added, at its normal price
14822incentive14821Y1-30-30The adjustment that makes it free

Reading an incentive line​

{
"id": 14811,
"class": "incentive",
"productId": null,
"parentOrderItemId": 14810,
"sku": "discount_percentage",
"name": "20% off ear protection",
"quantity": 3,
"originalPrice": -4,
"price": -4,
"priceTotal": -12,
"customerPrice": 0,
"isBonus": "N"
}
FieldMeaning on an incentive line
skuThe kind of adjustment, not a product code. See the next table
nameThe name given to the rule's action that produced it
priceThe adjustment per piece. Negative, so -4 means four off each piece
quantityThe pieces the adjustment applies to. Usually the quantity of the product line, but a "3 for 2" rule counts only the free pieces, for example 1 on a line of 3
priceTotalprice times quantity: the amount the line takes off the order
parentOrderItemIdThe product line this adjustment applies to
productIdAlways null
customerPriceAlways 0
skuProduced by
discount_percentageA percentage discount on the line
discountA fixed amount off each piece
freePieces the customer gets for free, such as the cheapest piece in a "3 for 2" or a product a rule added at price 0
set_priceA product a rule added at a set price. price is the set price minus the normal price, so a product that normally costs 30, added at 5, gives -25

The product line keeps its price before the incentive. Line 14810 above carries price: 20 and priceTotal: 60. The customer pays 48 for it: the 60 of the product line plus the -12 of its incentive line.

When two rules adjust the same product line, the order keeps the adjustment of the rule that was created last. Rules that adjust different lines each produce their own incentive line.

A discount on the order total does not produce a line. It is in total.discountType (P for a percentage, A for an amount) and total.discountValue, and it is already taken off the order total.

The product line's own discount field is not the incentive. It is originalPrice minus price plus the incentive per piece, so it also contains any difference between the product's list price and the customer's price. Read the adjustment from the incentive line.

What integrations should do​

Read class before anything else. Handle each class you know and stop with an error on a class you do not know. An ERP export, invoice, picking list or analytics feed that skips lines it does not recognize can silently change what the order is worth.

Book incentive lines, do not skip them. The discount exists only on the incentive line. For the amount the customer pays for a product line, add the priceTotal of its incentive line, matched on parentOrderItemId, to the product line's priceTotal. Alternatively, book the incentive line as a discount line of its own in the receiving system. Skipping it books the order at full price.

Keep surcharges. Surcharges are real charges the customer pays. Filtering to class == "product" alone silently drops them.

Send bonus products to the warehouse. A line with isBonus: "Y" and class: product is physical stock that has to be picked and shipped. Its incentive line is not.

Do not match incentive lines on sku. The field holds the kind of adjustment, so it collides with product SKU lookups.

Use parentOrderItemId to attribute a discount. It is the only link between an adjustment and the line it applies to.

See also​