> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Orders API

> Order creation and management

## Overview

The Orders API manages order creation, status tracking, and fulfillment. Returns **OrderInstance** objects with direct property access.

```typescript theme={null}
import { Orders, OrderStatus } from 'lua-cli';

// Create order - returns OrderInstance
const order = await Orders.create({
  basketId: 'basket_abc123',
  data: { shippingAddress, paymentMethod }
});

// Direct property access
console.log(order.status);       // "pending"
console.log(order.totalAmount);  // 59.98
console.log(order.items);        // Array of items

// Instance methods
await order.updateStatus(OrderStatus.FULFILLED);
await order.update({ trackingNumber: 'ABC123' });
await order.save();

// Access updated properties
console.log(order.status);          // "fulfilled"
console.log(order.trackingNumber);  // "ABC123"
```

<CardGroup cols={2}>
  <Card title="Direct Access" icon="bolt">
    Access `order.status` not `order.common.status`
  </Card>

  <Card title="Instance Methods" icon="wrench">
    Built-in `updateStatus()`, `update()`, and `save()` methods
  </Card>

  <Card title="Auto-Sync" icon="sync">
    Properties update after method calls
  </Card>

  <Card title="Type-Safe" icon="shield">
    Full TypeScript support
  </Card>
</CardGroup>

## Order Statuses

```typescript theme={null}
import { OrderStatus } from 'lua-cli';
```

<Steps>
  <Step title="PENDING">
    Order created, not yet confirmed

    Initial status for new orders
  </Step>

  <Step title="CONFIRMED">
    Order confirmed, being processed

    Payment successful, ready for fulfillment
  </Step>

  <Step title="FULFILLED">
    Order completed and delivered

    Final status for successful orders
  </Step>

  <Step title="CANCELLED">
    Order cancelled by user or system

    No further processing
  </Step>
</Steps>

## Methods

### create()

Create a new order.

```typescript theme={null}
Orders.create(orderData: CreateOrderRequest): Promise<OrderInstance>
```

<ParamField path="orderData.basketId" type="string" required>
  ID of the basket to convert to order
</ParamField>

<ParamField path="orderData.data" type="object" required>
  Order details (shipping, payment, etc.)
</ParamField>

**Returns:** `OrderInstance` with direct property access and methods

**Example:**

```typescript theme={null}
const order = await Orders.create({
  basketId: 'basket_abc123',
  data: {
    shippingAddress: {
      street: '123 Main St',
      city: 'New York',
      zip: '10001'
    },
    paymentMethod: 'stripe',
    customerEmail: 'customer@example.com'
  }
});

// Direct property access
console.log(order.id);          // "order_def456"
console.log(order.status);      // "pending"
console.log(order.totalAmount); // 59.98
console.log(order.items);       // Array of items
console.log(order.shippingAddress.city); // "New York"

// Instance methods available
await order.updateStatus(OrderStatus.CONFIRMED);
```

### get()

Retrieve orders, optionally filtered by status.

```typescript theme={null}
Orders.get(status?: OrderStatus): Promise<OrderInstance[]>
```

**Examples:**

```typescript theme={null}
// Get all orders
const allOrders = await Orders.get();

// Get pending orders only
const pending = await Orders.get(OrderStatus.PENDING);

// Get fulfilled orders
const fulfilled = await Orders.get(OrderStatus.FULFILLED);
```

### getById()

Get a specific order by ID.

```typescript theme={null}
Orders.getById(orderId: string): Promise<OrderInstance>
```

**Returns:** `OrderInstance` with direct property access

**Example:**

```typescript theme={null}
const order = await Orders.getById('order_def456');

// Direct property access (no .common needed!)
console.log(order.status);       // "fulfilled"
console.log(order.totalAmount);  // 59.98
console.log(order.items);        // Array of items
console.log(order.shippingAddress); // Address object

// Instance methods
await order.updateStatus(OrderStatus.FULFILLED);
await order.update({ deliveryDate: '2025-10-15' });
```

### updateStatus()

Update order status.

```typescript theme={null}
Orders.updateStatus(status: OrderStatus, orderId: string): Promise<OrderResponse>
```

Or use instance method:

```typescript theme={null}
order.updateStatus(status: OrderStatus): Promise<OrderInstance>
```

**Returns:** `OrderInstance` with updated status

**Example:**

```typescript theme={null}
// Using static method
const order = await Orders.updateStatus(OrderStatus.CONFIRMED, orderId);

// Or using instance method (recommended)
await order.updateStatus(OrderStatus.CONFIRMED);
await order.updateStatus(OrderStatus.FULFILLED);
await order.updateStatus(OrderStatus.FULFILLED);

// Access updated status directly
console.log(order.status); // "fulfilled"

// Cancel order
await order.updateStatus(OrderStatus.CANCELLED);
```

### updateData()

Update order data/metadata.

```typescript theme={null}
Orders.updateData(data: Record<string, any>, orderId: string): Promise<OrderResponse>
```

**Example:**

```typescript theme={null}
await Orders.updateData({
  trackingNumber: 'TRACK123456',
  carrier: 'UPS',
  estimatedDelivery: '2025-10-10',
  notes: 'Fragile - handle with care'
}, orderId);
```

### save() (Instance Method)

Save the current state of the order to the server. This is a convenience method that persists all changes made to the order instance.

```typescript theme={null}
order.save(): Promise<boolean>
```

**Returns:** Promise resolving to `true` if successful

**Example:**

```typescript theme={null}
const order = await Orders.getById('order_def456');

// Modify order data properties
order.trackingNumber = 'TRACK123456';
order.carrier = 'UPS';
order.estimatedDelivery = '2025-10-10';

// Save all changes at once
await order.save();

// Much cleaner workflow!
```

<Note>
  **New in Latest Version:** The `save()` method provides a simpler workflow - modify properties then save, rather than calling `Orders.updateData()` with the order ID.
</Note>

## OrderInstance

All order methods return `OrderInstance` objects with:

**Direct Property Access:**

```typescript theme={null}
order.id
order.status          // No .common needed!
order.totalAmount     // Direct access
order.itemCount       // Direct access
order.items           // Array of items
order.currency
order.shippingAddress // Data property via proxy
order.paymentMethod   // Data property via proxy
order.createdAt       // Via proxy (from OrderData)
```

**Instance Methods:**

```typescript theme={null}
await order.updateStatus(OrderStatus.FULFILLED);
await order.update({ trackingNumber: 'ABC123' });
await order.save();
```

**Backward Compatible:**

```typescript theme={null}
order.status;         // ✅ New way
order.common.status;  // ✅ Old way still works
```

## Complete Examples

### Create Order Tool

```typescript theme={null}
import { LuaTool, Orders } from 'lua-cli';
import { z } from 'zod';

export class CreateOrderTool implements LuaTool {
  name = "create_order";
  description = "Create order from basket";
  
  inputSchema = z.object({
    basketId: z.string(),
    shippingAddress: z.object({
      street: z.string(),
      city: z.string(),
      zip: z.string()
    }),
    paymentMethod: z.string().default('stripe')
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const order = await Orders.create({
      basketId: input.basketId,
      data: {
        shippingAddress: input.shippingAddress,
        paymentMethod: input.paymentMethod
      }
    });
    
    return {
      orderId: order.id,
      status: order.common.status,
      total: `$${order.common.totalAmount.toFixed(2)}`,
      message: "Order created successfully!"
    };
  }
}
```

### Track Order Tool

```typescript theme={null}
export class TrackOrderTool implements LuaTool {
  name = "track_order";
  description = "Get order status and tracking info";
  
  inputSchema = z.object({
    orderId: z.string()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const order = await Orders.getById(input.orderId);
    
    return {
      orderId: order.id,
      status: order.common.status,
      total: `$${order.common.totalAmount.toFixed(2)}`,
      itemCount: order.common.itemCount,
      trackingNumber: order.data?.trackingNumber,
      estimatedDelivery: order.data?.estimatedDelivery,
      message: this.getStatusMessage(order.common.status)
    };
  }
  
  private getStatusMessage(status: string): string {
    switch (status) {
      case 'pending': return 'Order is being processed';
      case 'confirmed': return 'Order confirmed and being prepared';
      case 'fulfilled': return 'Order delivered!';
      case 'cancelled': return 'Order was cancelled';
      default: return 'Unknown status';
    }
  }
}
```

### Update Order Status Tool

```typescript theme={null}
export class UpdateOrderStatusTool implements LuaTool {
  name = "update_order_status";
  description = "Update order fulfillment status";
  
  inputSchema = z.object({
    orderId: z.string(),
    status: z.enum(['pending', 'confirmed', 'fulfilled', 'cancelled'])
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const statusMap = {
      'pending': OrderStatus.PENDING,
      'confirmed': OrderStatus.CONFIRMED,
      'fulfilled': OrderStatus.FULFILLED,
      'cancelled': OrderStatus.CANCELLED
    };
    
    await Orders.updateStatus(statusMap[input.status], input.orderId);
    
    return {
      success: true,
      message: `Order status updated to ${input.status}`
    };
  }
}
```

## Use Cases

### Order Fulfillment Workflow

```typescript theme={null}
// 1. Create order
const order = await Orders.create({ basketId, data });

// 2. Confirm payment
await Orders.updateStatus(OrderStatus.CONFIRMED, order.id);

// 3. Add tracking info
await Orders.updateData({
  trackingNumber: 'TRACK123',
  carrier: 'UPS',
  shippedAt: new Date().toISOString()
}, order.id);

// 4. Mark as delivered
await Orders.updateStatus(OrderStatus.FULFILLED, order.id);
```

### Customer Service Lookup

```typescript theme={null}
// Find customer's orders
const userOrders = await Orders.get();

// Filter recent orders
const recent = userOrders.filter(order => {
  const orderDate = new Date(order.createdAt);
  const thirtyDaysAgo = new Date();
  thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
  return orderDate > thirtyDaysAgo;
});
```

### Order Analytics

```typescript theme={null}
// Get all orders
const orders = await Orders.get();

// Calculate metrics
const totalRevenue = orders.reduce((sum, order) => 
  sum + order.common.totalAmount, 0
);

const avgOrderValue = totalRevenue / orders.length;

const fulfillmentRate = orders.filter(o => 
  o.common.status === OrderStatus.FULFILLED
).length / orders.length;
```

## Best Practices

<AccordionGroup>
  <Accordion title="Store Tracking Information">
    ```typescript theme={null}
    await Orders.updateData({
      trackingNumber: 'TRACK123456',
      carrier: 'UPS',
      trackingUrl: 'https://track.ups.com/...',
      estimatedDelivery: '2025-10-10'
    }, orderId);
    ```
  </Accordion>

  <Accordion title="Send Status Notifications">
    ```typescript theme={null}
    async updateOrderStatus(orderId: string, status: OrderStatus) {
      // Update status
      await Orders.updateStatus(status, orderId);
      
      // Send notification
      const order = await Orders.getById(orderId);
      await sendEmail(order.data.customerEmail, {
        subject: `Order ${orderId} - ${status}`,
        body: getEmailTemplate(status, order)
      });
    }
    ```
  </Accordion>

  <Accordion title="Handle Cancellations Gracefully">
    ```typescript theme={null}
    async cancelOrder(orderId: string, reason: string) {
      const order = await Orders.getById(orderId);
      
      // Can only cancel if not fulfilled
      if (order.common.status === OrderStatus.FULFILLED) {
        throw new Error('Cannot cancel fulfilled order');
      }
      
      // Update status and add reason
      await Orders.updateStatus(OrderStatus.CANCELLED, orderId);
      await Orders.updateData({
        cancellationReason: reason,
        cancelledAt: new Date().toISOString()
      }, orderId);
    }
    ```
  </Accordion>

  <Accordion title="Validate Order Exists">
    ```typescript theme={null}
    const order = await Orders.getById(orderId);

    if (!order) {
      throw new Error(`Order not found: ${orderId}`);
    }
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Baskets API" icon="cart-shopping" href="/api/baskets">
    Create baskets before orders
  </Card>

  <Card title="Order Examples" icon="layer-group" href="/examples/baskets">
    See complete order workflows
  </Card>
</CardGroup>
