Bags

Violet API Bag Object - Initial Summary

Overview

A Bag is the fundamental unit that represents a single merchant's portion of a multi-merchant order in Violet's API. A Bag is an object that wraps all the data for an Order related to a single merchant in Violet. They live within Orders and mirror the information required by underlying e-commerce store. To a merchant, this bag is synonymous to an order in their merchant store.

Key Principle: Each merchant in an order gets their own bag, enabling Violet's core multi-merchant checkout capability while maintaining platform-specific requirements.


Core Architecture

Automatic Management

Bag management is automatic. You do not need to interact with Bags directly. Bags are automatically created and managed when items are added to a Cart. If an offer is from a different merchant to existing items in a Cart, a new bag is created and the offer is added to that bag.

Merchant Isolation

Each bag operates independently with its own:

  • Financial calculations (taxes, shipping, discounts)

  • Platform-specific settings and constraints

  • External system integration and synchronization

  • Commission rates and payout structures


Bag Structure & Properties

Core Identification

{
  "id": 11111,                     // Unique bag ID in Violet
  "order_id": 10000,              // Parent order this bag belongs to
  "merchant_id": 10000,           // Associated merchant
  "app_id": 10000,                // Your application ID
  "external_id": "7438192837181", // Order ID in merchant's system (post-submission)
  "external_reference_id": "R12345" // Vanity/reference ID (platform-specific)
}

Platform Integration

{
  "platform": "SHOPIFY",          // Merchant's ecommerce platform
  "external_checkout": true,      // Whether bag has external cart representation
  "channel": "APP",               // Originating channel type
  "merchant_name": "Violet Store" // Merchant display name
}

Status Tracking

{
  "status": "ACCEPTED",           // Overall bag status
  "fulfillment_status": "PROCESSING", // Fulfillment state
  "financial_status": "PAID",    // Payment state
  "dispute_status": "UNDISPUTED"  // Payment dispute status (null if none)
}

Financial Architecture

Independent Calculations

Each bag maintains its own financial totals (all amounts in cents):

{
  "sub_total": 19998,             // Item prices before adjustments
  "shipping_total": 644,          // Shipping costs for this merchant
  "tax_total": 2070,             // Tax amount calculated by merchant's system
  "discount_total": 500,          // Applied discounts for this merchant
  "total": 22192,                // Final total for this bag
  "taxes_included": false         // Whether taxes are included in item prices
}

Currency & Exchange

{
  "currency": "USD",              // Base currency (inherited from cart)
  "external_currency": "USD",     // Merchant's platform currency
  "exchange_rate": 1.0           // Rate if currencies differ
}

Commission Structure

{
  "commission_rate": 0.15         // Your commission rate for this merchant (15%)
}

Platform-Specific Features

External Cart Representation

If the Bag is attached to an external cart in the commerce platform.

  • external_checkout: true: Bag has corresponding cart in merchant's platform

  • external_checkout: false: Platform doesn't support carts (orders created directly)

Remorse Period

{
  "remorse_period_ends": "2023-04-28T18:12:55+0000" // 30-day return window
}

Fixed issue where the remorsePeriodEnds property on the bag did not reflect 30 days from the date the checkout was actually submitted.


Product Management (SKUs)

SKU Structure Within Bags

{
  "skus": [
    {
      "id": 10000,                  // Violet SKU ID
      "sku_id": 99999,             // Merchant's SKU ID
      "external_id": "1234567890", // SKU ID in merchant's platform
      "product_id": "525a1e59...", // Parent product ID
      "name": "Nintendo Entertainment System",
      "brand": "Nintendo",
      "thumbnail": "https://res.cloudinary.com/...",
      "quantity": 2,
      "price": 9999,               // Price per unit (cents)
      "line_price": 19998,         // Total line price (price × quantity)
      "weight": 1.0,               // Physical weight
      "available": true,           // Current availability
      "status": "PROCESSING",      // SKU-level status
      "product_type": "PHYSICAL",  // PHYSICAL or DIGITAL
      "custom": false              // Whether price was overridden
    }
  ]
}

Inventory Management

  • Real-time availability: available field reflects current stock

  • Automatic validation: Items become unavailable if out of stock

  • Platform sync: Inventory levels synchronized with merchant's system


Shipping & Fulfillment

Merchant-Specific Shipping

Each bag has its own shipping method based on the merchant's settings:

{
  "shipping_method": {
    "type": "FLAT_RATE_PRICE",      // Shipping method type
    "carrier": "USPS",              // Shipping carrier
    "label": "Priority Mail",       // Display name
    "price": 644,                   // Shipping cost (cents)
    "shipping_method_id": "07d19...", // Platform-specific ID
    "bag_id": 11111,               // Associated bag
    "merchant_id": 10000,          // Associated merchant
    "custom": false                // Whether price was overridden
  }
}

Fulfillment Tracking

{
  "fulfillments": [
    {
      "id": "fulfill_123",          // Fulfillment ID
      "bag_id": 11111,             // Associated bag
      "external_id": "ship_456",   // ID in merchant's system
      "carrier": "USPS",           // Shipping carrier
      "carrier_raw": "United States Postal Service",
      "status": "SHIPPED",         // Fulfillment status
      "carrier_status": "IN_TRANSIT", // Carrier-provided status
      "tracking_number": "1234567890", // Tracking number
      "tracking_url": "https://...", // Tracking URL
      "skus": [                    // Items in this fulfillment
        {
          "fulfillment_id": "fulfill_123",
          "sku_id": 10000,
          "quantity": 2
        }
      ]
    }
  ]
}

Tax Management

Platform-Calculated Taxes

Taxes are calculated by each merchant's platform based on their settings:

{
  "taxes": [
    {
      "order_id": 127021,
      "merchant_id": 10009,
      "state": "WA",
      "rate": 6.5,                  // Tax rate percentage
      "amount": 1300,               // Tax amount (cents)
      "description": "Washington State Tax"
    },
    {
      "order_id": 127021,
      "merchant_id": 10009,
      "state": "WA",
      "rate": 3.85,
      "amount": 770,
      "description": "Seattle City Tax"
    }
  ]
}

Tax Calculation Rules

  • Each merchant calculates taxes based on their platform's configuration

  • Multiple tax rates can apply (state, county, city)

  • Zero-rate taxes are included for transparency

  • Tax-inclusive vs. tax-exclusive pricing supported


Discount Management

Merchant-Specific Discounts

Each bag can have its own discount codes validated against the merchant's platform:

{
  "discounts": [
    {
      "id": 10367,
      "bag_id": 10643,
      "code": "SUMMER20",           // Discount code
      "merchant_id": 22,           // Associated merchant
      "status": "APPLIED",         // PENDING, APPLIED, INVALID, EXPIRED, ERROR
      "amount": 500,               // Discount amount (cents)
      "description": "20% off summer sale",
      "email": "[email protected]" // Email used for validation
    }
  ]
}

Discount Validation

  • Codes are validated against each merchant's platform individually

  • Same code may work for some merchants but not others

  • Email addresses can be provided for customer-specific discounts


Timestamps & Audit Trail

{
  "date_created": "2023-05-23T20:37:33+0000",     // Bag creation time
  "date_last_modified": "2023-05-24T10:15:22+0000", // Last update
  "date_last_checked": "2023-05-24T10:30:45+0000",  // Last parity check
  "date_submitted": "2023-05-24T11:00:12+0000",     // Submission to merchant
  "date_cancelled": "2023-05-25T09:15:30+0000"      // Cancellation time (if applicable)
}

Order Parity: Date the Bag was last checked for updates. This is a part of Order Parity and is used to discover missed or unsent webhooks from the external commerce platforms.


Wallet-Based Checkout Support

Special Handling for Digital Wallets

{
  "wallet_based_checkout": true   // Indicates Apple Pay/Google Pay usage
}

Multi-Merchant Wallet Limitations: Multi-merchant checkout with Apple Pay requires additional work due to the nuances around shipping methods for these orders. The Apple Pay Term Sheet was not built to allow for selecting different shipping methods within the same order.

Recommended Approach:

  • Single merchant: Full wallet experience

  • Multi-merchant: Hybrid approach with payment-only wallet integration


Error Handling & Recovery

Bag-Level Error Management

While errors are reported at the order level, many are bag-specific:

{
  "errors": [
    {
      "entity_type": "BAG",
      "entity_id": "11111",
      "message": "Insufficient inventory for SKU 99999",
      "platform": "SHOPIFY",
      "resolved": false
    }
  ]
}

Common Bag Error Scenarios

  1. Inventory Issues: Items out of stock after cart creation

  2. Platform Connectivity: Merchant's platform temporarily unavailable

  3. Validation Failures: Address, shipping, or payment validation errors

  4. Commission Setup: Missing or invalid commission rate configuration


Platform-Specific Considerations

Shopify Integration

  • Added a new field to the Bag object called external_reference_id. This field will be populated when a successful order is placed on a platform that utilizes vanity numbers on the external orders. This is currently limited to the SHOPIFY platform which hides the true order ID and instead uses a vanity number in customer communication emails.

  • Supports shipping profiles and inventory location restrictions

  • Real-time cart synchronization

BigCommerce Integration

  • Full API cart support

  • Comprehensive tax calculation

  • Multiple payment method support

Magento Integration

  • Quote-based system integration

  • Custom pricing rules support

  • Magento 2 extension version 1.2.0 has been released to the Magento Marketplace. This version adds several new custom endpoints to the Magento REST API that improves the speed and performance when performing Quick Checkout and Cart Estimations.

Platform Limitations

  • Squarespace: Some commerce platforms do not provide the concept of an external cart. For these platforms we emulate the cart experience using cart calculation endpoints to retrieve available shipping methods and to price orders.


Best Practices

Multi-Merchant Considerations

  1. Independent Processing: Each bag can succeed or fail independently

  2. Platform Differences: Account for varying platform capabilities

  3. Commission Rates: Ensure proper commission setup for each merchant

  4. Error Handling: Handle bag-specific errors appropriately

Performance Optimization

  1. Batch Operations: When possible, group operations by merchant

  2. Caching: Cache merchant platform information to reduce API calls

  3. Async Processing: Handle bag submissions asynchronously when possible

Data Consistency

  1. Order Parity: Violet automatically checks for missed webhook updates

  2. Status Synchronization: Bag statuses reflect real merchant platform states

  3. Financial Accuracy: All calculations validated against merchant platforms


Key Differentiators

vs. Traditional Carts

  • Merchant Isolation: Each bag operates independently

  • Platform Fidelity: Mirrors merchant's native cart/order structure

  • Automatic Management: No direct bag manipulation required

vs. Simple Line Items

  • Rich Context: Full merchant and platform information

  • Independent Lifecycle: Each bag can progress through states independently

  • Complete Financial Model: Taxes, shipping, discounts calculated per merchant


This bag architecture enables Violet's unique value proposition: unified multi-merchant checkout that preserves the full functionality and requirements of individual ecommerce platforms while providing a single, consistent API interface for channels to integrate with.

Last updated

Was this helpful?