● Available Now
E-commerce

Shopify Integration

When a customer orders on Shopify, Dark Obsidian automatically creates the sale, deducts inventory, adds the customer to CRM, awards loyalty points, and updates all financial reports - in real time.

How It Works

Shopify sends a webhook event when an order is paid. Your server (or Zapier) receives that event and calls the Dark Obsidian POST /orders endpoint. One API call triggers all side effects:

Prerequisites

Get your API key: Settings → Developer → API Keys → Create Key (or via the Developer Portal).

Option 1: Shopify Webhooks (No-Code Server)

The fastest setup. Requires a server that can receive HTTP POST requests (a $5/mo VPS, Netlify Functions, Vercel Edge Functions, or Cloudflare Workers all work).

Step 1 - Create a webhook listener

Create a file called shopify-webhook.js and deploy it to your server or serverless function:

// shopify-webhook.js - Node.js / Vercel / Netlify / Cloudflare Workers
const DO_API_KEY = process.env.DO_API_KEY // do_live_...
const DO_BASE    = 'https://qatxonlxvtgxvqjgfxpl.supabase.co/functions/v1/api'

// Map Shopify SKUs → Dark Obsidian product UUIDs
// Build this map once by calling GET /products and matching SKUs
async function getProductId(sku) {
  const res = await fetch(`${DO_BASE}/products?sku=${sku}`, {
    headers: { 'Authorization': `Bearer ${DO_API_KEY}` }
  })
  const data = await res.json()
  return data.data?.[0]?.id ?? null
}

export default async function handler(req, res) {
  if (req.method !== 'POST') return res.status(405).end()

  const order = req.body  // Shopify order object

  // Only process paid orders
  if (order.financial_status !== 'paid') return res.json({ skipped: true })

  // Build items array - resolve SKUs to Dark Obsidian product IDs
  const items = await Promise.all(
    order.line_items.map(async item => ({
      product_id: await getProductId(item.sku),
      quantity:   item.quantity,
      unit_price: parseFloat(item.price)
    }))
  )
  const validItems = items.filter(i => i.product_id)  // skip unmatched

  if (!validItems.length) return res.json({ skipped: 'no matching products' })

  // Create the sale in Dark Obsidian - one call does everything
  const doRes = await fetch(`${DO_BASE}/orders`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${DO_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      customer: {
        name:  `${order.customer?.first_name} ${order.customer?.last_name}`.trim(),
        email: order.customer?.email,
        phone: order.customer?.phone
      },
      items: validItems,
      payment_method: order.payment_gateway || 'card',
      send_invoice:   false,  // Shopify sends its own receipt
      notes: `Shopify order #${order.order_number}`
    })
  })

  const result = await doRes.json()
  res.json({ dark_obsidian: result.data })
}

Step 2 - Register the webhook in Shopify

  1. In Shopify Admin: Settings → Notifications → Webhooks
  2. Click Create webhook
  3. Event: Order payment
  4. URL: your deployed function URL (e.g. https://mysite.vercel.app/api/shopify-webhook)
  5. Format: JSON
  6. Click Save
✓ Done. Every paid Shopify order now automatically creates a sale in Dark Obsidian, deducts stock, creates/updates the customer in CRM, and awards loyalty points.

Option 2: Custom Shopify App (Full Control)

Use our JavaScript SDK inside a Shopify custom app for more control - product syncing, real-time inventory display, and bidirectional data flow.

// Install the SDK
npm install dark-obsidian

// shopify-app.js
import DarkObsidian from 'dark-obsidian'

const client = new DarkObsidian({
  apiKey: process.env.DO_API_KEY
})

// Sync a Shopify order to Dark Obsidian
async function syncOrder(shopifyOrder) {
  const items = shopifyOrder.line_items.map(item => ({
    product_id: item.properties?.find(p => p.name === 'do_id')?.value,
    quantity:   item.quantity,
    unit_price: parseFloat(item.price)
  })).filter(i => i.product_id)

  return client.orders.create({
    customer: {
      name:  shopifyOrder.customer?.first_name + ' ' + shopifyOrder.customer?.last_name,
      email: shopifyOrder.customer?.email
    },
    items,
    payment_method: 'card',
    send_invoice:   false
  })
}

// Show live stock on a Shopify product page
async function showLiveStock(productId) {
  const product = await client.products.get(productId)
  document.getElementById('stock-count').textContent =
    product.stock > 0 ? `${product.stock} in stock` : 'Out of stock'
}

Option 3: Zapier (Zero Code)

No server needed. Zapier connects Shopify to Dark Obsidian in minutes.

1
Create a new Zap in Zapier.
Trigger: Shopify → New Paid Order
2
Action: Webhooks by Zapier → POST
URL: https://qatxonlxvtgxvqjgfxpl.supabase.co/functions/v1/api/orders
Header: Authorization: Bearer do_live_YOUR_KEY
Data type: JSON
3
Map the fields:
items → manually set your product IDs + map quantity
customer.email → Shopify customer email
payment_method → "card"
4
Turn on the Zap. Test it with a sample order.

What Gets Synced

Shopify Event Dark Obsidian Action
Order paid Create sale + deduct stock + award loyalty
New customer Add customer to CRM (via order create)
Product updated Update product in inventory (via PUT /products)
Stock low (DO → Shopify) Dark Obsidian fires stock.low webhook → update Shopify inventory