Frontend Integration Guide
Ready to connect your application to BareCommerce Core? This guide covers authentication, API routes, integration patterns, and practical examples.
System Architecture
Key Points:
- Your frontend communicates with BareCommerce API
- Payment providers are external (Stripe, PayPal, Square)
- Orders are created automatically from webhooks, not API calls
- All data is stored in BareCommerce (you don't need a database)
- Files are stored in Cloudflare R2 with no egress fees
Key Understanding: Orders Are Webhook-Driven
Important: BareCommerce Core creates orders exclusively via webhooks from payment providers. There is no API endpoint to manually create orders. You cannot POST to create an order.
Instead:
- Your frontend creates a Payment Intent with order metadata
- Payment provider processes the payment
- Payment provider sends a webhook to BareCommerce
- BareCommerce automatically creates the order
- Your frontend fetches the order via GET endpoint
The Order Flow
Storefront
↓
Customer adds items to cart
↓
Creates Payment Intent (with order metadata)
↓
Payment Provider (Stripe/PayPal/Square)
↓
Customer completes payment
↓
Payment Provider sends webhook
↓
BareCommerce creates order automatically
↓
Frontend fetches order via GET /orders
↓
Show confirmation to customerAuthentication
For Merchant Dashboard
Session-based login:
POST /api/auth/merchant/login
{
"email": "merchant@example.com",
"password": "password"
}Response sets barecommerce_session cookie. OAuth (GitHub, Google) also supported.
For Storefronts & Integrations
API key authentication:
X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxAPI keys are scoped to stores and limited by permissions.
Core API Routes
Authentication
POST /api/auth/merchant/signup
POST /api/auth/merchant/login
POST /api/auth/merchant/logout
GET /api/auth/merchant/me
POST /api/auth/merchant/avatar (v1.7 - Upload avatar)
GET /api/auth/github
GET /api/auth/googleProducts
GET /api/stores/{storeId}/products
POST /api/stores/{storeId}/products
GET /api/stores/{storeId}/products/{id}
PUT /api/stores/{storeId}/products/{id}
DELETE /api/stores/{storeId}/products/{id}
POST /api/stores/{storeId}/products/bulk (v1.7 - Bulk operations)
GET /api/stores/{storeId}/products/attributes (v1.7 - Get attributes)
GET /api/stores/{storeId}/products/import-schema (v1.7 - Import schema)
GET /api/stores/{storeId}/products/by-variant-group?variantGroupId=xxx
GET /api/stores/{storeId}/products/by-attributes?color=red&size=mCategories
GET /api/stores/{storeId}/categories
POST /api/stores/{storeId}/categories
GET /api/stores/{storeId}/categories/{id}
PUT /api/stores/{storeId}/categories/{id}
DELETE /api/stores/{storeId}/categories/{id}Customers
GET /api/stores/{storeId}/customers
POST /api/stores/{storeId}/customers
GET /api/stores/{storeId}/customers/{id}
PUT /api/stores/{storeId}/customers/{id}
DELETE /api/stores/{storeId}/customers/{id}Orders (Read-Only)
GET /api/stores/{storeId}/orders
GET /api/stores/{storeId}/orders/{id}⚠️ Important: Orders are created exclusively via payment provider webhooks. There are no POST/PUT/DELETE endpoints for orders.
Media
GET /api/stores/{storeId}/media
POST /api/stores/{storeId}/media
GET /api/stores/{storeId}/media/{id}
PUT /api/stores/{storeId}/media/{id}
DELETE /api/stores/{storeId}/media/{id}Pages
GET /api/stores/{storeId}/pages
POST /api/stores/{storeId}/pages
GET /api/stores/{storeId}/pages/{id}
PUT /api/stores/{storeId}/pages/{id}
DELETE /api/stores/{storeId}/pages/{id}Webhooks
GET /api/stores/{storeId}/webhooks
POST /api/stores/{storeId}/webhooks
GET /api/stores/{storeId}/webhooks/{id}
PUT /api/stores/{storeId}/webhooks/{id}
DELETE /api/stores/{storeId}/webhooks/{id}API Keys
GET /api/stores/{storeId}/api-keys
POST /api/stores/{storeId}/api-keys
GET /api/stores/{storeId}/api-keys/{id}
PUT /api/stores/{storeId}/api-keys/{id}
DELETE /api/stores/{storeId}/api-keys/{id}Audit Logs
GET /api/stores/{storeId}/audit-logs
GET /api/stores/{storeId}/audit-logs/{id}Response Format
Single Resource:
{
"item": { ...fields... }
}List:
{
"items": [...],
"total": 100
}Error:
{
"error": {
"code": "ERROR_CODE",
"message": "Human readable message",
"details": { ...context... }
}
}Common Error Codes
| Code | HTTP | Description |
|---|---|---|
| VALIDATION_ERROR | 400 | Invalid field values |
| UNAUTHORIZED | 401 | Auth required |
| FORBIDDEN | 403 | Insufficient permissions |
| NOT_FOUND | 404 | Resource not found |
| CONFLICT | 409 | Duplicate or state conflict |
| RATE_LIMITED | 429 | Too many requests |
| INTERNAL_ERROR | 500 | Server error |
Database Schema at a Glance
Products
id, storeId, title, slug, price, sku, barcode
variantGroupId (groups variants)
attributes (JSON: color, size, etc)
status (draft|published|archived|deleted)
stock, trackStock, allowBackorder
categoryIds, mediaIds (JSON arrays)Orders
id, orderNumber (auto-generated)
customerId, storeId
status (pending|paid|fulfilled|cancelled)
total, subtotal, tax, shipping, discount
currency (default: USD)
paymentProvider, paymentId, paymentStatus
items (OrderItem[])
shippingAddress, billingAddress (JSON)
placedAt, paidAt, fulfilledAt, cancelledAtVariants
Variants are just Products with the same variantGroupId:
- Product 1: Blue Shirt / M
- Product 2: Blue Shirt / L
- Product 3: Red Shirt / MQuery with:
GET /api/stores/{storeId}/products/by-variant-group?variantGroupId=vg_123Integration Patterns
Pattern 1: Public Storefront
Your Job:
- Fetch and display products
- Build shopping cart
- Create Payment Intent with order metadata
- Send to payment provider
BareCommerce Job:
- Receive webhook from payment provider
- Create order automatically
- Make available via GET /orders
Flow:
1. Display products
2. Customer adds items
3. Create Payment Intent
4. Payment Provider
5. Payment webhook
6. BareCommerce creates order
7. GET /orders to fetch
8. Show confirmationPattern 2: Merchant Dashboard
Operations:
- Create/read/update/delete products
- Create/read/update/delete categories
- View orders (read-only)
- Manage customers
- View activity logs
- Configure store
Auth: Session (merchant login)
Pattern 3: Headless / Programmatic
Operations:
- Fetch products
- Listen to webhooks
- Read orders
- Sync to custom systems
Auth: API Key
Common Tasks
Fetch Products
const response = await fetch(
`https://api.barecommercecore.com/api/stores/${storeId}/products?status=published&limit=20`,
{ headers: { "X-API-Key": apiKey } }
);
const { items } = await response.json();Fetch Variants
const response = await fetch(
`https://api.barecommercecore.com/api/stores/${storeId}/products/by-variant-group?variantGroupId=vg_123`,
{ headers: { "X-API-Key": apiKey } }
);
const { items: variants } = await response.json();Fetch Orders
const response = await fetch(
`https://api.barecommercecore.com/api/stores/${storeId}/orders?status=paid`,
{ headers: { "X-API-Key": apiKey } }
);
const { items: orders } = await response.json();Create Payment Intent with Metadata
const stripe = require("stripe")(STRIPE_SECRET_KEY);
const paymentIntent = await stripe.paymentIntents.create({
amount: 9999, // $99.99 in cents
currency: "usd",
metadata: {
store_id: storeId,
customer_id: customerId,
items: JSON.stringify([
{ productId: "prod_1", quantity: 2, unitPrice: "29.99" }
]),
subtotal: "59.98",
tax: "4.80",
shipping: "10.00"
}
});
return { clientSecret: paymentIntent.client_secret };Webhooks
Events You'll Receive
order.created ← Order created from payment
order.updated - Order status changed
product.created - New product
product.updated - Product changed
category.created - New category
customer.created - New customerWebhook Payload
{
"id": "webhook_event_id",
"event": "order.created",
"timestamp": "2024-01-15T10:30:00Z",
"storeId": "store_123",
"data": {
"id": "order_123",
"orderNumber": "ORD-000001",
"customerId": "cust_456",
"total": "99.99",
"status": "paid",
"items": [...],
...all order fields...
}
}Verify Webhook Signature
All webhooks are signed with HMAC-SHA256:
import crypto from "crypto";
function verifySignature(body: string, signature: string, secret: string) {
const hash = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(hash),
Buffer.from(signature)
);
}
export async function POST(request: Request) {
const signature = request.headers.get("x-signature");
const body = await request.text();
if (!verifySignature(body, signature!, WEBHOOK_SECRET)) {
return Response.json({ error: "Invalid" }, { status: 401 });
}
const event = JSON.parse(body);
if (event.event === "order.created") {
const order = event.data;
// Send confirmation email
await sendOrderConfirmation(order);
// Notify fulfillment
await notifyWarehouse(order);
// Update inventory
await updateInventory(order.items);
}
return Response.json({ ok: true });
}Pagination
All list endpoints support:
?limit=50&offset=0limit: 1-200 (default 50)offset: Skip count (default 0)
Error Handling
async function apiCall(url: string, options: RequestInit) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const { error } = await response.json();
switch (error.code) {
case "VALIDATION_ERROR":
error.details?.forEach(({ field, reason }) => {
console.error(`${field}: ${reason}`);
});
break;
case "UNAUTHORIZED":
redirect("/login");
break;
case "RATE_LIMITED":
await new Promise(r => setTimeout(r, 1000));
return apiCall(url, options); // Retry
break;
default:
console.error(error.message);
}
throw new Error(error.code);
}
return response.json();
} catch (err) {
console.error("API error:", err);
throw err;
}
}Integration Checklist
- Understand orders are webhook-driven only
- Set up payment provider (Stripe/PayPal/Square)
- Create API key or set up session auth
- Implement product fetching
- Implement category browsing
- Implement variant selection
- Build shopping cart
- Create Payment Intent with metadata
- Build checkout flow
- Implement webhook receiver
- Verify webhook signatures
- Handle order.created webhook
- Fetch orders via GET /orders
- Show order confirmation
- Implement error handling
- Test in payment provider test mode
- Deploy to staging
- Test end-to-end
- Deploy to production
- Switch to live API keys
- Monitor webhook delivery
Next Steps
- Read Products, Variants & Categories for variant details
- Check Best Practices for security tips
- See Getting Started for payment setup
- Join Discord (opens in a new tab) for support
For detailed technical specs, see the FRONTEND_INTEGRATION_GUIDE.md in the barecommerce-core repository.