BigCommerce
Eコマースプラットフォーム
BigCommerce
概要
BigCommerceは成長志向の企業向けSaaS型Eコマースプラットフォームです。API-ファーストアーキテクチャ、ヘッドレスコマース機能、エンタープライズグレードのスケーラビリティを特徴とし、多店舗運営、オムニチャネル販売をサポートします。取引手数料なしのプラットフォーム設計により、高成長企業での採用が拡大しており、2025年には133億ドル規模が見込まれるヘッドレスコマース市場での主要プレイヤーとなっています。
詳細
BigCommerceは2009年に設立され、急成長企業向けの包括的なEコマースソリューションを提供しています。従来のSaaS型プラットフォームに加え、ヘッドレスコマース、API-ファースト戦略、Catalyst フレームワークによる最新のフロントエンド開発に対応し、企業の成長に合わせて柔軟にスケールできる設計となっています。
主な特徴
- API-ファースト設計: 包括的なREST・GraphQL APIによる柔軟なカスタマイズ
- ヘッドレスコマース: フロントエンドとバックエンドの完全分離による自由度の高い開発
- 多店舗・多地域対応: 複数ブランド・地域・言語の統合管理
- 取引手数料なし: 売上に応じた追加費用なしの料金体系
- エンタープライズスケーラビリティ: 大規模トラフィック・注文量への対応
- Catalyst フレームワーク: Next.js + React Server Componentsによる次世代ストアフロント
- オムニチャネル統合: Amazon、eBay、ソーシャルメディア等との統合
- 内蔵機能: SEO、マーケティング、分析ツールを標準搭載
対応決済方法
- Stripe、PayPal、Square、Braintree
- 主要クレジットカード・デジタルウォレット
- Apple Pay、Google Pay、Amazon Pay
- Buy now, pay later(Klarna、Affirm)
- 地域特化決済(Adyen経由)
- 仮想通貨決済(BitPay連携)
メリット・デメリット
メリット
- 取引手数料なし: 売上成長時の追加コストが発生しない
- 強力なAPI: ヘッドレスコマース・カスタム開発に最適
- 内蔵機能の豊富さ: 多くの機能が標準で利用可能
- スケーラビリティ: 大規模サイトへの対応力
- SEO最適化: 標準でSEOフレンドリーな構造
- 多様な統合: 既存システム・外部サービスとの柔軟な連携
- 技術サポート: 24/7の技術サポート体制
デメリット
- 月額費用: 小規模事業者には比較的高い月額料金
- カスタマイズ制限: テーマ・デザインの自由度に一部制約
- 学習コスト: API活用・ヘッドレス開発には技術的知識が必要
- アプリ依存: 一部機能は有料アプリが必要
- 海外発: 日本特有の商慣習への対応が限定的
- トランザクション制限: プランによる月間トランザクション上限
参考ページ
- BigCommerce公式サイト
- BigCommerce Developer Documentation
- BigCommerce API Documentation
- BigCommerce App Marketplace
- BigCommerce Support Center
実装例
1. 基本セットアップ
# BigCommerce CLI インストール
npm install -g @bigcommerce/stencil-cli
# ストアトークン設定
stencil init
# ストアURL、アクセストークンを入力
# 開発環境起動
stencil start
# BigCommerce APIクライアント インストール
npm install @bigcommerce/node-api-client
2. 商品カタログ管理
// BigCommerce API クライアント設定
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'
});
// 商品作成
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設定
search_keywords: productData.keywords,
meta_description: productData.metaDescription,
page_title: productData.pageTitle,
// 画像設定
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('商品作成エラー:', error);
throw error;
}
}
// 商品バリエーション作成
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);
}
// 在庫管理
async function updateInventory(productId, variantId, newLevel) {
const inventoryUpdate = {
inventory_level: newLevel,
inventory_warning_level: Math.floor(newLevel * 0.1) // 10%で警告
};
if (variantId) {
return await bigCommerce.v3.products.variants(productId, variantId).update(inventoryUpdate);
} else {
return await bigCommerce.v3.products(productId).update(inventoryUpdate);
}
}
3. 決済統合
// BigCommerce Payments API 統合
class PaymentService {
constructor(storeHash, accessToken) {
this.storeHash = storeHash;
this.accessToken = accessToken;
this.paymentsApiUrl = `https://payments.bigcommerce.com/stores/${storeHash}`;
}
// 決済アクセストークン取得
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;
}
// 利用可能決済方法取得
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();
}
// 決済処理
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(`決済処理に失敗: ${result.data.status}`);
}
}
}
4. 注文管理システム
// 注文管理クラス
class OrderManager {
constructor(bigCommerceClient) {
this.bc = bigCommerceClient;
}
// 注文一覧取得
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;
}
// 注文詳細取得
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
};
}
// 注文ステータス更新
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);
}
// 発送処理
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);
// 顧客に発送通知メール送信
if (shipmentData.sendNotification) {
await this.sendShippingNotification(orderId, response.data);
}
return response.data;
}
// 返金処理
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. ヘッドレスコマース実装
// Next.js + BigCommerce GraphQL API 統合
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
// GraphQL クライアント設定
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}`
}
});
// 商品一覧取得クエリ
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 コンポーネント例
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('商品取得エラー:', error);
} finally {
setLoading(false);
}
};
if (loading) return <div>読み込み中...</div>;
return (
<div className="product-grid">
{products.map(product => (
<ProductCard key={product.entityId} product={product} />
))}
</div>
);
}
// カート操作(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・分析統合
// Webhook ハンドラー (Express.js)
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Webhook 署名検証
function verifyWebhookSignature(data, signature, secret) {
const hash = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(data))
.digest('hex');
return hash === signature;
}
// 注文作成 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;
// 注文処理ロジック
processNewOrder(orderData);
res.status(200).send('OK');
});
// 商品更新 Webhook
app.post('/webhooks/product/updated', (req, res) => {
const productData = req.body;
// 在庫同期、検索インデックス更新等
updateProductData(productData);
res.status(200).send('OK');
});
// 分析データ収集
class AnalyticsService {
static async trackEvent(eventType, eventData) {
// Google Analytics 4 イベント送信
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
};
}
}