upsell_completed

Once per accepted upsell, when the order is loaded with it.

CODE
next.analytics.on('upsell_completed', (event) => {});

Triggered by order.loaded.

Data

Present: always; optional when it may be missing; campaign once the campaign is loaded; priced once the server priced the cart.

FieldTypePresent
ref_idstringalwaysThe order's reference: ref_id in post-purchase page URLs.
numberstringoptionalThe order number customers see.
currencystringoptionalISO 4217, such as USD.
testbooleanalwaystrue for a test order.
paidbooleanalwaystrue once the order is paid; false while the shopper pays at a gateway.
linesOrderItem[]always
couponsstring[]alwaysThe codes the shopper applied at checkout in this tab, uppercase.
total_discountnumberalwaysThe discounts on the order.
shipping_methodPick<ShippingMethod, "name" | "price"> & { tax?: number }optionalThe shipping method's name, its price, and the tax in that price.
taxnumberalwaysThe tax in the order: its lines' and shipping's.
totalnumberalwaysWhat the shopper paid.
userPick<User, "first_name" | "last_name" | "email" | "phone">optional
shipping_addressAddressoptional
billing_addressAddressoptional
payment_methodstringoptionalThe API's code for the payment method, such as card_token or paypal.
supports_upsellsbooleanalwaystrue when upsells can be added to the order.
status_urlstringoptionalThe order's status page on the store.
upsellobjectalwaysWhich line this upsell added.
upsell.numbernumberalways1 for the first upsell on the order.
upsell.lineOrderItemalways

OrderItem

One line of an order. Prices are numbers in the order's currency, as the shopper paid them.

FieldTypePresent
idstringalwaysThe order line's id.
product_idnumberoptionalThe product in the store.
product_titlestringalwaysThe product's name as customers see it.
variant_idnumberoptionalThe product variant.
variant_titlestringoptionalThe variant's name, such as Black / M.
skustringoptionalThe product's Stock Keeping Unit.
imagestringoptional
quantitynumberalways
pricenumberalwaysWhat one unit cost after discounts.
original_pricenumberalwaysWhat one unit cost before discounts.
totalnumberalwaysWhat the line cost; price is total / quantity, rounded to the cent.
taxnumberalwaysThe tax in total; the line before tax is total − tax.
upsellbooleanalwaystrue for a line an upsell added.

User

The shopper, as the store's user on the Open Cart and the order.

FieldTypePresent
emailstringoptionalAs typed, trimmed; none when data-trigger-on created the user without one.
first_namestringalways
last_namestringalways
phonestringoptionalIn E.164 once the address service read it, else the digits typed.
accepts_marketingbooleanalwaysThe marketing checkbox, as sent with the Open Cart and the order.
languagestringalwaysThe language the store keeps for the shopper, such as en.
ipstringoptionalThe shopper's IP address, as the store recorded it with the Open Cart, else as the address service saw it; none when neither knows it.
user_agentstringalwaysAs the store recorded it with the Open Cart, else the browser's.

Address

A postal address as the shopper entered it, once every field its country requires is valid.

FieldTypePresent
first_namestringalways
last_namestringalways
line1stringalways
line2stringoptional
citystringoptionalNone in a country whose addresses have no city, such as Singapore.
statestringoptionalThe state or province code, in a country that has them.
postcodestringoptional
countrystringalwaysISO 3166-1 alpha-2.
phonestringoptionalIn E.164 once the address service read it, else the digits typed.

Example

The envelope next.analytics.on hands out, with data inside. See How analytics works for its fields.

CODE
{
  "event_id": "R1-US1",
  "event_type": "upsell_completed",
  "object": "order",
  "data": {
    "ref_id": "R1",
    "number": "1001",
    "currency": "USD",
    "test": false,
    "paid": true,
    "lines": [
      {
        "id": "11",
        "product_title": "Earbuds",
        "sku": "EB-2",
        "image": "https://img.test/eb.png",
        "quantity": 2,
        "price": 48.06,
        "original_price": 99,
        "total": 96.12,
        "tax": 7.12,
        "upsell": false
      },
      {
        "id": "99",
        "product_title": "Bump",
        "quantity": 1,
        "price": 20,
        "original_price": 20,
        "total": 20,
        "tax": 0,
        "upsell": true
      }
    ],
    "coupons": [],
    "total_discount": 0,
    "shipping_method": {
      "name": "Express",
      "price": 9.99,
      "tax": 0
    },
    "tax": 7.12,
    "total": 106.11,
    "user": {
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe"
    },
    "shipping_address": {
      "first_name": "Jane",
      "last_name": "Doe",
      "line1": "1 Main St",
      "city": "Austin",
      "state": "TX",
      "postcode": "73301",
      "country": "US"
    },
    "billing_address": {
      "first_name": "Ann",
      "last_name": "Lee",
      "line1": "2 Side St",
      "city": "Reno",
      "state": "NV",
      "country": "US"
    },
    "payment_method": "card_token",
    "supports_upsells": true,
    "upsell": {
      "number": 1,
      "line": {
        "id": "99",
        "product_title": "Bump",
        "quantity": 1,
        "price": 20,
        "original_price": 20,
        "total": 20,
        "tax": 0,
        "upsell": true
      }
    }
  },
  "created_at": "2026-11-04T08:30:00.000Z",
  "session_id": "0b8f3c2d1e4a4f6b9c7d5e3f2a1b0c9d",
  "sdk_version": "0.5.0",
  "context": {
    "page_location": "https://shop.test/checkout/",
    "page_title": "Olympus Earbuds",
    "page_referrer": "",
    "campaign": {
      "id": 1310,
      "name": "Olympus",
      "currency": "USD",
      "language": "en"
    },
    "session_id": "0b8f3c2d1e4a4f6b9c7d5e3f2a1b0c9d",
    "attribution": {
      "funnel": "Olympus"
    },
    "browser": {
      "user_agent": "Mozilla/5.0 …",
      "language": "en-US",
      "device_type": "desktop"
    }
  }
}

Sent to