Skip to content

Upsell on Confirmation Page


This page explains how to enable and integrate the Kustom Upsell feature, which displays product recommendations on the order confirmation page after a purchase is completed.

Upsell must be enabled for your merchant account before use. Contact Kustom to activate it.

Overview

Upsell lets you present product recommendations to shoppers immediately after they complete a purchase. Because payment is already authorized, shoppers can add items to their existing order with a single tap — no re-entering payment details.

Kustom handles the UI widget, payment authorization increase, and order updates. You control what products are shown and when.

Enabling upsell

Enable per order

Set options.confirmation_page_upsell to true when creating a checkout order. This is the recommended approach for A/B testing or selective rollout.

{
  "options": {
    "confirmation_page_upsell": true
  }
}

The flag can be updated on the order until it reaches status checkout_complete.

Enable for all sessions (global)

Kustom can enable upsell at the merchant ID level so all eligible sessions show the widget without any per-order flag. You can still override per order using options.confirmation_page_upsell: false.

Contact Kustom to enable global activation.

When upsell is not applicable — for example if it is disabled or the payment method is unsupported — the confirmation push fires immediately with no delay to your existing flow.

Choosing a recommendation engine

Kustom supports two recommendation modes.

Provide a Google Shopping feed URL and Kustom handles enrichment, model training, and serving. No merchant_urls.upsell endpoint is needed.

ParameterDetails
Feed formatGoogle Shopping XML or CSV — public URL
Sync frequencyEvery 2–4 hours
One feed perMarket / currency pair (e.g. SE-SEK, DE-EUR)
Recommended filtermin_stock=50 to avoid out-of-stock recommendations

The AI model works from day one without historical data and improves with every interaction.

Your own endpoint

Set merchant_urls.upsell to your recommendation endpoint. Kustom calls it before the confirmation page loads and you return the list of products to display.

{
  "merchant_urls": {
    "upsell": "https://www.example.com/api/upsell"
  }
}

Your endpoint must respond within 2–3 seconds. A slow or failed response results in no widget being shown and the push notification fires immediately.

The sections below on request/response structure apply only when using your own endpoint.

Upsell callback

When merchant_urls.upsell is set, Kustom sends a POST request to that URL before the confirmation page loads.

Request — upsell_request

FieldTypeDescription
upsell_possiblebooleanfalse if the payment method does not support upsell.
max_upsell_amountintegerMaximum additional amount that can be authorized, in minor units. Pre-filter your recommendations by this value.
order_linesarrayCurrent items in the order.
selected_shipping_optionobjectThe shipping option selected by the customer. Use to filter out items that would break the selected shipping method.
billing_addressobjectUse for tax rate and locale-aware filtering.
shipping_addressobjectUse for tax rate and locale-aware filtering.
purchase_currencystringISO 4217 (e.g. SEK, EUR, USD).
localestringRFC 1766 (e.g. sv-SE, en-US).
merchant_idstringYour merchant ID.
session_idstringThe order/session ID. Use to map the request to your internal order model.

The callback is made even when upsell_possible is false. Return an empty upsell_lines[] array in that case to short-circuit.

These fields enable you to:

  • Price products correctly based on purchase_currency and locale
  • Apply correct tax rates based on billing_address / shipping_address
  • Pre-filter candidates using the max_upsell_amount authorization headroom
  • Consider shipping compatibility via selected_shipping_option

Response — upsell_service_response

FieldTypeRequiredDescription
upsell_linesarrayYesList of products to display. Return an empty array to show no widget.
last_upsell_timestringNoISO 8601 datetime when the upsell window expires. If omitted, Kustom uses the MID-level timeout.
notification_uristringNoURL for push notifications when the order is updated with upsell items. Use as a trigger to re-read the order from the Order Management API (Method 1).
emptybooleanNoSignal no upsell without returning lines.

Upsell line fields — upsell_line

Required fields:

FieldTypeDescription
namestringProduct name (max 255 characters).
quantityintegerDefault offered quantity. See note below.
unit_priceintegerMinor units, includes tax.
tax_rateintegerTwo implicit decimals. 2500 = 25%.
total_amountintegerMinor units, includes tax and discount. Must equal unit_price × quantity.
total_tax_amountintegerMinor units.
max_allowed_quantityintegerMaximum quantity the shopper can add.

Strongly recommended fields:

FieldDescription
referenceSKU or article number.
image_urlProduct card image URL (max 1024 characters). Required to render product cards.
product_urlLink to the product page (max 1024 characters).
descriptionProduct description (max 1024 characters).
product_identifiersProduct identifiers such as GTIN or ISBN.
shipping_attributesWeight, dimensions, and tags for shipping compatibility checks.
feedback_urlItem-level signal URL called when a shopper adds the item.
Number validation

unit_price × quantity must equal total_amount. Kustom re-validates and recalculates when a shopper adds an item.

Understanding the quantity field

quantity is the default offer quantity you are proposing, not the shopper's final selection. If you are unsure, set quantity: 1 and control the upper bound via max_allowed_quantity. Kustom recalculates totals and re-validates authorization when the shopper adds items.

{
  "name": "Matching Phone Case",
  "quantity": 1,
  "unit_price": 19900,
  "max_allowed_quantity": 5,
  "tax_rate": 2500,
  "total_amount": 19900,
  "total_tax_amount": 3980
}

Example response

{
  "upsell_lines": [
    {
      "name": "Baseball Cap",
      "reference": "CAP-SAND-001",
      "quantity": 1,
      "unit_price": 40000,
      "tax_rate": 2500,
      "total_amount": 40000,
      "total_tax_amount": 8000,
      "max_allowed_quantity": 3,
      "image_url": "https://www.example.com/images/cap-sand.jpg",
      "product_url": "https://www.example.com/products/cap-sand"
    }
  ],
  "last_upsell_time": "2024-01-01T12:05:00Z"
}

Upsell validation callback (optional)

Set merchant_urls.upsell_validation to control whether a specific item add is allowed before Kustom processes it. This callback is not required — by default, items are added without a validation callback.

{
  "merchant_urls": {
    "upsell_validation": "https://www.example.com/api/upsell-validation"
  }
}

The request body is the same as the standard order API model, with one addition: upsell_order_lines, which contains the list of upsell lines being requested for addition. The model is the same as order_lines.

Return 2xx to allow the add. Any other status code blocks it.

Do not rely on this callback as the final confirmation. The payment authorization increase can still fail after this callback returns. Use the confirmation push to finalize the order state.

Integration methods

Because items can be added after the initial payment, you need to decide how your backend handles order creation. There are two approaches.

Integration methods for upsell on confirmation page

Method 1 — Create on redirect

Create the order immediately when the shopper is redirected to the confirmation page, then accept updates as items are added.

  1. Payment is authenticated — KCO marks the checkout order as CHECKOUT_COMPLETE.
  2. KCO redirects to your confirmation page URL.
  3. Your backend reads the order and creates it in your system, placed on hold.
  4. You load the KCO confirmation iframe.
  5. KCO calls merchant_urls.upsell to fetch recommendations.
  6. Shopper adds items — KCO triggers the upsell validation callback if configured, increases authorization, and updates the order.
  7. Upsell timeout expires — KCO sends the confirmation push.
  8. Your backend reads the final order state and releases the hold for fulfilment.

Best for merchants who need immediate order visibility in their systems or who handle high-value items where instant inventory reservation is critical.

Fulfilment timing

The order must be updatable during the upsell timeout window. Do not send it to your warehouse or trigger confirmation emails until the confirmation push arrives.

Do not create the order in your system until the confirmation push arrives. This avoids mid-session order modifications entirely.

  1. Payment is authenticated — KCO marks the checkout order as CHECKOUT_COMPLETE.
  2. KCO redirects to your confirmation page URL.
  3. Your backend reads the order but does not create it yet.
  4. You load the KCO confirmation iframe.
  5. KCO calls merchant_urls.upsell to fetch recommendations.
  6. Shopper adds items — KCO handles authorization and updates the order.
  7. Upsell timeout expires — KCO sends the confirmation push with the final order_lines.
  8. Your backend creates the order once from the push payload.

Best for most integrations — simpler logic, no order modification needed, faster go-live.

Determining which flow applies

The confirmation push is only delayed if upsell is enabled for the session and the payment method supports upsell. If either condition is false, the push fires immediately — you do not need to wait.

You can determine whether upsell is active by:

  • Checking options.confirmation_page_upsell on the order object
  • Observing the upsell_possible field in the upsell callback request
  • Checking whether the upsell widget appears in the iframe

Payment method support

Payment methodUpsell supported
CardYes
Klarna BNPL / Pay LaterYes
SwishNo
Direct bank transferNo

When upsell_possible is false, the widget is not shown and the push fires immediately with no change to your existing flow.

Kustom can increase Klarna authorization limits on a per-merchant basis. Contact Kustom to discuss your limits. Use max_upsell_amount in your recommendations endpoint to pre-filter products to amounts that can be authorized.

Upsell timeout

The upsell window is configured at the merchant ID level by Kustom, with a maximum of 15 minutes. The timeout cannot be set via the API — contact Kustom to configure your preferred duration.

Upsell is compatible with the minimal_confirmation GUI option. The upsell widget overrides it automatically when upsell is enabled.

Shipping and upsell

The upsell_request always includes selected_shipping_option when available. Use this to filter out recommendations that would break the selected shipping method.

Use shipping_attributes on your upsell lines to specify weight, dimensions, and tags. This is the recommended way to ensure suggestions are compatible with the selected shipping method.

{
  "shipping_attributes": {
    "weight": 500,
    "dimensions": {
      "width": 100,
      "height": 150,
      "length": 200
    },
    "tags": ["standard", "non-fragile"]
  }
}

Shipping information is only included in the upsell request if you use Kustom Shipping Assistant. Without it, selected_shipping_option will not be present.

If your shipping platform requires re-rating after cart changes (for example when using a third-party TMS), you have two options:

  • Pre-filter (recommended): Perform a soft compatibility check in your upsell endpoint before returning candidates. Only propose items that keep the current shipping method valid.
  • Post-upsell re-rate: After an upsell is accepted, re-rate and handle any method changes per your policy. You can optionally use the shipping_option_update callback for this.

Tracking upsold items

Compare order_lines in the original checkout order with order_lines in the final confirmation push to identify which items were added via upsell. Use feedback_url on each upsell_line for item-level add signals.

Recommendations are fetched once before the confirmation page loads and cannot be refreshed during the upsell window. Return your best candidates in the initial response.

FAQ

What does the quantity field mean in upsell_line?

It is the default offer quantity you are proposing, not the shopper's final selection. Set quantity: 1 and use max_allowed_quantity to control the upper bound. Kustom recalculates totals and re-validates authorization when the shopper adds items.

When should we create the order — on redirect or after the push?

Both are supported. Method 2 (create on push) is simpler for most integrations. Method 1 (create on redirect) is better when immediate inventory reservation is required. See Integration methods above.

How do we know if we should wait for a delayed push?

The push is only delayed if upsell is enabled and the payment method supports it. Check options.confirmation_page_upsell on the order or the upsell_possible field in the upsell request.

What happens if our upsell endpoint is slow or times out?

The confirmation page loads normally, the upsell widget is not shown, and the push fires immediately. Optimize your endpoint to respond within 2–3 seconds.

Can we A/B test recommendation variants?

Yes. You can swap your merchant_urls.upsell endpoint at any time to test variants against each other or against the Kustom AI engine.

Can we show free shipping thresholds in the widget?

No. Real-time free shipping threshold tracking within the upsell widget is not currently supported. Handle threshold logic on your side when processing the final order after the push.

What happens if the upsell amount exceeds the authorization?

Kustom validates authorization when the shopper adds items and blocks additions that exceed the limit. Pre-filtering your recommendations by max_upsell_amount improves conversion by avoiding recommendations that will be blocked.

How do we track which items were upsold?

Compare the original order_lines with the final order_lines from the confirmation push. Use feedback_url on upsell lines for item-level add signals.

API reference