BigCommerce

EcommerceEnterpriseHeadlessAPI-FirstSaaSMulti-StoreScalability

E-commerce Platform

BigCommerce

Overview

BigCommerce is a growth-focused SaaS e-commerce platform for businesses. Featuring API-first architecture, headless commerce capabilities, and enterprise-grade scalability, it supports multi-store operations and omnichannel selling. With a no-transaction-fee platform design, adoption has expanded among high-growth companies, positioning it as a major player in the headless commerce market projected to reach $13.3 billion by 2025.

Details

Founded in 2009, BigCommerce provides comprehensive e-commerce solutions for rapidly growing businesses. In addition to traditional SaaS platform features, it supports headless commerce, API-first strategies, and modern frontend development through the Catalyst framework, designed to scale flexibly as businesses grow.

Key Features

  • API-First Design: Flexible customization through comprehensive REST and GraphQL APIs
  • Headless Commerce: Complete separation of frontend and backend for high-flexibility development
  • Multi-Store & Multi-Region: Unified management of multiple brands, regions, and languages
  • No Transaction Fees: Pricing model without additional costs based on sales volume
  • Enterprise Scalability: Support for large-scale traffic and order volumes
  • Catalyst Framework: Next-generation storefront with Next.js + React Server Components
  • Omnichannel Integration: Integration with Amazon, eBay, social media, and more
  • Built-in Features: Standard SEO, marketing, and analytics tools included

Supported Payment Methods

  • Stripe, PayPal, Square, Braintree
  • Major credit cards and digital wallets
  • Apple Pay, Google Pay, Amazon Pay
  • Buy now, pay later (Klarna, Affirm)
  • Regional payment methods (via Adyen)
  • Cryptocurrency payments (BitPay integration)

Pros and Cons

Pros

  • No Transaction Fees: No additional costs when sales grow
  • Powerful APIs: Ideal for headless commerce and custom development
  • Rich Built-in Features: Many features available as standard
  • Scalability: Capability to handle large-scale sites
  • SEO Optimization: SEO-friendly structure by default
  • Diverse Integrations: Flexible integration with existing systems and external services
  • Technical Support: 24/7 technical support system

Cons

  • Monthly Costs: Relatively high monthly fees for small businesses
  • Customization Limitations: Some constraints on theme and design freedom
  • Learning Curve: Technical knowledge required for API utilization and headless development
  • App Dependencies: Some features require paid apps
  • International Platform: Limited support for Japan-specific business practices
  • Transaction Limits: Monthly transaction limits based on plan

Reference Links

Implementation Examples

1. Basic Setup

# Install BigCommerce CLI
npm install -g @bigcommerce/stencil-cli

# Configure store token
stencil init
# Enter store URL and access token

# Start development environment
stencil start

# Install BigCommerce API client
npm install @bigcommerce/node-api-client

2. Product Catalog Management

// BigCommerce API client configuration
const BigCommerce = require('@bigcommerce/node-api-client');

const bigCommerce = new BigCommerce({
  clientId: process.env.BC_CLIENT_ID,
  accessToken: process.env.BC_ACCESS_TOKEN,
  storeHash: process.env.BC_STORE_HASH,
  responseType: 'json'
});

// Product creation
async function createProduct(productData) {
  try {
    const product = {
      name: productData.name,
      type: 'physical',
      sku: productData.sku,
      description: productData.description,
      price: productData.price,
      categories: productData.categories,
      weight: productData.weight,
      inventory_level: productData.inventory,
      is_visible: true,
      availability: 'available',
      // SEO settings
      search_keywords: productData.keywords,
      meta_description: productData.metaDescription,
      page_title: productData.pageTitle,
      // Image settings
      images: productData.images.map(imageUrl => ({
        image_url: imageUrl,
        is_thumbnail: false
      }))
    };
    
    const response = await bigCommerce.v3.products.create(product);
    return response.data;
  } catch (error) {
    console.error('Product creation error:', error);
    throw error;
  }
}

// Product variant creation
async function createProductVariants(productId, variants) {
  const variantPromises = variants.map(async (variant) => {
    return await bigCommerce.v3.products.variants(productId).create({
      option_values: variant.options,
      price: variant.price,
      sku: variant.sku,
      inventory_level: variant.inventory,
      weight: variant.weight,
      image_url: variant.imageUrl
    });
  });
  
  return Promise.all(variantPromises);
}

// Inventory management
async function updateInventory(productId, variantId, newLevel) {
  const inventoryUpdate = {
    inventory_level: newLevel,
    inventory_warning_level: Math.floor(newLevel * 0.1) // Warning at 10%
  };
  
  if (variantId) {
    return await bigCommerce.v3.products.variants(productId, variantId).update(inventoryUpdate);
  } else {
    return await bigCommerce.v3.products(productId).update(inventoryUpdate);
  }
}

3. Payment Integration

// BigCommerce Payments API integration
class PaymentService {
  constructor(storeHash, accessToken) {
    this.storeHash = storeHash;
    this.accessToken = accessToken;
    this.paymentsApiUrl = `https://payments.bigcommerce.com/stores/${storeHash}`;
  }
  
  // Create payment access token
  async createPaymentAccessToken(orderId) {
    const response = await fetch(
      `https://api.bigcommerce.com/stores/${this.storeHash}/v3/payments/access_tokens`,
      {
        method: 'POST',
        headers: {
          'X-Auth-Token': this.accessToken,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify({
          order: { id: orderId }
        })
      }
    );
    
    const data = await response.json();
    return data.data.token;
  }
  
  // Get available payment methods
  async getPaymentMethods(orderId) {
    const response = await fetch(
      `https://api.bigcommerce.com/stores/${this.storeHash}/v3/payments/methods?order_id=${orderId}`,
      {
        headers: {
          'X-Auth-Token': this.accessToken,
          'Accept': 'application/json'
        }
      }
    );
    
    return await response.json();
  }
  
  // Process payment
  async processPayment(paymentToken, paymentData) {
    const response = await fetch(`${this.paymentsApiUrl}/payments`, {
      method: 'POST',
      headers: {
        'Authorization': `PAT ${paymentToken}`,
        'Accept': 'application/vnd.bc.v1+json',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        payment: {
          instrument: {
            type: paymentData.type, // 'card', 'stored_card', 'paypal' etc.
            number: paymentData.cardNumber,
            cardholder_name: paymentData.cardholderName,
            expiry_month: paymentData.expiryMonth,
            expiry_year: paymentData.expiryYear,
            verification_value: paymentData.cvv
          },
          payment_method_id: paymentData.paymentMethodId,
          save_instrument: paymentData.saveCard || false
        }
      })
    });
    
    const result = await response.json();
    
    if (result.data.status === 'success') {
      return {
        success: true,
        transactionId: result.data.id,
        transactionType: result.data.transaction_type
      };
    } else {
      throw new Error(`Payment processing failed: ${result.data.status}`);
    }
  }
}

4. Order Management System

// Order management class
class OrderManager {
  constructor(bigCommerceClient) {
    this.bc = bigCommerceClient;
  }
  
  // Get order list
  async getOrders(filters = {}) {
    const queryParams = new URLSearchParams();
    
    if (filters.status) queryParams.append('status_id', filters.status);
    if (filters.customerId) queryParams.append('customer_id', filters.customerId);
    if (filters.dateFrom) queryParams.append('min_date_created', filters.dateFrom);
    if (filters.dateTo) queryParams.append('max_date_created', filters.dateTo);
    
    const orders = await this.bc.v2.orders.list({
      include: ['products', 'shipping_addresses', 'billing_address'],
      ...Object.fromEntries(queryParams)
    });
    
    return orders.data;
  }
  
  // Get order details
  async getOrderDetails(orderId) {
    const [order, products, shipments] = await Promise.all([
      this.bc.v2.orders(orderId).get(),
      this.bc.v2.orders(orderId).products.list(),
      this.bc.v2.orders(orderId).shipments.list()
    ]);
    
    return {
      order: order.data,
      products: products.data,
      shipments: shipments.data
    };
  }
  
  // Update order status
  async updateOrderStatus(orderId, statusId, message = '') {
    const orderUpdate = {
      status_id: statusId
    };
    
    if (message) {
      orderUpdate.customer_message = message;
    }
    
    return await this.bc.v2.orders(orderId).update(orderUpdate);
  }
  
  // Create shipment
  async createShipment(orderId, shipmentData) {
    const shipment = {
      tracking_number: shipmentData.trackingNumber,
      tracking_carrier: shipmentData.carrier,
      items: shipmentData.items.map(item => ({
        order_product_id: item.orderProductId,
        quantity: item.quantity
      }))
    };
    
    const response = await this.bc.v2.orders(orderId).shipments.create(shipment);
    
    // Send shipping notification email to customer
    if (shipmentData.sendNotification) {
      await this.sendShippingNotification(orderId, response.data);
    }
    
    return response.data;
  }
  
  // Process refund
  async processRefund(orderId, refundData) {
    const refund = {
      items: refundData.items,
      reason: refundData.reason,
      message: refundData.message
    };
    
    return await this.bc.v3.orders(orderId).refunds.create(refund);
  }
}

5. Headless Commerce Implementation

// Next.js + BigCommerce GraphQL API integration
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

// GraphQL client configuration
const client = new ApolloClient({
  uri: `https://store-${process.env.BC_STORE_HASH}.mybigcommerce.com/graphql`,
  cache: new InMemoryCache(),
  headers: {
    'Authorization': `Bearer ${process.env.BC_STOREFRONT_TOKEN}`
  }
});

// Product list query
const GET_PRODUCTS = gql`
  query GetProducts($first: Int, $after: String, $filters: ProductFiltersInput) {
    site {
      products(first: $first, after: $after, filters: $filters) {
        pageInfo {
          hasNextPage
          hasPreviousPage
          startCursor
          endCursor
        }
        edges {
          node {
            entityId
            name
            sku
            plainTextDescription
            prices {
              price {
                value
                currencyCode
              }
              salePrice {
                value
                currencyCode
              }
            }
            defaultImage {
              url(width: 300, height: 300)
              altText
            }
            brand {
              name
            }
            categories {
              edges {
                node {
                  name
                  path
                }
              }
            }
          }
        }
      }
    }
  }
`;

// React component example
export default function ProductListing({ categoryId, searchTerm }) {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetchProducts();
  }, [categoryId, searchTerm]);
  
  const fetchProducts = async () => {
    setLoading(true);
    
    const filters = {};
    if (categoryId) filters.categoryEntityIds = [categoryId];
    if (searchTerm) filters.searchTerm = searchTerm;
    
    try {
      const { data } = await client.query({
        query: GET_PRODUCTS,
        variables: {
          first: 20,
          filters
        }
      });
      
      setProducts(data.site.products.edges.map(edge => edge.node));
    } catch (error) {
      console.error('Product fetch error:', error);
    } finally {
      setLoading(false);
    }
  };
  
  if (loading) return <div>Loading...</div>;
  
  return (
    <div className="product-grid">
      {products.map(product => (
        <ProductCard key={product.entityId} product={product} />
      ))}
    </div>
  );
}

// Cart operations (Storefront API)
export class CartService {
  static async createCart(lineItems) {
    const CREATE_CART = gql`
      mutation CreateCart($createCartInput: CreateCartInput!) {
        cart {
          createCart(input: $createCartInput) {
            cart {
              entityId
              lineItems {
                physicalItems {
                  entityId
                  name
                  quantity
                  originalPrice {
                    value
                  }
                }
              }
            }
          }
        }
      }
    `;
    
    const { data } = await client.mutate({
      mutation: CREATE_CART,
      variables: {
        createCartInput: {
          lineItems
        }
      }
    });
    
    return data.cart.createCart.cart;
  }
  
  static async addCartItems(cartId, lineItems) {
    const ADD_CART_LINE_ITEMS = gql`
      mutation AddCartLineItems($addCartLineItemsInput: AddCartLineItemsInput!) {
        cart {
          addCartLineItems(input: $addCartLineItemsInput) {
            cart {
              entityId
              lineItems {
                physicalItems {
                  entityId
                  name
                  quantity
                }
              }
            }
          }
        }
      }
    `;
    
    const { data } = await client.mutate({
      mutation: ADD_CART_LINE_ITEMS,
      variables: {
        addCartLineItemsInput: {
          cartEntityId: cartId,
          data: {
            lineItems
          }
        }
      }
    });
    
    return data.cart.addCartLineItems.cart;
  }
}

6. Webhook & Analytics Integration

// Webhook handler (Express.js)
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

// Webhook signature verification
function verifyWebhookSignature(data, signature, secret) {
  const hash = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(data))
    .digest('hex');
  
  return hash === signature;
}

// Order created webhook
app.post('/webhooks/order/created', (req, res) => {
  const signature = req.get('X-BC-Webhook-Signature');
  const isValid = verifyWebhookSignature(
    req.body, 
    signature, 
    process.env.BC_WEBHOOK_SECRET
  );
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  const orderData = req.body;
  
  // Order processing logic
  processNewOrder(orderData);
  
  res.status(200).send('OK');
});

// Product updated webhook
app.post('/webhooks/product/updated', (req, res) => {
  const productData = req.body;
  
  // Inventory sync, search index update, etc.
  updateProductData(productData);
  
  res.status(200).send('OK');
});

// Analytics data collection
class AnalyticsService {
  static async trackEvent(eventType, eventData) {
    // Send Google Analytics 4 event
    await fetch('https://www.google-analytics.com/mp/collect', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        client_id: eventData.clientId,
        events: [{
          name: eventType,
          params: eventData.params
        }]
      })
    });
  }
  
  static async getSalesReport(startDate, endDate) {
    // BigCommerce Analytics API (V2)
    const response = await bigCommerce.v2.analytics.get({
      date_from: startDate,
      date_to: endDate,
      dimensions: ['date', 'product_id'],
      metrics: ['revenue', 'orders', 'units_sold']
    });
    
    return response.data;
  }
  
  static async getCustomerInsights(customerId) {
    const [orders, products] = await Promise.all([
      bigCommerce.v2.orders.list({ customer_id: customerId }),
      bigCommerce.v2.customers(customerId).get()
    ]);
    
    const totalValue = orders.data.reduce((sum, order) => sum + parseFloat(order.total_inc_tax), 0);
    const avgOrderValue = totalValue / orders.data.length;
    
    return {
      customer: products.data,
      totalOrders: orders.data.length,
      totalValue,
      avgOrderValue,
      lastOrderDate: orders.data[0]?.date_created
    };
  }
}