Checkout
Create orders from the cart
Create Order
const order = await client.checkout.createOrder({
email: '[email protected]',
phone: '+420123456789',
shippingAddress: {
firstName: 'Jan',
lastName: 'Novak',
street: 'Vodickova 12',
city: 'Praha',
zip: '11000',
country: 'CZ',
},
billingAddress: {
firstName: 'Jan',
lastName: 'Novak',
street: 'Vodickova 12',
city: 'Praha',
zip: '11000',
country: 'CZ',
},
customerNote: 'Ring the bell twice',
termsConsent: true, // required when the shop has requireTermsConsent
gdprConsent: true, // required when the shop has requireGdprConsent
newsletterOptIn: true, // optional, first-party newsletter opt-in
pickupPointId: 'Z-12345', // required when the shipping method supportsPickupPoints
redeemLoyaltyPoints: 500, // optional, redeems loyalty points
});After a successful checkout:
- Cart is automatically cleared
order:createdandcart:clearedevents are emitted- Cart session is reset
Checkout Input
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Customer email |
phone | string | No | Customer phone |
shippingAddress | Address | Yes | Shipping address |
billingAddress | Address | No | Billing (defaults to shipping) |
customerNote | string | No | Note from customer |
termsConsent | boolean | Conditional | Must be true when the shop requires terms consent |
gdprConsent | boolean | Conditional | Must be true when the shop requires GDPR consent |
newsletterOptIn | boolean | No | Subscribe the email to the shop newsletter |
pickupPointId | string | Conditional | Pickup point externalId; required when the method supportsPickupPoints |
redeemLoyaltyPoints | number | No | Points to redeem (1-1,000,000) |
Checkout Settings Contract
ShopInfo.checkout carries the full merchant-configured checkout contract. Read it once and render the checkout to match:
const { data: shop } = await client.getShopInfo();
const c = shop.checkout;
// c.requirePhone, c.requireTaxId, c.requireTermsConsent, c.requireGdprConsent,
// c.newsletterOptInDefault ('CHECKED' | 'UNCHECKED' | 'HIDDEN'),
// c.allowOrderNote, c.allowDiscountCodes, c.minOrderValue, c.maxOrderValue,
// c.minItemsInCart, c.maxItemsPerProduct, c.freeShippingThreshold,
// c.stockBehavior, c.showLowStock, c.lowStockThreshold,
// c.addressAutocompleteEnabledThe backend enforces these settings unconditionally. When requireTermsConsent or requireGdprConsent is on (an EU legal requirement), createOrder without termsConsent: true / gdprConsent: true returns 400. The same applies to requirePhone (phone), requireTaxId (companyId/vatId on an address), minItemsInCart, maxItemsPerProduct and minOrderValue/maxOrderValue. Render the matching UI and send the fields.
Security
All financial operations are atomic and race-condition safe:
- Stock is decremented atomically, so overselling is impossible. The stock
rule follows
stockBehavior:HIDE/SHOW_SOLD_OUTshops reject over-stock quantities already at add-to-cart / quantity update (400) and again at checkout;BACKORDERshops accept any quantity and the stock balance may go negative (units owed) - Gift cards use conditional balance check, so double-spend is blocked
- Discount codes with usage limits are claimed atomically
- Loyalty points are deducted inside the same transaction
- Cart is verified non-empty inside the transaction
Since SDK 0.37.0 ShopInfo.checkout.stockMode (TRACKED | ALWAYS_AVAILABLE | MADE_TO_ORDER) tells you the shop's stock mode: non-TRACKED shops (resellers, made-to-order producers) are always purchasable regardless of stock, stockQuantity is null and availability derives to in-stock / on-order. Hide stock UI entirely for those shops.
Guest checkout may be disabled by the shop admin. If allowGuestCheckout is false, customers must register before checking out.
Events
client.on('order:created', (order) => {
router.push(`/thank-you?order=${order.orderNumber}`);
});