Checkout
Methods of @cobuntu/embed for marketplace and ticket checkout, quotes, checkout session status and guest order links. Setup, sessions and errors are on the
client overview; each method links to its endpoint in the
REST API reference.
checkoutSessions
checkoutSessions.get
checkoutSessions.get(sessionId)
Route: GET /checkout/sessions/:sessionId
Returns: { status: "pending" } or { status: "paid", totalAmount, currency, items }
checkout (marketplace basket)
checkout.create
create({ items | cartToken, customer?, shippingAddress?, successUrl, cancelUrl, donation?, events?, taxId? })
Route: POST /checkout
Returns: { checkoutUrl, sessionId, transactionId, isFreeCheckout, requiresShipping, tickets? }. An all-free order has checkoutUrl: null.
checkout.quote
quote({ items | cartToken, shippingAddress?, customer?, donation?, events? })
Route: POST /checkout/quote
Returns: Quote: lines (with index, kind, eventId, requiresApproval), subtotal, shipping, total (tax excluded), memberSavings, allowedShippingCountries, groups
An item is { productId? | sku?, tierId?, quantity?, customAmount?, formAnswers? }
(max 20 lines, quantity 1-10). A product with several variants needs tierId
(TIER_REQUIRED). Common codes: SOLD_OUT (details.tierId),
PHYSICAL_CART_MUST_BE_ALONE, SHIPPING_COUNTRY_NOT_SERVED
(details.allowedCountries), MIXED_CURRENCY, MEMBERS_ONLY, SESSION_REQUIRED,
ALREADY_PURCHASED, FORM_ANSWERS_REQUIRED. Then check payment with
checkoutSessions.get(sessionId).
A ticket line is { tierId | productId, quantity?, customAmount?, attendees? }, where
attendees[i] is { name?, email?, formAnswers? } for place i (missing places
default to the buyer). Per-event options go in events: { [eventId]: { chatOptOut?, invitationToken? } }, one donation per order in donation: { amount, eventId? },
and the buyer's VAT number in taxId: { value, country }.
A basket that cannot be paid in one checkout throws BasketNeedsSplitError
(code: "BASKET_NEEDS_SPLIT") with groups: [{ lines, mode, reason, requiresAccount }],
where lines index into items. basketSplitGroups(e) returns the groups MAIN
first (or null for any other error). Send each group's items as its own checkout.
The quote never throws it: it returns groups with their totals instead.
import { basketSplitGroups } from "@cobuntu/embed";
try {
return await cobuntu.checkout.create({ items, successUrl, cancelUrl });
} catch (e) {
const groups = basketSplitGroups(e);
if (!groups) throw e;
const first = groups[0].lines.map((i) => items[i]);
return await cobuntu.checkout.create({ items: first, successUrl, cancelUrl });
}Ticket codes: TOO_MANY_TICKETS (details.max), INVALID_ATTENDEES, DUPLICATE_TIER,
INVALID_EVENTS (details.eventId), INVALID_INVITATION_TOKEN, INVALID_DONATION,
QUANTITY_LOCKED, CUSTOM_AMOUNT_REQUIRED, CUSTOM_AMOUNT_TOO_LOW (details.minAmount),
CUSTOM_AMOUNT_NOT_ACCEPTED, TIER_NOT_FOUND, TIER_NOT_ON_SALE (details.state,
details.opensAt), TIER_FULL (details.remaining), FORM_ANSWERS_REQUIRED
(details.missingFields, details.ticketIndex). VAT codes: INVALID_TAX_ID,
TAX_ID_COUNTRY_UNSUPPORTED. Line-level codes carry details.index into items.
sales (guest order link)
sales.manage
manage(token)
Route: GET /sales/manage?token=
Returns: GuestSale: the order, refund eligibility, invoiceUrl, hasReceipt
sales.manageReceipt
manageReceipt(token)
Route: GET /sales/manage/receipt?token=
Returns: The receipt PDF as a Blob
Guests get the token in a "Manage your order" link in their order email. Token
codes: INVALID_LINK, LINK_EXPIRED, UNSUPPORTED_LINK, LINK_MISMATCH,
LINK_NOT_FOUND. See the Marketplace guide.