Skip to main content

Quickstart

A complete flow: create a category, add a menu item (with variants in TypeScript), customize it with a modifier group, place an order, and advance it through the kitchen lifecycle. The Python flow uses the unified menu resources — items priced directly and orders identified by menu_item_id.

import { WiilClient } from 'wiil-js';
import { MenuOrderType, OrderStatus, PreferredContactMethod } from 'wiil-core-js';

async function setupRestaurant() {
const client = new WiilClient({ apiKey: process.env.WIIL_API_KEY! });

// 1. Create customer
const customer = await client.customers.create({
phone_number: '+15551234567',
firstname: 'John',
lastname: 'Doe',
preferred_language: 'en',
preferred_contact_method: PreferredContactMethod.SMS,
isValidatedNames: false,
});

// 2. Create menu categories
const appetizers = await client.menus.createCategory({ name: 'Appetizers', description: 'Start your meal', displayOrder: 1 });
const entrees = await client.menus.createCategory({ name: 'Entrees', description: 'Main courses', displayOrder: 2 });

// 3. Create menu items with required variants
const wings = await client.menus.createItem({
categoryId: appetizers.id,
name: 'Buffalo Wings',
description: 'Crispy wings with hot sauce',
price: 11.99,
isAvailable: true,
isActive: true,
preparationTime: 15,
displayOrder: 1,
variants: [
{ name: '6 pieces', price: 11.99, isDefault: true, isActive: true, isAvailable: true },
{ name: '12 pieces', price: 19.99, isDefault: false, isActive: true, isAvailable: true },
],
});

const burger = await client.menus.createItem({
categoryId: entrees.id,
name: 'Classic Burger',
description: 'Angus beef with all the fixings',
price: 14.99,
isAvailable: true,
isActive: true,
preparationTime: 12,
displayOrder: 1,
variants: [
{ name: 'Default', price: 14.99, isDefault: true, isActive: true, isAvailable: true },
],
});

// 4. Create a modifier group and bind it to the burger
const toppings = await client.modifiers.createGroup({
name: 'Extra Toppings',
description: 'Customize your burger',
isRequired: false,
minSelection: 0,
maxSelection: 3,
displayOrder: 1,
isActive: true,
options: [
{ name: 'Bacon', priceDelta: 2.00, displayOrder: 1, isDefault: false, isActive: true },
{ name: 'Extra Cheese', priceDelta: 1.50, displayOrder: 2, isDefault: false, isActive: true },
{ name: 'Avocado', priceDelta: 2.50, displayOrder: 3, isDefault: false, isActive: true },
],
});

await client.modifiers.createBinding({
menuItemId: burger.id,
modifierGroupId: toppings.id,
displayOrder: 1,
isRequired: false,
});

// 5. Create an order
const order = await client.menuOrders.create({
customerId: customer.id,
type: MenuOrderType.DINE_IN,
orderDate: Date.now(),
items: [
{ menuItemId: wings.id, variantId: wings.variants[1].id, itemName: 'Buffalo Wings (12 pieces)', quantity: 1, unitPrice: 19.99, totalPrice: 19.99 },
{ menuItemId: burger.id, variantId: burger.variants[0].id, itemName: 'Classic Burger', quantity: 2, unitPrice: 14.99, totalPrice: 29.98 },
],
pricing: { subtotal: 49.97, total: 49.97 },
});

// 6. Move the order through its lifecycle
await client.menuOrders.updateStatus(order.id, {
id: order.id,
status: OrderStatus.CONFIRMED,
estimatedReadyTime: null,
actualReadyTime: null,
});

return { customer, categories: [appetizers, entrees], items: [wings, burger], order };
}

setupRestaurant().catch(console.error);

Next steps

  • Categories & items — full reference for categories, items, and variants
  • Modifiers — customization groups, options, and bindings
  • Orders — order fields, pricing, and the kitchen lifecycle