Skip to main content

Full Cart API Guide

Build a complete checkout flow with Firmly’s Full Cart API. This guide walks through adding items, setting shipping, and completing payment.

When to Use Full Cart API

The Full Cart API supports complex fulfillment scenarios like split shipments and scheduled delivery. Use it when you need:
  • Mix of standard shipping and scheduled delivery
  • Items requiring different fulfillment types
  • Addon services (warranties, protection plans)
  • In-store pickup options
  • Complex shipping scenarios

Prerequisites

Before starting, ensure you have:

Firmly Application ID

Your Application ID from Firmly (contact support if you don’t have one)

Test Merchant Domain

Work with Firmly to enable your app ID for a specific test store

API Client

cURL, Postman, or your preferred HTTP client
Important: Before you can access a merchant’s store, Firmly must configure your app ID to work with that specific domain. Contact our team to set up access to your test merchant.

Step 1: Authenticate

Get an access token for your session:
curl -X POST https://api.firmly.work/api/v1/browser-session \
  -H "x-firmly-app-id: YOUR_APP_ID"
Use the access_token from the response as x-firmly-authorization in all API calls.

Step 2: Browse Products

Discover available products from the merchant:
# List products
curl -X GET "https://api.firmly.work/api/v1/domains-products/staging.luma.gift?size=100" \
  -H "x-firmly-authorization: YOUR_TOKEN"

# Get product details
curl -X GET "https://api.firmly.work/api/v1/domains-products/staging.luma.gift/radiant-tee" \
  -H "x-firmly-authorization: YOUR_TOKEN"

Step 3: Add to Cart

Add a product variant to the cart:
curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/line-items \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "add_to_cart_ref": {
      "variant_id": "WS12-XS-Orange"
    },
    "quantity": 1
  }'

Step 4: Set Shipping Address

Add shipping information and get available shipping methods:
curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/shipping-info \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "John",
    "last_name": "Doe",
    "email": "[email protected]",
    "phone": "555-123-4567",
    "address1": "123 Main St",
    "city": "New York",
    "state_or_province": "NY",
    "postal_code": "10001",
    "country": "US"
  }'

Step 5: Select Shipping Method

Choose a shipping method for each shipment:
curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/shipment/methods \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "shipment_id": "SHIPMENT-ID-FROM-CART",
    "shipping_method_id": "standard"
  }'

Step 6: Complete the Order

Get the public key and complete the order with encrypted payment:
# Get public key for encryption
curl -X GET https://cc.firmly.work/api/v1/payment/key \
  -H "x-firmly-authorization: YOUR_TOKEN"

# Complete order with encrypted card data
curl -X POST https://cc.firmly.work/api/v2/payment/domains/staging.luma.gift/complete-order \
  -H "x-firmly-authorization: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "encrypted_card": "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoidjEifQ...",
    "billing_info": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "address1": "123 Main St",
      "city": "New York",
      "state_or_province": "NY",
      "postal_code": "10001",
      "country": "US"
    }
  }'

Complete Example

// Full checkout flow
async function checkout(domain, productVariantId) {
  // 1. Authenticate
  const authResponse = await fetch('https://api.firmly.work/api/v1/browser-session', {
    method: 'POST',
    headers: { 'x-firmly-app-id': 'YOUR_APP_ID' }
  });
  const { access_token } = await authResponse.json();

  const headers = {
    'x-firmly-authorization': access_token,
    'Content-Type': 'application/json'
  };

  // 2. Add to cart
  const cartResponse = await fetch(
    `https://api.firmly.work/api/v2/domains/${domain}/cart/line-items`,
    {
      method: 'POST',
      headers,
      body: JSON.stringify({
        add_to_cart_ref: { variant_id: productVariantId },
        quantity: 1
      })
    }
  );
  const cart = await cartResponse.json();

  // 3. Set shipping
  const shippingResponse = await fetch(
    `https://api.firmly.work/api/v2/domains/${domain}/cart/shipping-info`,
    {
      method: 'POST',
      headers,
      body: JSON.stringify({
        first_name: 'John',
        last_name: 'Doe',
        email: '[email protected]',
        phone: '555-123-4567',
        address1: '123 Main St',
        city: 'New York',
        state_or_province: 'NY',
        postal_code: '10001',
        country: 'US'
      })
    }
  );
  const cartWithShipping = await shippingResponse.json();

  // 4. Select shipping method
  const shipment = cartWithShipping.shipments[0];
  const shippingMethod = shipment.shipping_method_options[0];
  
  await fetch(
    `https://api.firmly.work/api/v2/domains/${domain}/cart/shipment/methods`,
    {
      method: 'POST',
      headers,
      body: JSON.stringify({
        shipment_id: shipment.shipment_id,
        shipping_method_id: shippingMethod.id
      })
    }
  );

  // 5. Get public key and encrypt card
  const keyResponse = await fetch(
    'https://cc.firmly.work/api/v1/payment/key',
    { headers }
  );
  const { key, kid } = await keyResponse.json();
  
  // Encrypt card data (see Complete Order API docs for encryption details)
  const encryptedCard = await encryptCardData(
    { number: '4242424242424242', cvv: '123', exp_month: '12', exp_year: '2025' },
    key,
    kid
  );

  // 6. Complete order
  const orderResponse = await fetch(
    `https://cc.firmly.work/api/v2/payment/domains/${domain}/complete-order`,
    {
      method: 'POST',
      headers,
      body: JSON.stringify({
        encrypted_card: encryptedCard,
        billing_info: {
          first_name: 'John',
          last_name: 'Doe',
          email: '[email protected]',
          address1: '123 Main St',
          city: 'New York',
          state_or_province: 'NY',
          postal_code: '10001',
          country: 'US'
        }
      })
    }
  );

  const order = await orderResponse.json();
  return order;
}

Key Differences from Simple Cart API

FeatureSimple Cart APIFull Cart API
Cart StructureFlatShipment-based
ShippingOne method for allPer-shipment selection
FulfillmentStandard onlyMultiple types
AddonsNot supportedFull support

Error Handling

Common errors and their meanings:
  • ErrorCartNotFound - Cart session expired
  • ErrorProductNotFound - Invalid variant ID
  • ErrorNotEnoughStock - Item out of stock
  • ErrorCountryNotSupported - Shipping country not available
  • CreditCardDeclined - Payment failed

Next Steps