This endpoint is called by the channel to validate a customer's request to use their cash wallet balance as a discount on the current order.
Purpose: To confirm the customer's eligibility for the requested wallet amount and retrieve the final, valid discount object to be applied to the order.
Expectation: The endpoint will return a list of applicable discounts for successful validation or a list of validation errors.
Wallet Validation Payload
This schema defines the complete request body sent to the wallet validation webhook. It combines account and session context with the customer's specific request for applying a wallet balance to the current order.
| Field | Type | Required | Description |
|---|---|---|---|
sessionId | string | No | A unique session token linking all related loyalty actions (e.g., retrieve, validate, create order). |
order | object | Yes | See Order schema 🔗 |
wallet | object | Yes | The customer's request detailing the amount they wish to redeem from their wallet. See WalletUsageRequest below. |
Nested Schema: WalletUsageRequest
WalletUsageRequestThis object details the specific amount the customer wishes to use from their wallet.
| Field | Type | Required | Description |
|---|---|---|---|
type | string (enum) | Yes | The type of wallet being used. Currently, only "cash" is supported. |
amount | number | Yes | The amount to be used from the wallet. This value must be greater than zero. |
Wallet Validation Response
This is the top-level object returned by the /wallet/validate webhook. It should contains the resulting discounts and any errors encountered during the validation process.
Field | Type | Required | Description |
|---|---|---|---|
|
| No | A list of errors encountered during validation. This array is empty if validation is successful. See |
|
| No | A list of validated You can find the schema details in the Discount Schema page 🔗 |
Wallet Validation Error (ValidationError)
ValidationError)This object provides specific details about a validation failure.
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | A human-readable message explaining the reason for the validation failure. |
code | string (enum) | Yes | A machine-readable error code identifying the type of failure. See ValidationErrorCodes below. |
Wallet Validation Error Codes (ValidationErrorCodes)
ValidationErrorCodes)This enum lists the standardized error codes for wallet validation failures.
| Code | Value | Description |
|---|---|---|
| Insufficient Balance | insufficient_balance | The customer's available wallet balance is less than the requested amount. |
| Invalid Input Amount | invalid_input_amount | The requested amount violates internal business rules (e.g., amount is zero, negative, or exceeds a maximum cap). |
Endpoint Behavior and Logic
The channel's actions are defined by four distinct stages:
1. Initial Request (First Application)
This occurs when a customer first attempts to apply a wallet amount to the order.
- Channel Action: Sends the desired wallet amount in the
walletobject and an emptyorder.discountsarray. - API Response: Returns a single discount object on success, or an error message on failure.
Example Request Payload
{
"sessionId": "test",
"order": {
"accountId": "6798b2b2a030bcf7dd6c1ee0",
"channelLinkId": "684940251579e410c7792352",
"locationId": "684940131579e410c7792348",
"orderType": 2,
"paymentAmount": 0,
"customer": {
"email": "[email protected]",
"phoneNumber": "+32474081356",
"loyaltyProviderCustomerId": "88017991",
"name": "John Doe"
},
"items": [
{
"plu": "3726",
"name": "Sisi No Bubbles mango",
"price": 10000,
"quantity": 1,
"subItems": []
}
],
"subTotal": 10000,
"discounts": [],
"decimalDigits": 2,
"serviceCharge": 0,
"deliveryCost": 0,
"bagFee": 0,
"tip": 0,
"driverTip": 0,
"smallOrderFee": 0
},
"wallet": {
"type": "cash",
"amount": 500
}
}Example Success Response
{
"validationErrors": [],
"discounts": [
{
"externalId": null,
"provider": "loyalty",
"scope": {
"type": "order"
},
"offer": {
"type": "flat_off",
"value": 500
}
}
],
"maxRedeemableAmount": 1000
}2. Revalidation (Same Amount)
This scenario is an integrity check. The channel sends the currently applied discount in the order.discounts array, and the same amount in the wallet object.
Success Outcome:
Response: Returns no additional discounts ("discounts": []) and no errors.
Channel Action: The existing discount remains valid; no change to the basket is required.
Error Outcome:
Response: Returns a detailed error message (e.g., insufficient_balance).
Channel Action: The current discount is no longer valid; it must be removed from the basket immediately.
Example Request Payload
{
"sessionId": "test",
"order": {
// Relevant fields only shown for this example.
"discounts": [
{
"type": "wallet_cash",
"provider": "loyalty",
"amount": 500,
"name": null,
"programId": null,
}
],
...,
},
"wallet": {
"type": "cash",
"amount": 500
}
} Example Success Response
{
"validationErrors": [],
"discounts": [],
"maxRedeemableAmount": 1000
}3. Revalidation (Changed Amount)
This occurs when the customer modifies the requested amount. The channel sends the NEW amount in the wallet and the OLD discount in order.discounts.
Success Outcome:
Response: Returns a new discount object based on the new amount.
Channel Action: The channel replaces the existing wallet discount with the new discount object.
Error Outcome:
Response: Returns a detailed error message.
Channel Action: The requested amount is invalid; the channel should prompt the user for a valid amount.
Example Request Payload
{
"sessionId": "test",
"order": {
// Relevant fields only shown for this example.
"discounts": [
{
"type": "wallet_cash",
"provider": "loyalty",
"amount": 500,
"name": null,
"programId": null,
}
],
...,
},
"wallet": {
"type": "cash",
"amount": 1000
}
}
Example Success Response
{
"validationErrors": [],
"discounts": [
{
"externalId": null,
"provider": "loyalty",
"scope": { "type": "order" },
"offer": { "type": "flat_off", "value": 1000 } // NEW discount value
}
],
"maxRedeemableAmount": 1000
}4. Removed Discount (Explicit Removal)
This occurs when the customer explicitly removes the wallet discount. The channel sends a request with the discount present in order.discounts, but sets the wallet field to null.
API Response: Returns no additional discounts ("discounts": []) and no errors.
Channel Action: The channel removes the discount from the basket.
Example Request Payload
{
"sessionId": "test",
"accountId": "6798b2b2a030bcf7dd6c1ee0",
"loyaltyProfileId": "68fa15d0ab58f558a01a77de",
"order": {
// ... order details ...
"discounts": [
{
"type": "wallet_cash",
"provider": "loyalty",
"amount": 500,
"name": null,
"programId": null
}
]
},
"locationId": "684940131579e410c7792348",
"channelLinkId": "684940251579e410c7792352",
"wallet": null // Explicitly signaling discount removal
}Example Success Response
{
"validationErrors": [],
"discounts": [],
"maxRedeemableAmount": 1000
}