# Checkout

Create, manage, and complete checkout sessions for purchasing products.

---

Checkout endpoints let agents create purchase sessions, add buyer information, and complete transactions. All checkout endpoints require [authentication](/docs/acp/authentication).

## Create checkout session

```
POST /acp/{appId}/checkout_sessions
```

Creates a new checkout session with one or more products.

### Headers

| Header             | Required | Description                                  |
|--------------------|----------|----------------------------------------------|
| `Authorization`    | Yes      | `Bearer acp_xxxxx`.                          |
| `Content-Type`     | Yes      | `application/json`.                          |
| `Idempotency-Key`  | No       | Unique string to prevent duplicate sessions. |

### Request body

```json
{
  "line_items": [
    { "product_id": "550e8400-e29b-41d4-a716-446655440000", "quantity": 2 },
    { "product_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "quantity": 1 }
  ],
  "buyer": {
    "name": "Jane Smith",
    "email": "jane@integrator.com",
    "phone": "+1-555-0100"
  },
  "shipping_address": {
    "line1": "123 Main St",
    "line2": "Suite 4B",
    "city": "San Francisco",
    "state": "CA",
    "postal_code": "94102",
    "country": "US"
  }
}
```

### Parameters

| Field                          | Type           | Required | Description                                          |
|--------------------------------|----------------|----------|------------------------------------------------------|
| `line_items`                   | array          | Yes      | At least one item.                                   |
| `line_items[].product_id`      | string (UUID)  | Yes      | Product ID from the catalog.                         |
| `line_items[].quantity`        | integer        | No       | Defaults to 1. Must be >= 1.                         |
| `buyer`                        | object         | No       | Purchaser information.                               |
| `buyer.name`                   | string         | No       | Buyer's name.                                        |
| `buyer.email`                  | string         | No       | Buyer's email (must be a valid format).              |
| `buyer.phone`                  | string         | No       | Buyer's phone number.                                |
| `shipping_address`             | object         | No       | Shipping address.                                    |
| `shipping_address.line1`       | string         | No       | Street address.                                      |
| `shipping_address.line2`       | string         | No       | Suite, floor, etc.                                   |
| `shipping_address.city`        | string         | No       | City.                                                |
| `shipping_address.state`       | string         | No       | State or province.                                   |
| `shipping_address.postal_code` | string         | No       | Postal code.                                         |
| `shipping_address.country`     | string         | No       | Country code.                                        |

### Example request

```bash
curl -X POST https://app.avcodex.com/acp/{appId}/checkout_sessions \
  -H "Authorization: Bearer acp_xxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-abc-123" \
  -d '{
    "line_items": [
      { "product_id": "550e8400-e29b-41d4-a716-446655440000", "quantity": 1 }
    ],
    "buyer": {
      "name": "Jane Smith",
      "email": "jane@integrator.com"
    }
  }'
```

### Response (201 Created)

```json
{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "ready_for_payment",
    "line_items": [
      {
        "productId": "550e8400-e29b-41d4-a716-446655440000",
        "productName": "Room Audit Report",
        "sku": "AUDIT-001",
        "quantity": 1,
        "unitPriceCents": 25000,
        "totalCents": 25000
      }
    ],
    "subtotal": { "amount": 25000, "currency": "usd" },
    "total": { "amount": 25000, "currency": "usd" },
    "buyer": {
      "name": "Jane Smith",
      "email": "jane@integrator.com",
      "phone": null
    },
    "shipping_address": null,
    "payment": null,
    "expires_at": "2025-01-15T13:00:00.000Z",
    "created_at": "2025-01-15T12:00:00.000Z",
    "updated_at": "2025-01-15T12:00:00.000Z"
  }
}
```

### Idempotency

Pass an `Idempotency-Key` header to safely retry requests. If a session with the same idempotency key already exists for this agent, the existing session is returned instead of creating a duplicate.

```bash
curl -X POST https://app.avcodex.com/acp/{appId}/checkout_sessions \
  -H "Authorization: Bearer acp_xxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-123" \
  -d '{ "line_items": [{ "product_id": "...", "quantity": 1 }] }'
```

---

## Get checkout session

```
GET /acp/{appId}/checkout_sessions/{id}
```

Retrieve the current status and details of a checkout session.

### Example request

```bash
curl https://app.avcodex.com/acp/{appId}/checkout_sessions/{sessionId} \
  -H "Authorization: Bearer acp_xxxxx"
```

### Response (200 OK)

Returns the same shape as the create response:

```json
{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "ready_for_payment",
    "line_items": [...],
    "subtotal": { "amount": 25000, "currency": "usd" },
    "total": { "amount": 25000, "currency": "usd" },
    "buyer": { "name": "Jane Smith", "email": "jane@integrator.com", "phone": null },
    "shipping_address": null,
    "payment": null,
    "expires_at": "2025-01-15T13:00:00.000Z",
    "created_at": "2025-01-15T12:00:00.000Z",
    "updated_at": "2025-01-15T12:00:00.000Z"
  }
}
```

---

## Update checkout session

```
POST /acp/{appId}/checkout_sessions/{id}
```

Update line items, buyer information, or shipping address on an existing session. Only works when the session is in a pre-payment state (`not_ready_for_payment` or `ready_for_payment`).

### Request body

All fields are optional. Only include the fields you want to update.

```json
{
  "line_items": [
    { "product_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "quantity": 3 }
  ],
  "buyer": {
    "email": "updated@integrator.com"
  }
}
```

### Example request

```bash
curl -X POST https://app.avcodex.com/acp/{appId}/checkout_sessions/{sessionId} \
  -H "Authorization: Bearer acp_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "buyer": { "name": "Jane Smith", "email": "jane.updated@integrator.com" }
  }'
```

### Response (200 OK)

Returns the updated session in the same shape as the create response.

---

## Complete checkout

```
POST /acp/{appId}/checkout_sessions/{id}/complete
```

Completes the checkout, triggering order creation, fulfillment (for automatic products), and webhook delivery. The session must be in `ready_for_payment` status and must not be expired.

### Example request

```bash
curl -X POST https://app.avcodex.com/acp/{appId}/checkout_sessions/{sessionId}/complete \
  -H "Authorization: Bearer acp_xxxxx"
```

### Response (200 OK)

```json
{
  "data": {
    "checkout_session": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "completed",
      "line_items": [...],
      "subtotal": { "amount": 25000, "currency": "usd" },
      "total": { "amount": 25000, "currency": "usd" },
      "buyer": { "name": "Jane Smith", "email": "jane@integrator.com", "phone": null },
      "shipping_address": null,
      "payment": null,
      "expires_at": "2025-01-15T13:00:00.000Z",
      "created_at": "2025-01-15T12:00:00.000Z",
      "updated_at": "2025-01-15T12:05:00.000Z"
    },
    "order": {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "status": "fulfilled",
      "fulfillment_result": [
        { "toolName": "generate_audit_report", "success": true, "output": "Audit complete" }
      ],
      "created_at": "2025-01-15T12:05:00.000Z"
    }
  }
}
```

### Order status values

| Status          | Description                                                    |
|-----------------|----------------------------------------------------------------|
| `created`       | Order created, awaiting processing.                            |
| `manual_review` | Requires human review before fulfillment.                      |
| `confirmed`     | Order confirmed, awaiting fulfillment.                         |
| `fulfilled`     | Automatic fulfillment completed successfully.                  |
| `shipped`       | Physical order shipped.                                        |
| `canceled`      | Order canceled.                                                |

> **Note:** Products with `fulfillment_type: "automatic"` are fulfilled immediately on checkout completion **only if a bound tool is configured** on the product. The order status will be `fulfilled` with results in the `fulfillment_result` field. If no bound tool is configured **or if all bound tool executions fail**, the order receives status `confirmed` instead. Manual products will also have status `confirmed` and require human action.

---

## Cancel checkout

```
POST /acp/{appId}/checkout_sessions/{id}/cancel
```

Cancels an active checkout session. Only works for sessions in pre-payment states (`not_ready_for_payment` or `ready_for_payment`). Sessions that are already completed or in progress cannot be canceled.

### Example request

```bash
curl -X POST https://app.avcodex.com/acp/{appId}/checkout_sessions/{sessionId}/cancel \
  -H "Authorization: Bearer acp_xxxxx"
```

### Response (200 OK)

```json
{
  "data": { "canceled": true }
}
```

---

## Checkout session status values

| Status                  | Description                                                                                                                                                          |
|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `not_ready_for_payment` | Session created without line items (internal only. The external API requires at least one line item, so sessions created via the API will never have this status). |
| `ready_for_payment`     | Has line items, ready to complete.                                                                                                                                   |
| `in_progress`           | Payment is being processed.                                                                                                                                          |
| `completed`             | Checkout finished, order created.                                                                                                                                    |
| `canceled`              | Session was canceled.                                                                                                                                                |

## Checkout response fields

| Field              | Type              | Description                                                                                                                                                  |
|--------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id`               | string (UUID)     | Checkout session identifier.                                                                                                                                 |
| `status`           | string            | Current session status (see table above).                                                                                                                    |
| `line_items`       | array             | Products in the checkout.                                                                                                                                    |
| `subtotal`         | object            | `{ amount, currency }`. Sum of line item totals.                                                                                                             |
| `total`            | object            | `{ amount, currency }`. Final amount to charge.                                                                                                              |
| `buyer`            | object or null    | `{ name, email, phone }`. Requires at least `name` or `email` to be present. Returns `null` if neither is set, even if `phone` was provided.                 |
| `shipping_address` | object or null    | Shipping address if provided.                                                                                                                                |
| `payment`          | object or null    | `{ payment_intent_id }` when payment exists.                                                                                                                 |
| `expires_at`       | string (ISO 8601) | Session expiration time (default: 1 hour after creation).                                                                                                    |
| `created_at`       | string (ISO 8601) | When the session was created.                                                                                                                                |
| `updated_at`       | string (ISO 8601) | Last modification time.                                                                                                                                      |

## Error responses

### 400 Bad Request

Invalid request body or state transition:

```json
{ "error": "Cannot complete checkout in status: canceled" }
```

### 404 Not Found

Session does not exist or belongs to a different agent:

```json
{ "error": "Checkout session not found" }
```

### 405 Method Not Allowed

Attempting to cancel a session that cannot be canceled:

```json
{ "error": "Cannot cancel checkout in status: completed" }
```

### 410 Gone

Session has expired:

```json
{ "error": "Checkout session has expired" }
```

*AVCodex · Your AV expertise. Amplified by AI.*