New Engine Promo Engine
Use this model when Loyal Guru must evaluate discount campaigns and return the final discount amounts that the POS or e-commerce checkout applies to the receipt.
Responsibilitiesβ
| System | Responsibility |
|---|---|
| Loyal Guru | Evaluates active campaigns, coupons, vouchers, stackability, limits, customer eligibility, product/store scope, and returns calculated effects[]. |
| POS / e-commerce | Sends the cart with complete line, store, customer, payment, and coupon data; displays the returned discounts; confirms or cancels the transaction. |
End-to-end flowβ
Runtime endpointsβ
| Step | Endpoint | Purpose |
|---|---|---|
| Preview | POST /carts/simulate | Calculates discounts and points without persisting the cart or consuming vouchers. |
| Confirm | POST /carts/realtime | Persists the cart, commits effects, and updates voucher/coupon usage. |
| Cancel | POST /carts/cancellation | Rolls back the confirmed cart effects. Wait at least 5 minutes after the original cart creation. |
Cart requestβ
Send apply_discounts: true when Loyal Guru must calculate and return final discount values.
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
{
"id": 202607090001,
"customer_id": 123456,
"apply_discounts": true,
"apply_points": true,
"total": 45.0,
"country": "ES",
"location_id": 1001,
"payment_method": "visa",
"coupons_desired": ["SUMMER20"],
"lines": [
{
"product_id": 10045,
"product_code": "CC-33CL-LATA",
"quantity": 3,
"unit_price": 1.5,
"total": 4.5
}
]
}
Response handlingβ
Read effects[] as the source of truth for the applied promotion result. The POS should not re-calculate the same discount; it should apply or display what the response returns.
{
"effects": [
{
"rule_id": 101,
"type": "discount",
"effectType": "percentage",
"distribution_type": "individual_items",
"discount_value": 2.25,
"line": 0
}
],
"total_discount": 2.25,
"points_earned": 45
}
Implementation notesβ
- Use
POST /carts/simulatefor UI preview andPOST /carts/realtimeonly when the transaction is confirmed. - Use the same cart line identifiers in simulation and confirmation to avoid different eligibility results.
- Send coupon or voucher codes in
coupons_desired; Loyal Guru validates them against campaign, customer, store, dates, limits, and redemption state. - Add
Idempotency-Keyfor safe retries ofPOST /carts/realtime. - If payment fails after confirmation, call
POST /carts/cancellationso campaign limits, points, and vouchers are rolled back. - If campaign conditions reference Customer profile fields, use the
attributesobject on the Customer. Legacycustom1βcustom11/custom1fβcustom8ffields are deprecated β see Custom fields β Attributes. - If another POS (online or physical) accepts the same vouchers but is not integrated as Promo Engine, that POS can call
POST /discounts/redeemto burn the code in Loyal Guru and reduce double-redemption fraud. See Vouchers redeem vs Discounts redeem.
Troubleshootingβ
| Symptom | What to check |
|---|---|
| Discount appears in simulation but not in realtime | Cart payload changed between calls, campaign validity window changed, voucher was consumed, or cart ID/idempotency handling differs. |
| Coupon is rejected | Verify coupons_desired, customer identity, voucher status, available redemptions, store scope, date window, and campaign audience. |
| Discount amount differs from POS expectation | In Promo Engine mode, the LG response is authoritative. Check campaign rule_effects, stackability, limits, and line identifiers. |
| Cancellation does not restore a voucher immediately | Verify the original cart ID and wait for asynchronous rollback processing before retrying the same voucher. |