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

{
  "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

{
  "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:

{
  "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:

{
  "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:

{
  "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

{
  "customer": {
    "user_id": 10000,
    "first_name": "Super",
    "last_name": "Mario",
    "email": "[email protected]",
    "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

{
  "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)

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

Error Handling

Carts include comprehensive error tracking:

{
  "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 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

Action
Endpoint
Method

Create cart

/checkout/cart

POST

Get cart

/checkout/cart/{id}

GET

Get by token

/checkout/cart/byToken/{token}

GET

Delete cart

/checkout/cart/{id}

DELETE

Add items

/checkout/cart/{id}/items

POST

Apply payment

/checkout/cart/{id}/payment

POST

Set shipping

/checkout/cart/{id}/shipping

POST

Add discounts

/checkout/cart/{id}/discounts

POST

Submit cart

/checkout/cart/{id}/submit

POST


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

// 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.

Last updated

Was this helpful?