Payments
Quick Start

Quick Start: Accept Payments

TL;DR: Create payment intent with order data → Customer pays → BareCommerce creates order from webhook

BareCommerce is payment-provider-first. Your payment provider (Stripe, PayPal, Square) is the source of truth. BareCommerce creates orders automatically from payment webhooks.

How It Works

BareCommerce doesn't create orders via API. Instead:

  1. You create a payment intent/session with all order data embedded
  2. Customer pays
  3. Payment provider sends webhook to BareCommerce
  4. BareCommerce ingests the order automatically
  5. Order is immediately paid (no pending state)
Your Frontend/Backend

Create PaymentIntent/Session (with order metadata)

Payment Provider (Stripe/PayPal/Square)

Customer completes payment

Provider sends webhook → BareCommerce

✅ Order created (automatically paid)

The 4-Step Flow

1. Collect Order Information

Your frontend gathers cart items, customer info, and addresses:

const orderData = {
  customerId: 'cust_12345',  // From your customer system
  storeId: 'store_xyz',
  items: [
    { productId: 'prod_1', quantity: 2, unitPrice: '29.99' },
    { productId: 'prod_2', quantity: 1, unitPrice: '49.99' }
  ],
  subtotal: '109.97',
  tax: '8.80',
  shipping: '10.00',
  discount: '0.00',
  total: '128.77',
  currency: 'USD',
  shippingAddress: {
    address1: '123 Main St',
    city: 'San Francisco',
    region: 'CA',
    postalCode: '94103',
    country: 'US'
  }
};

2. Create Payment Intent (Server-Side)

Your backend creates a payment intent with this order data in metadata:

// Your backend endpoint
const paymentIntent = await stripe.paymentIntents.create({
  amount: Math.round(parseFloat(orderData.total) * 100), // cents
  currency: orderData.currency.toLowerCase(),
  metadata: {
    store_id: orderData.storeId,
    customer_id: orderData.customerId,
    items: JSON.stringify(orderData.items),
    subtotal: orderData.subtotal,
    tax: orderData.tax,
    shipping: orderData.shipping,
    discount: orderData.discount,
    shippingAddress: JSON.stringify(orderData.shippingAddress),
  },
  automatic_payment_methods: { enabled: true }
});
 
return { clientSecret: paymentIntent.client_secret };

3. Customer Completes Payment

Your frontend collects payment info and confirms:

// Frontend payment collection
const result = await stripe.confirmCardPayment(clientSecret, {
  payment_method: {
    card: cardElement,
    billing_details: { name: 'Customer Name' }
  }
});
 
if (result.paymentIntent?.status === 'succeeded') {
  // Order is already created in BareCommerce!
  // Just wait for webhook processing
  await new Promise(resolve => setTimeout(resolve, 2000));
  redirectToOrderConfirmation();
}

4. Done!

BareCommerce automatically:

  • ✅ Receives webhook from payment provider
  • ✅ Verifies signature
  • ✅ Creates order with status paid
  • ✅ Records payment info
  • ✅ Stores order data

No API calls needed. Orders are created automatically.

Order Status Flow

paid → fulfilled → shipped
  ↘ refunded (if payment refunded)

Unlike traditional e-commerce, there is no pending status. Orders go directly to paid when payment succeeds.

Choose Your Provider

ProviderGuide
StripeFull Stripe Setup
PayPalFull PayPal Setup
SquareFull Square Setup

Environment Variables

# Payment Provider Keys
STRIPE_SECRET_KEY=sk_test_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
 
PAYPAL_CLIENT_ID=xxxxx
PAYPAL_CLIENT_SECRET=xxxxx
PAYPAL_WEBHOOK_ID=xxxxx
 
SQUARE_ACCESS_TOKEN=xxxxx
SQUARE_LOCATION_ID=xxxxx
SQUARE_WEBHOOK_SIGNATURE_KEY=xxxxx

Test Cards (Stripe)

Card NumberResult
4242 4242 4242 4242Success
4000 0000 0000 0002Declined
4000 0025 0000 3155Requires authentication

Use any future expiry and any 3-digit CVC.

Architecture: Payment-Provider-First

BareCommerce uses a unique architecture:

  • Payment provider is the source of truth — Stripe/PayPal/Square record the actual payment
  • BareCommerce ingests via webhooks — Orders are created when webhooks arrive
  • Read-only for merchants — Merchants read orders via GET API, but can't directly POST/PUT orders
  • Automatic order creation — No manual API calls needed to create orders

This design ensures:

  • Payment data is always authoritative
  • Orders can't be created without actual payment
  • No race conditions between payment and order creation
  • Webhooks provide guaranteed delivery

Why No Direct Order Creation?

Traditional e-commerce systems allow:

  1. Create order (pending state)
  2. Process payment
  3. Update order to paid

BareCommerce skips step 1:

  1. Create order (payment provider processes first)
  2. Process payment
  3. Webhook creates order (already paid)

This eliminates:

  • Abandoned pending orders
  • Inconsistency between payment provider and order database
  • Complex state management

Next Steps