Skip to content
BuildBase

Bundles

A seller sells several of their own items together, at one price - the buyer gets everything each included item gives.

A bundle is an item that includes other items of the same seller, sold together at one price: "Course + ebook + 1:1 call", or "3 mugs". Buying it gives the buyer everything each included item gives, as if each were bought on its own.

Note

Arrives with selling. Bundles arrive with selling and run on the same Stripe keys: test keys in Staging for test sales, live keys in Production once live selling is open for your app.

Requires @buildbase/sdk 1.2.0 or later. The "Included items" section of <ItemEditor>, ItemBenefit.quantity, ItemView.includes, OrderLineView.components and HoldingView.bundle arrive with it.

Walkthrough

New to selling? Zero to first sale: marketplace and Zero to first sale: storefront walk the whole flow once, from Stripe keys to a refund and going live.

When to use it

"Course + ebook + call" or "3 mugs": several of one seller's items, sold together at one price.

Before you start

An item type that allows the item benefit kind (the Bundle starter does), and the included items live, sold by checkout at a one-time price.

Set it up in the console

Under Billing, Item types, start a type from the Bundle starter, or allow the item benefit on your own type, and publish it. A bundle's included items then show on its page under Billing, Selling, Items, and an order lists what each line included.

Marketplace and storefront

The same in both: your fee is taken on the bundle's price, and the money goes as for any line of that shape.

What the seller sees

The "Included items" section of <ItemEditor>, and Needs update on a bundle when an included item stops selling.

What the buyer sees

One price; after paying, everything each included item gives, each grant marked with the bundle it came from (bundleContents lists them).

Emails and webhooks

As any order: Order Receipt, order.paid, and one grant.created per benefit of each included item.

Limits

Up to 10 included items, each 1 to 100 times, one-time prices only, no bundle inside a bundle.

Staging and Production

Nothing of its own: it follows its items.

How a bundle is made

In the console, a bundle's included items show on its page under Billing > Selling > Items, each linked to its own page, with a mark on any that cannot be sold with the bundle now; an order of a bundle lists what each line included under Billing > Selling > Orders.

A bundle is an ordinary item whose benefits include item benefits: each names one of the seller's items, an option of it (variantId, the first when unset) and how many (quantity, 1 to 100). The item type must allow the item benefit kind (the "Bundle" starter does).

{
  "title": "Course + ebook + call",
  "benefits": [
    {
      "id": "course",
      "kind": "item",
      "title": "The course",
      "itemId": "<course id>"
    },
    {
      "id": "ebook",
      "kind": "item",
      "title": "The ebook",
      "itemId": "<ebook id>"
    },
    {
      "id": "mugs",
      "kind": "item",
      "title": "Mugs",
      "itemId": "<mug id>",
      "quantity": 3
    }
  ],
  "variants": [
    {
      "id": "std",
      "prices": [
        { "id": "usd", "currency": "usd", "mode": "fixed", "amount": 5900 }
      ]
    }
  ]
}

Sellers make bundles in <ItemEditor> ("Included items"), through the same item routes as any item.

Rules

A bundle includes at most 10 items, each once, and sells one-time prices only. An included item must be:

  • the same seller's, and not the bundle itself or another bundle;
  • live (published or unlisted);
  • sold by checkout, at a one-time price, to anyone (no named buyers, no co-sellers);
  • delivering only what selling delivers today.

An included item may be booked by time: the buyer picks its slot at the bundle's checkout (slotStarts), and a bundle may include at most one slot's seats of it. See Booking calendars.

Publishing refuses a bundle that breaks a rule, with the problem at benefits.<id>:

CodeMeans
too_many_itemsMore than 10 included items
duplicate_itemThe same item included twice
bundle_one_time_onlyThe bundle has a subscription or a price paid in parts
bundle_selfThe bundle includes itself
bundle_item_not_foundThe included item no longer exists
bundle_other_sellerThe included item is another seller's
bundle_item_not_liveThe included item is not on sale
bundle_unknown_variantThe included item has no such option
bundle_nestedThe included item is a bundle
bundle_item_listingThe included item is a listing, with no checkout
bundle_item_recurringThe included item sells by subscription or in parts
bundle_item_restrictedThe included item is for named buyers only
bundle_item_co_soldThe included item is shared with co-sellers
bundle_item_undeliverableThe included item delivers something selling does not yet
bundle_item_booking_seatsThe bundle includes more of a booked item than a slot's seats

When an included item stops selling (archived, back to draft, rejected), the bundle stays live and is marked "Needs update"; checkout refuses it with CHECKOUT_REFUSED, problem bundle_item_unavailable, until the seller fixes it. Buyers who already bought it keep what they got.

Buying a bundle

  • Price. One price, the bundle's; the app's fee is taken on it, and a coupon applies to it like any line.
  • Stock. Checkout holds the stock of every included item that counts stock (quantity times bundle quantity) and gives it back if the checkout ends unpaid. Short of any, it refuses with OUT_OF_STOCK and holds nothing. A one-of-a-kind item cannot be included more than once (bundle_single_quantity).
  • What the buyer gets. Each included item's benefits, granted from that item (grant.itemId), each marked with the bundle it came from (bundle). Access checks, files and licence keys work as for a direct purchase.
  • The order. The line keeps a copy of what was included (components), and the sales export has a bundle_items column.
  • Refunds. A full refund of a bundle line revokes each included item's grants by that item's own after-refund rule; a partial refund revokes nothing.

Reading what a bundle includes

Item reads (the seller's, the console's, and the public catalog) carry includes: each included item's itemId, variantId, quantity, title, variantLabel, cover, whether it can be sold with the bundle now (available), and whether it is booked by time (bookable).

import { bundleContents } from '@buildbase/sdk';

const contents = bundleContents(item); // [{ title: 'Wheel course', quantity: 1, available: true }, ...]

Errors

A refused request answers { error, message, code }, with problems naming the included item. The console shows the message; the SDK shows each code in the reader's language.

codeWhat the person seesWhat to do
ITEM_INVALIDThis item cannot go live yet, with the problem at benefits.<id> (codes in Rules)Fix the bundle so it follows the rules, then publish again
CHECKOUT_REFUSEDAn included item cannot be sold with the bundle now (bundle_item_unavailable)The seller fixes the included item or the bundle ("Needs update")
OUT_OF_STOCKNot enough left for this orderWait for the seller to restock the included item, or buy fewer
ITEM_STATE_CONFLICTThis item changed meanwhile. Reload it and try againReload the bundle and try again