Handling Discounts in Walley Checkoutβ
This guide describes how discounts can be represented in Walley Checkout and how they should be handled when refunding orders. You will find:
- Overview of approaches for different discount models
- Comparison matrix to choose the right model
- Clear end-to-end JSON examples for checkout and refund
Overview of Approachesβ
Walley supports multiple ways to handle discounts in checkout:
| Approach | Description | When to use |
|---|---|---|
| Explicit discount item | Represent discounts as a separate negative cart item | Most flexible; recommended for most campaigns |
| Campaign cases | Standard patterns like Buy 3 Pay for 2, percent discounts | Use explicit discount items and refund recalculation |
| Simple discount (adjusted price) | Discount is baked into the product price | Quick + simple, minimal refund needs |
Comparison Matrixβ
| Criteria | Explicit discount item | Simple discount |
|---|---|---|
| Transparency | β Customer sees discount item | β οΈ Only visible in item description |
| Refund flexibility | β Fully controllable | β Fully controllable |
| Partial refunds | β Supported | β Supported |
1. Explicit Discount Item (Recommended)β
Checkoutβ
A discount item is a cart item with a negative unitPrice that represents the discount amount. Add the discount item to the cart alongside regular products.
"cart": {
"items": [
{
"id": "item-001",
"description": "Cool T-shirt",
"unitPrice": 250,
"quantity": 1,
"vat": 25
},
{
"id": "discount-SPRING",
"description": "Spring campaign discount",
"unitPrice": -50,
"quantity": 1,
"vat": 25
}
]
}
Full Refundβ
POST /manage/orders/{orderId}/refund
{
"amount": 200,
"actionReference": "refund-spring-discount",
"items": [
{
"id": "item-001",
"description": "Cool T-shirt",
"unitPrice": 250,
"quantity": 1,
"type": "purchase"
},
{
"id": "discount-SPRING",
"description": "Spring discount refund",
"unitPrice": -50,
"quantity": 1,
"vat": 25,
"type": "discount"
}
]
}
2. Partial Refund β Buy 3, Pay for 2 (Explicit Discount)β
This section describes how to model a Buy 3, Pay for 2 campaign using an explicit discount item, and how to correctly perform a partial refund.
Original order (Checkout)β
Scenario:
- 3 products
- Price per product: 100 SEK
- Buy 3, Pay for 2 discount: negative 100 SEK
- Amount paid by customer: 200 SEK
Checkoutβ
All products are sent with their full price, and the campaign is represented as a separate discount item.
"cart": {
"items": [
{
"id": "item-001",
"description": "Product A",
"unitPrice": 100,
"quantity": 1,
"vat": 25
},
{
"id": "item-002",
"description": "Product B",
"unitPrice": 100,
"quantity": 1,
"vat": 25
},
{
"id": "item-003",
"description": "Product C",
"unitPrice": 100,
"quantity": 1,
"vat": 25
},
{
"id": "discount-B3P2",
"description": "Buy 3, pay for 2 discount",
"unitPrice": -100,
"quantity": 1,
"vat": 25
}
]
}
Partial refund (2 items returned)β
Refund logic:
The customer returns 2 out of 3 items.
Refund calculation:
- Refund products: 2 multiplied by 100 SEK = 200 SEK
- Apply adjusted discount: negative 100 SEK
- Net refund amount: 100 SEK
The refund must reflect the net amount paid for the returned items.
Refund requestβ
POST /manage/orders/{orderId}/refund
Authorization: Bearer <token>
Content-Type: application/json
{
"amount": 100,
"actionReference": "partial-refund-buy3pay2",
"items": [
{
"id": "item-001",
"description": "Product A",
"unitPrice": 100,
"quantity": 1,
"type": "purchase"
},
{
"id": "item-002",
"description": "Product B",
"unitPrice": 100,
"quantity": 1,
"type": "purchase"
},
{
"id": "discount-B3P2",
"description": "Buy 3, pay for 2 discount (adjusted)",
"unitPrice": -100,
"quantity": 1,
"vat": 25,
"type": "discount"
}
]
}
Result:
- plus 200 SEK refunded for products
- minus 100 SEK discount applied
- Customer receives 100 SEK
- The discount remains negative during refunds
type: "discount"is required for discount items in refunds- The
amountmust equal the sum of all refund items - Walley does not recalculate discounts β the merchant must adjust the discount item manually
3. Percentage Discounts with Explicit Discount Itemsβ
Checkout (10 Percent on 3 Multiplied by 100)β
"cart": {
"items": [
{ "id": "item-001", "description": "Product A", "unitPrice": 100, "quantity": 1, "vat": 25 },
{ "id": "item-002", "description": "Product B", "unitPrice": 100, "quantity": 1, "vat": 25 },
{ "id": "item-003", "description": "Product C", "unitPrice": 100, "quantity": 1, "vat": 25 },
{ "id": "discount-10pct", "description": "10 percent discount", "unitPrice": -30, "quantity": 1, "vat": 25 }
]
}
Partial Refund (2 items returned, refund amount 180)β
POST /manage/orders/{orderId}/refund
{
"amount": 180,
"actionReference": "partial-refund-10pct",
"items": [
{ "id": "item-001", "description": "Product A", "unitPrice": 100, "quantity": 1, "type": "purchase" },
{ "id": "item-002", "description": "Product B", "unitPrice": 100, "quantity": 1, "type": "purchase" },
{ "id": "discount-10pct", "description": "10 percent discount (original)", "unitPrice": -30, "quantity": 1, "vat": 25, "type": "discount" },
{ "id": "discount-10pct-adj", "description": "10 percent discount (remaining)", "unitPrice": 10, "quantity": 1, "vat": 25, "type": "discount" }
]
}
Explanation:
- Original discount refunded: negative 30
- Remaining discount added back: plus 10
- Net discount: negative 20, which results in amount 180
4. Simple Discount (Price Already Adjusted)β
Discount is reflected directly in product price β no dedicated discount item.
Checkout Example (10 Percent Simple)β
"cart": {
"items": [
{
"id": "item-001",
"description": "Product A (10 percent discount applied)",
"unitPrice": 90,
"quantity": 1,
"vat": 25
}
]
}
Simple "Buy 3 Pay 2"β
"cart": {
"items": [
{ "id": "item-001", "description": "Product A (Buy 3 Pay 2)", "unitPrice": 100, "quantity": 1, "vat": 25 },
{ "id": "item-002", "description": "Product B (Buy 3 Pay 2)", "unitPrice": 100, "quantity": 1, "vat": 25 },
{ "id": "item-003", "description": "Product C (Buy 3 Pay 2 β discounted)", "unitPrice": 0, "quantity": 1, "vat": 25 }
]
}
Refund with Simple Discountβ
POST /manage/orders/{orderId}/refund
{
"amount": 90,
"actionReference": "refund-simple-discount",
"items": [
{ "id": "item-001", "description": "Product A (10 percent discount applied)", "unitPrice": 90, "quantity": 1, "type": "purchase" }
]
}
Best Practicesβ
- Use explicit discount items for campaigns and complex refunds.
- Use simple discount when discount logic is internal and refund patterns are trivial.
- Always align VAT correctly for both items and discount items.
- Recalculate discount for partial refunds and represent in refund request.
See Alsoβ
- Initialize Checkout - Setup checkout sessions with cart items
- Order Management API - Capture, refund, cancel orders
- Inventory Validation Use Case - Another callback example
- Simple Payment Flow - Complete payment lifecycle