Skip to main content

Simulate and Apply Discounts

Discount simulation lets a retailer use Loyal Guru as a real-time promotion calculator. Before the customer confirms payment, the POS, e-commerce checkout, or mobile app can ask: "Which discounts would apply to this cart right now?"

This helps teams show savings before checkout, validate coupon codes, compare club prices, preview bundle mechanics, and verify whether stackability or limits change the final result. When the cart is confirmed, the same logic is applied with the real-time cart endpoint.

What you can simulate​

Simulation use caseWhat the response tells you
Automatic discountsWhich mass or club discounts apply without a code
Coupons and vouchersWhether the submitted code is valid and which discount it unlocks
Bundles and BOGOWhether the cart contains enough items to form each group
StackabilityWhich campaigns win, stack, or are excluded by priority
LimitsWhether campaign caps, per-customer frequency, or per-transaction caps affect the result
Client vs LG calculationWhether Loyal Guru modifies cart line values or only returns applicable promotions

Endpoint summary​

EndpointPurposePersisted?
POST /carts/simulatePreview discounts before payment confirmationNo
POST /carts/realtimeApply discounts to a confirmed cartYes

Both endpoints use the same cart payload. The main difference is persistence: simulation returns the same kind of promotional answer but does not save the cart or consume vouchers.

Control discount application​

Use apply_discounts to decide who performs the final price calculation:

ValueBehavior
trueLoyal Guru calculates the discount and returns adjusted cart values and effects[].
falseLoyal Guru returns which discounts apply, but the client system keeps responsibility for final price calculation.
omittedThe company-level default configuration is used.

Use apply_discounts: true when Loyal Guru is the promo engine. Use apply_discounts: false when the POS or e-commerce system must calculate prices locally but still wants Loyal Guru to evaluate eligibility, coupons, vouchers, and campaign rules.

Control coupon and voucher application​

Discount campaigns that are mass or loyalty-member promotions and do not require a coupon are included by default in every discount calculation. Use coupons_desired to decide which coupon-gated or voucher-gated discounts should also be evaluated.

coupons_desired valueDiscount behavior
"all"Apply all mass and loyalty-member discounts without coupon, plus all vouchers assigned to the customer.
"selected"Apply all mass and loyalty-member discounts without coupon, plus only vouchers previously selected by the customer through the voucher selection flow.
["SUMMER25", "34433"]Apply all mass and loyalty-member discounts without coupon, plus the listed static coupon codes or unique voucher codes.
[] or omittedApply only mass and loyalty-member discounts without coupon. No specific voucher or coupon is requested.

This is how simulation can answer questions like "what happens if the customer applies this code?" or "what happens if all customer vouchers are considered?" The old vouchers_desired naming is deprecated; use coupons_desired.

When a coupon has auto redeem enabled, the customer does not need to manually type the code in the checkout experience. The cart request still decides the evaluation scope with coupons_desired: all assigned vouchers, selected vouchers, explicit codes, or no requested voucher.

Simulate a discount​

POST /carts/simulate
X-Api-Key: your_api_key
X-Api-Secret: your_api_key_secret
X-Api-Version: 1
Content-Type: application/json
{
"id": 20260702002,
"customer_id": 1042,
"currency": "EUR",
"country": "ES",
"location_id": 12,
"apply_discounts": true,
"apply_points": false,
"coupons_desired": ["SUMMER25"],
"total": 42.80,
"lines": [
{
"product_id": "SKU-COFFEE-250",
"product_code": "COFFEE250",
"quantity": 2,
"unit_price": 6.50,
"total": 13.00,
"categories": ["beverages"]
},
{
"product_id": "SKU-CEREAL-500",
"product_code": "CEREAL500",
"quantity": 1,
"unit_price": 4.80,
"total": 4.80,
"categories": ["breakfast"]
}
]
}

To simulate every assigned voucher for the customer, use:

{
"id": 20260702002,
"customer_id": 1042,
"apply_discounts": true,
"coupons_desired": "all",
"total": 42.80,
"lines": [...]
}

Example response:

{
"id": 20260702002,
"apply_discounts": true,
"total": 36.50,
"effects": [
{
"rule_id": 3210,
"rule_name": "Club beverage discount",
"type": "discount",
"effectType": "percentage",
"distribution_type": "individual_items",
"value": -1.30,
"line": 1
},
{
"rule_id": 3399,
"rule_name": "SUMMER25 coupon",
"type": "discount",
"effectType": "direct_value",
"value": -5.00,
"coupon_info": {
"coupon_name": "SUMMER25",
"voucher_code": "SUMMER25"
}
}
]
}

Apply the discount to a confirmed cart​

When the customer pays, submit the same cart to POST /carts/realtime.

POST /carts/realtime
X-Api-Key: your_api_key
X-Api-Secret: your_api_key_secret
X-Api-Version: 1
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

Use an Idempotency-Key when the POS or e-commerce checkout may retry after a timeout. This prevents the same cart from being processed twice.

How to read effects[]​

FieldMeaning
rule_idDiscount campaign that produced the effect
rule_nameCampaign name
effectTypePercentage, direct value, combo price, etc.
distribution_typeHow the discount is distributed across the cart
lineCart line affected, when the effect applies to a specific line
coupon_infoCoupon or voucher details, when a code was involved

If effects[] is empty, no discount qualified for that cart. Check audience, dates, currency, country, coupon/voucher code, conditions, limits, and stackability.