Skip to main content

Endpoint

POST /cart/add
Adds a reserved seat to the user’s cart. Creates a draft order if one doesn’t exist for the user, or adds the seat to an existing draft order.

Base URL

http://localhost:5003

Authentication

At least one required:
  • userId - For authenticated users
  • guestToken - For anonymous/guest checkout
If both userId and guestToken are null or empty, the request will return a 400 Bad Request error.

Request Body

{
  "reservationId": "8bf7fffc-9ff5-401c-9d2d-86f525f42e40",
  "seatId": "550e8400-e29b-41d4-a716-446655440002",
  "price": 50.00,
  "userId": "user-123",
  "guestToken": null
}

Parameters

FieldTypeRequiredDescription
reservationIdUUIDNoID of the reservation from Inventory service (can be null)
seatIdUUIDYesID of the seat to add to cart
pricedecimalYesPrice of the seat
userIdstringConditional*ID of the authenticated user
guestTokenstringConditional*Token for anonymous checkout
*At least one of userId or guestToken must be provided.

Response

Success Response (200 OK)

{
  "id": "order-uuid-001",
  "userId": "user-123",
  "guestToken": null,
  "totalAmount": 50.00,
  "state": "draft",
  "createdAt": "2026-02-24T15:15:00Z",
  "paidAt": null,
  "items": [
    {
      "id": "item-001",
      "seatId": "550e8400-e29b-41d4-a716-446655440002",
      "price": 50.00
    }
  ]
}

Response Fields

FieldTypeDescription
idUUIDUnique order identifier
userIdstring | nullUser ID (null if guest)
guestTokenstring | nullGuest token (null if authenticated)
totalAmountdecimalTotal amount for all items in cart
statestringOrder state (see Order States)
createdAtDateTimeOrder creation timestamp
paidAtDateTime | nullPayment timestamp (null for draft orders)
itemsarrayArray of order items
items[].idUUIDOrder item identifier
items[].seatIdUUIDSeat identifier
items[].pricedecimalItem price

Order States

The state field can have the following values:
StateDescription
draftCart created, waiting for more items or checkout
pendingCheckout completed, awaiting payment
completedPayment completed successfully
cancelledOrder was cancelled

Error Responses

400 Bad Request - Missing Authentication

{
  "error": "Either UserId or GuestToken must be provided"
}
Both userId and guestToken are null or empty.

400 Bad Request - Reservation Not Found

{
  "error": "Reservation not found"
}
The reservation has not been processed yet by the Kafka event consumer. Wait 2-3 seconds after creating a reservation before calling this endpoint.

400 Bad Request - Seat Already in Cart

{
  "error": "Seat is already in the cart"
}
The specified seat has already been added to the user’s cart.

400 Bad Request - Reservation Expired

{
  "error": "Reservation has expired"
}
The reservation has expired (30-minute window). Create a new reservation and try again.

Kafka Event Consumption

This endpoint depends on the reservation-created event from the Inventory service:
  1. User creates reservation via POST /reservations (Inventory service)
  2. Inventory publishes reservation-created event to Kafka
  3. Ordering service consumes the event and stores reservation data
  4. Wait 2-3 seconds for event processing
  5. Call POST /cart/add with the reservationId
Always wait 2-3 seconds after creating a reservation before calling /cart/add to ensure the Kafka event has been processed.

Adding Multiple Seats

To add multiple seats to the same cart, call this endpoint once for each seat:
// Add first seat
const order1 = await fetch('http://localhost:5003/cart/add', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    reservationId: 'res-id-1',
    seatId: 'seat-1',
    price: 50.00,
    userId: 'user-123'
  })
}).then(r => r.json());

// Add second seat - same userId will update existing draft order
const order2 = await fetch('http://localhost:5003/cart/add', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    reservationId: 'res-id-2',
    seatId: 'seat-2',
    price: 50.00,
    userId: 'user-123'
  })
}).then(r => r.json());

// order2.totalAmount = 100.00
// order2.items.length = 2
The system will:
  • Find the existing draft order for the user
  • Add the new seat to the order
  • Update the totalAmount

Examples

cURL - Authenticated User

curl -X POST http://localhost:5003/cart/add \
  -H "Content-Type: application/json" \
  -d '{
    "reservationId": "8bf7fffc-9ff5-401c-9d2d-86f525f42e40",
    "seatId": "550e8400-e29b-41d4-a716-446655440002",
    "price": 50.00,
    "userId": "user-123"
  }'

cURL - Guest User

curl -X POST http://localhost:5003/cart/add \
  -H "Content-Type: application/json" \
  -d '{
    "reservationId": "8bf7fffc-9ff5-401c-9d2d-86f525f42e40",
    "seatId": "550e8400-e29b-41d4-a716-446655440002",
    "price": 50.00,
    "guestToken": "guest-abc123xyz"
  }'

JavaScript/TypeScript

async function addToCart(reservationId, seatId, price, userId) {
  const response = await fetch('http://localhost:5003/cart/add', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      reservationId,
      seatId,
      price,
      userId
    })
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error || 'Failed to add to cart');
  }

  return response.json();
}

// Usage
try {
  const order = await addToCart(
    '8bf7fffc-9ff5-401c-9d2d-86f525f42e40',
    '550e8400-e29b-41d4-a716-446655440002',
    50.00,
    'user-123'
  );
  console.log('Order:', order.id);
  console.log('Total:', order.totalAmount);
} catch (error) {
  console.error('Error:', error.message);
}

Python

import requests

def add_to_cart(reservation_id, seat_id, price, user_id):
    """Add a seat to the cart"""
    url = 'http://localhost:5003/cart/add'
    payload = {
        'reservationId': reservation_id,
        'seatId': seat_id,
        'price': price,
        'userId': user_id
    }
    
    response = requests.post(url, json=payload)
    response.raise_for_status()
    return response.json()

# Usage
try:
    order = add_to_cart(
        reservation_id='8bf7fffc-9ff5-401c-9d2d-86f525f42e40',
        seat_id='550e8400-e29b-41d4-a716-446655440002',
        price=50.00,
        user_id='user-123'
    )
    print(f"Order ID: {order['id']}")
    print(f"Total: ${order['totalAmount']}")
except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Workflow

Typical purchase flow:
  1. Get Event - GET /events/{eventId}/seatmap (Catalog service)
  2. Reserve Seat - POST /reservations (Inventory service)
  3. Wait - Wait 2-3 seconds for Kafka event processing
  4. Add to Cart - POST /cart/add (this endpoint)
  5. Checkout - POST /orders/checkout (Ordering service)

Build docs developers (and LLMs) love