# Carts

### Overview

The Cart object is the central entity in Violet's unified checkout API that represents a shopping cart containing products from one or more merchants. It serves as the primary container for managing multi-merchant checkout flows and automatically organizes items into "bags" based on the merchant they come from.

***

### Key Concepts

#### **Cart vs Order**

* **Cart**: Active shopping session that can be modified (add/remove items, apply discounts, set shipping)
* **Order**: Immutable record created after cart submission to merchants' platforms

#### **Multi-Merchant Architecture**

* A single cart can contain products from multiple merchants
* Items are automatically organized into **bags** - one bag per merchant
* Each bag mirrors the cart/order structure of the merchant's ecommerce platform

***

### Core Properties

#### **Identification**

```json
{
  "id": 10000,                    // Unique cart ID in Violet
  "token": "fz8x7gksdjsy2p9...",  // Cart token for secure access
  "app_order_id": "order_123",    // Your system's order identifier
  "external_id": "ref_456"        // Optional reference ID
}
```

#### **Ownership & Context**

```json
{
  "user_id": 10002,               // User who created the cart
  "app_id": 10001,                // Your application ID
  "developer_id": 10001,          // Developer account ID
  "app_name": "Your App Name"     // Name of originating application
}
```

#### **Financial Summary**

All monetary values are in **cents** in the base currency:

```json
{
  "base_currency": "USD",         // Cart currency (set at creation)
  "sub_total": 2500,             // Item prices before discounts/shipping/tax
  "shipping_total": 599,         // Total shipping costs
  "tax_total": 200,              // Total tax amount
  "discount_total": 500,         // Total discount amount
  "total": 2799,                 // Final total (sub_total + shipping + tax - discounts)
  "taxes_included": false        // Whether taxes are included in item prices
}
```

***

### Bags Structure

Each cart contains an array of **bags** - one per merchant:

```json
{
  "bags": [
    {
      "id": 11111,                  // Unique bag ID
      "merchant_id": 10000,         // Merchant this bag belongs to
      "status": "IN_PROGRESS",      // Bag status (see lifecycle below)
      "fulfillment_status": "PROCESSING",
      "financial_status": "UNPAID",
      "platform": "SHOPIFY",       // Merchant's ecommerce platform
      "commission_rate": 0.15,      // Your commission rate (15%)
      "external_checkout": true,    // Whether bag has external cart representation
      
      // Financial totals for this bag
      "sub_total": 2500,
      "shipping_total": 599,
      "tax_total": 200,
      "discount_total": 500,
      "total": 2799,
      
      // Items in this bag
      "skus": [...],               // Array of SKU objects
      "shipping_method": {...},    // Applied shipping method
      "discounts": [...],          // Applied discount codes
      "taxes": [...]               // Tax breakdown
    }
  ]
}
```

#### **Bag Lifecycle States**

* **`IN_PROGRESS`**: Cart is being built, can be modified
* **`SUBMITTED`**: Cart has been sent to merchant platform
* **`ACCEPTED`**: Merchant platform confirmed the order
* **`COMPLETED`**: All items fulfilled and shipped
* **`REFUNDED`**: All items returned and refunded

***

### SKU (Product Items) Structure

Each bag contains SKUs representing individual products:

```json
{
  "skus": [
    {
      "id": 10000,                    // Violet SKU ID
      "sku_id": 99999,               // Merchant's SKU ID
      "external_id": "1234567890",   // SKU ID in merchant's system
      "name": "Nintendo Entertainment System",
      "brand": "Nintendo",
      "thumbnail": "https://res.cloudinary.com/...",
      "quantity": 2,                 // Quantity in cart
      "price": 9999,                // Price per unit (in cents)
      "line_price": 19998,          // Total for this line (price × quantity)
      "weight": 1.0,                // Item weight
      "available": true,             // Still available for purchase
      "status": "IN_PROGRESS",       // Current status
      "product_type": "PHYSICAL",    // PHYSICAL or DIGITAL
      "custom": false                // Whether price was overridden
    }
  ]
}
```

***

### Customer Information

```json
{
  "customer": {
    "user_id": 10000,
    "first_name": "Super",
    "last_name": "Mario",
    "email": "super@mar.io",
    "name": "Super Mario",
    "shipping_address": {
      "address_1": "123 Main St",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "country": "US",
      "type": "SHIPPING"
    },
    "billing_address": {...},       // Similar structure
    "same_address": true            // Whether billing = shipping
  }
}
```

***

### Payment Integration

#### **Standard Payment Flow**

```json
{
  "payment_transactions": [
    {
      "id": 84808,
      "payment_provider": "STRIPE",
      "amount": 900,
      "currency": "USD",
      "capture_status": "REQUIRES_PAYMENT_METHOD",
      "capture_method": "AUTOMATIC",
      "status": "REQUIRES_PAYMENT_METHOD"
    }
  ]
}
```

#### **Wallet-Based Checkout** (Apple Pay, Google Pay)

```json
{
  "wallet_based_checkout": true,
  "stripe_key": "pk_test_UHg8oLvg4rrDCbvtqfwTE8qd",
  "payment_intent_client_secret": "pi_3MbFHUK29KDiBVld0N8b8EDd_secret_..."
}
```

***

### Error Handling

Carts include comprehensive error tracking:

```json
{
  "errors": [
    {
      "id": "error_123",
      "entity_type": "SKU",          // What caused the error
      "entity_id": "sku_456",        // ID of problematic entity
      "message": "Item out of stock",
      "resolved": false,
      "date_created": "2024-06-17T10:30:00Z",
      "date_resolved": null
    }
  ]
}
```

**Important**: Always check the `errors` array - the API returns 200 even with bag-level errors.

***

### Special Features

#### **Multi-Currency Support**

* Set currency at cart creation with `base_currency` parameter
* Once a cart has been created in a currency, you cannot change it. You will need to create a new cart with the updated base\_currency to achieve this.
* Real-time exchange rates applied automatically or using presentment currencies

#### **Discount Codes**

* Discount codes can be added during cart creation (\[POST]/checkout/cart) or through an exclusive endpoint (\[POST]/checkout/cart/:cart\_id/discounts)
* Validated against each merchant's platform
* States: `PENDING`, `APPLIED`, `INVALID`, `EXPIRED`, `ERROR`
* See [Discounts](/prism/checkout-guides/discounts.md) section for more info

#### **Shipping Methods**

* Automatically retrieved from each merchant's platform
* Applied per bag (per merchant)
* Calculated based on shipping address and item weights

***

### Key API Endpoints

<table><thead><tr><th width="194.9140625">Action</th><th width="339.0546875">Endpoint</th><th>Method</th></tr></thead><tbody><tr><td>Create cart</td><td><code>/checkout/cart</code></td><td>POST</td></tr><tr><td>Get cart</td><td><code>/checkout/cart/{id}</code></td><td>GET</td></tr><tr><td>Get by token</td><td><code>/checkout/cart/byToken/{token}</code></td><td>GET</td></tr><tr><td>Delete cart</td><td><code>/checkout/cart/{id}</code></td><td>DELETE</td></tr><tr><td>Add items</td><td><code>/checkout/cart/{id}/items</code></td><td>POST</td></tr><tr><td>Apply payment</td><td><code>/checkout/cart/{id}/payment</code></td><td>POST</td></tr><tr><td>Set shipping</td><td><code>/checkout/cart/{id}/shipping</code></td><td>POST</td></tr><tr><td>Add discounts</td><td><code>/checkout/cart/{id}/discounts</code></td><td>POST</td></tr><tr><td>Submit cart</td><td><code>/checkout/cart/{id}/submit</code></td><td>POST</td></tr></tbody></table>

***

### Best Practices

#### **Cart Management**

1. **Use app\_order\_id**: While not enforced unique in Violet's system, it is strongly recommended that unique values are used for each cart to help correlate identifiers between Violet's system and yours.
2. **Error Checking**: Always examine the `errors` array after any cart operation
3. **Currency Immutability**: Choose currency carefully at creation - it cannot be changed later
4. **Bag Awareness**: Remember that multi-merchant carts create multiple bags, each potentially with different shipping methods, discounts, and states

#### **Performance Considerations**

* Carts persist indefinitely - implement cleanup for abandoned carts
* Carts with wallet\_based\_checkout set to true cannot be completed without completing the front end client work listed below, specifically the Stripe Element integration and the client side Payment Confirmation. There is no API-only path complete such an order

#### **Security**

* Use cart tokens for client-side access instead of cart IDs
* Validate cart ownership before allowing modifications
* Implement proper authentication for cart operations

***

### Example: Basic Cart Creation

```javascript
// Create a cart with items from multiple merchants
const cart = await fetch('/v1/checkout/cart', {
  method: 'POST',
  headers: {
    'X-Violet-Token': authToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    base_currency: 'USD',
    app_order_id: 'your-order-123',
    skus: [
      {
        sku_id: 12345,      // From Merchant A
        quantity: 2
      },
      {
        sku_id: 67890,      // From Merchant B  
        quantity: 1
      }
    ]
  })
});

const cartData = await cart.json();
// cartData.bags will contain 2 bags (one per merchant)
// Each bag will have the respective SKUs
```

***

This cart object design enables Violet's core value proposition: unified multi-merchant checkout through a single API interface, while maintaining the flexibility and features of individual ecommerce platforms.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.violet.io/prism/checkout-guides/carts-and-bags/carts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
