Order Agent

Order status, modifications, and customer service automation.

Overview

The Order Agent handles post-purchase customer interactions: order status inquiries, modifications, cancellations, and return processing. It provides a conversational interface for order management.

Capabilities

ORDER AGENT CAPABILITIES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ENDPOINTS:
  GET /orders/:id           Get order details
  GET /orders               List customer orders
  POST /orders/:id/cancel   Cancel order
  POST /orders/:id/modify   Modify order
  POST /orders/:id/return   Initiate return

FEATURES:
  ✓ Order lookup        Real-time order status
  ✓ Order history       Full purchase history
  ✓ Modifications       Address changes, item updates
  ✓ Cancellations       Pre-shipment cancellation
  ✓ Returns             Return initiation and tracking
  ✓ Refunds             Automatic refund processing

INTEGRATIONS:
  • Firestore (order state)
  • Stripe (refund processing)
  • Fulfillment Agent (status coordination)
  • CRM (customer history)

Order Status

Handle order status queries with full tracking information:

// Order Agent handling order status queries

@OnACPEvent('order_status')
async handleOrderStatus(orderId: string, context: BuyerContext) {
  const order = await this.orders.get(orderId);

  // Verify customer owns this order
  if (order.customer_id !== context.customer_id) {
    return { status: 'error', error: 'order_not_found' };
  }

  return {
    order_id: order.id,
    status: order.status,
    status_display: this.formatStatus(order.status),

    items: order.items.map(item => ({
      name: item.name,
      quantity: item.quantity,
      price: item.price,
      status: item.fulfillment_status,
    })),

    shipping: {
      address: order.shipping_address,
      method: order.shipping_method,
      tracking_number: order.tracking_number,
      carrier: order.carrier,
      estimated_delivery: order.estimated_delivery,
      current_location: await this.getTrackingLocation(order.tracking_number),
    },

    timeline: [
      { event: 'Order placed', date: order.created_at },
      { event: 'Payment confirmed', date: order.payment_confirmed_at },
      { event: 'Shipped', date: order.shipped_at },
      { event: 'Out for delivery', date: order.out_for_delivery_at },
    ].filter(e => e.date),

    actions_available: this.getAvailableActions(order),
  };
}

// Get available actions based on order state
getAvailableActions(order: Order): string[] {
  const actions = [];

  if (order.status === 'pending' || order.status === 'processing') {
    actions.push('cancel', 'modify_address');
  }

  if (order.status === 'shipped') {
    actions.push('track');
  }

  if (order.status === 'delivered') {
    const daysSinceDelivery = this.daysSince(order.delivered_at);
    if (daysSinceDelivery <= 30) {
      actions.push('return', 'exchange');
    }
  }

  return actions;
}

Order Modifications

Process order changes, cancellations, and refunds:

// Handling order modifications

@OnACPEvent('modify_order')
async handleModifyOrder(
  orderId: string,
  modification: OrderModification,
  context: BuyerContext
) {
  const order = await this.orders.get(orderId);

  // Check if modification is allowed
  if (!this.canModify(order)) {
    return {
      status: 'error',
      error: 'cannot_modify',
      reason: `Order cannot be modified. Status: ${order.status}`,
    };
  }

  switch (modification.type) {
    case 'address_change':
      return await this.updateShippingAddress(order, modification.new_address);

    case 'cancel_item':
      return await this.cancelItem(order, modification.item_id);

    case 'add_item':
      return await this.addItem(order, modification.product_id, modification.quantity);

    case 'full_cancel':
      return await this.cancelOrder(order, modification.reason);

    default:
      return { status: 'error', error: 'unknown_modification' };
  }
}

// Cancel order with refund
async cancelOrder(order: Order, reason: string) {
  // Check cancellation eligibility
  if (order.status === 'shipped') {
    return {
      status: 'error',
      error: 'already_shipped',
      message: 'Order has already shipped. Please initiate a return instead.',
      return_link: `/orders/${order.id}/return`,
    };
  }

  // Process refund
  const refund = await this.stripe.refunds.create({
    payment_intent: order.payment_intent_id,
    reason: 'requested_by_customer',
  });

  // Update order status
  await this.orders.update(order.id, {
    status: 'cancelled',
    cancelled_at: new Date().toISOString(),
    cancellation_reason: reason,
    refund_id: refund.id,
  });

  // Restore inventory
  await this.restoreInventory(order.items);

  // Notify customer
  await this.sendCancellationEmail(order);

  return {
    status: 'cancelled',
    refund_amount: refund.amount / 100,
    refund_status: refund.status,
    message: 'Your order has been cancelled and refund initiated.',
  };
}

Configuration

# order-agent-config.yaml
name: order-agent
type: order
version: "1.0"

# Order modification rules
modifications:
  address_change:
    allowed_statuses: [pending, processing]
    deadline_before_ship: 2h

  item_cancellation:
    allowed_statuses: [pending, processing]
    partial_cancel_allowed: true

  full_cancellation:
    allowed_statuses: [pending, processing, awaiting_fulfillment]
    refund_method: original_payment

# Return policy
returns:
  window_days: 30
  conditions:
    - "Item must be unused and in original packaging"
    - "Electronics must include all accessories"
  free_return_shipping: true
  restocking_fee:
    enabled: false
    percentage: 0

  # Auto-approve conditions
  auto_approve:
    enabled: true
    conditions:
      - "customer.tier in ['gold', 'platinum']"
      - "order.total < 100"
      - "reason in ['wrong_size', 'changed_mind']"

# Refund settings
refunds:
  auto_process: true
  processing_days: 3-5
  methods:
    - original_payment
    - store_credit

# Notifications
notifications:
  order_confirmed: true
  shipped: true
  out_for_delivery: true
  delivered: true
  cancelled: true
  refund_processed: true