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>:
| Code | Means |
|---|---|
too_many_items | More than 10 included items |
duplicate_item | The same item included twice |
bundle_one_time_only | The bundle has a subscription or a price paid in parts |
bundle_self | The bundle includes itself |
bundle_item_not_found | The included item no longer exists |
bundle_other_seller | The included item is another seller's |
bundle_item_not_live | The included item is not on sale |
bundle_unknown_variant | The included item has no such option |
bundle_nested | The included item is a bundle |
bundle_item_listing | The included item is a listing, with no checkout |
bundle_item_recurring | The included item sells by subscription or in parts |
bundle_item_restricted | The included item is for named buyers only |
bundle_item_co_sold | The included item is shared with co-sellers |
bundle_item_undeliverable | The included item delivers something selling does not yet |
bundle_item_booking_seats | The 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_STOCKand 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 abundle_itemscolumn. - 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.
code | What the person sees | What to do |
|---|---|---|
ITEM_INVALID | This 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_REFUSED | An 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_STOCK | Not enough left for this order | Wait for the seller to restock the included item, or buy fewer |
ITEM_STATE_CONFLICT | This item changed meanwhile. Reload it and try again | Reload the bundle and try again |