Upsell after a completed purchase
Offer extra products to the customer once their purchase is complete. Let Walley Checkout render the upsell inside the iframe, or build your own UI and call Reauthorize.
Auto-activated invoices cannot be upsold. Custom upsell using Reauthorize works for orders with status NotActivated or PartActivated. For in-checkout upsell, see Availability.
Choose your integrationβ
| Option | Who renders the UI | When to pick it |
|---|---|---|
| In-checkout upsell | Walley Checkout iframe | Sweden, credit purchases and Swish on a Walley-managed Swish account. |
| Custom upsell using Reauthorize | Your own post-checkout UI | Credit purchases. Use when you need full control or upsell is decided post-checkout. |
In-checkout upsellβ
In-checkout upsell is only allowed for Checkout sessions that create an order, which is the default. If the session uses a settings profile set up for another purpose, such as subscriptions or identification, sending upsell items is rejected with 400 Bad Request.
How it worksβ
- Pass an
upsell.itemsarray on the Initialize Checkout request. Max 10 items. - The customer completes their purchase as usual.
- On the purchase-completed view, Walley Checkout renders the items as cards (image, description, price, Add button) together with a countdown for the offer's time limit.
- When the customer taps Add, Walley appends the article to the order. For credit purchases the order is reauthorized automatically. For Swish, the customer approves the extra payment in the Swish app. No merchant call required.
- Accepted items appear as extra rows with
type: "Upsell"in the order. Read them from Get Checkout Information underorder.itemsonce the offer has expired.
Availabilityβ
- Country: Sweden (
SE) only. - Payment method: Walley credit purchases, and Swish when the purchase is made on a Walley-managed Swish account.
- Order state: not activated. If the order is auto-activated, no upsell is shown.
If any of the above is not met the upsell block is silently omitted from the completed view β the rest of the checkout is unaffected.
If you activate the order before the time limit has expired, the customer can no longer add items and the offer closes. Wait until the time limit has expired before activating the order, fully or partly.
Before you integrateβ
- Using
redirectPageUri? When it is set, the customer is redirected as soon as the purchase is complete, before the upsell view is shown. The redirect cannot be delayed. To show the upsell, render the checkout again on your redirect page, or leave outredirectPageUri. - No checkout notification is sent when an item is added. Neither the notificationUri callback nor any checkout event fires for upsell. If you subscribe to webhooks, a
walley:order:reauthorizedwebhook is sent each time an item is added. The time limit is the reliable signal: once it has expired, the order can no longer change. Fetch the final order after that. - The
validationUriis not called before an upsell item is added. Stock and price are not re-validated, so only offer items you can deliver at the price you sent.
Adding upsell items at initβ
Extend your existing Initialize Checkout request with an upsell object:
POST /checkouts HTTP/1.1
Host: api.uat.walleydev.com
Authorization: Bearer bXlVc2VybmFtZTpmN2E1ODA4MGQzZTk0M2VmNWYyMTZlMDE...
Content-Type: application/json
{
"storeId": 123,
"countryCode": "SE",
"reference": "123456789",
"merchantTermsUri": "https://example.com/terms",
"notificationUri": "https://example.com/notifications",
"cart": {
"items": [
/* primary cart items */
]
},
"upsell": {
"timeLimitInSeconds": 300,
"items": [
{
"id": "10101",
"description": "Premium gift wrapping",
"quantity": 1,
"unitPrice": 49.0,
"vat": 25.0,
"sku": "GIFTWRAP-PREMIUM",
"imageUrl": "https://cdn.example.com/img/giftwrap.jpg"
},
{
"id": "10102",
"description": "Extended 2-year warranty",
"quantity": 1,
"unitPrice": 199.0,
"vat": 25.0,
"imageUrl": "https://cdn.example.com/img/warranty.jpg"
}
]
}
}
upsell propertiesβ
| Property | Required | Explanation |
|---|---|---|
| items | Yes | The products to offer. See upsell.items[] properties. |
| timeLimitInSeconds | No | How long the offer stays open, counted from purchase completion. Range 60β300, default 300. The customer sees a countdown. Once it has expired, nothing more can be added. Not allowed when items is empty. |
upsell.items[] propertiesβ
| Property | Required | Explanation |
|---|---|---|
| id | Yes | Article id. Max 50 characters. Shown on the invoice. |
| description | Yes | Short product description shown on the upsell card and the invoice. Truncated to 50 characters. |
| quantity | Yes | Allowed values 1β99999999. |
| unitPrice | Yes | Unit price including VAT. Max 2 decimals. Range 0.01β999999.99. |
| vat | Yes | VAT in percent. Max 2 decimals. Range 0β100. |
| imageUrl | Yes | Absolute HTTPS URL to the product image. Max 2048 characters. Rendered in the upsell card. |
| sku | No | Stock Keeping Unit. Max 1024 characters. |
A maximum of 10 upsell items can be sent per checkout.
Updating upsell itemsβ
Upsell items can be changed with Update Checkout until the customer commits to payment. Omit upsell, or send null, to keep the current items. Send "items": [] to clear them. An upsell object without timeLimitInSeconds resets the time limit to 300.
Reading back what the customer acceptedβ
When the customer adds an upsell item, Walley appends it to the order. Once the time limit has expired, Get Checkout Information returns the final order under order.items β accepted upsell rows show up alongside the original cart rows with type set to Upsell:
{
"order": {
"orderId": "...",
"totalAmount": 248.0,
"items": [
/* original cart rows */
{
"id": "10101",
"description": "Premium gift wrapping",
"quantity": 1,
"unitPrice": 49.0,
"vat": 25.0,
"sku": "GIFTWRAP-PREMIUM",
"type": "Upsell"
}
]
}
}
- Each offered item can be bought once.
- Identical offered items (same
id,description,unitPrice,vatandsku) are shown as separate upsell cards. If the customer adds more than one, they are merged into one row inorder.itemswith the summed quantity. - An upsell row is never merged with a cart row, even if they share the same
id.
Accepted items are already on the Walley invoice β no further merchant call is required.
When an upsell failsβ
- Credit purchase denied, for example by the credit check: the item is not added, the original order is unaffected and the offer closes for the rest of the checkout.
- Swish declined or cancelled in the Swish app: the item is not added and the customer is not charged.
No notification is sent in either case. An item missing from order.items is the only signal.
Custom upsell using Reauthorizeβ
Itβs possible to include your own upsell functionality after the purchase is complete in the checkout. This is done with a call to Reauthorize with the added products of the customer's choice or a larger amount than the original.

How to get started πβ
- When the purchase is completed and the checkout information is fetched, it will return an
orderId. - Use the
orderIdfor calling the Reauthorize endpoint, remember to send along all existing article rows with the new upsell articles if you want the old articles to show on the new invoice. If you only want to adjust the amount, sending in an amount is enough. This will return a201or202response depending on if a credit check is needed or not. The response headers will contain aLocationheader with a path to the order. - Use this url path to verify that the order has successfully been reauthorized. In the case where a credit check happens (201), you will need to poll on the endpoint you received in the
Location headerto await that the reauthorize finalizes.