Workflow

B2B Order-to-Cash

Complete business workflow from customer onboarding through order placement, fulfillment, invoicing, and payment collection. Covers 12 services working together.

1
Customer Setup
2
Catalog Browse
3
Cart & Pricing
4
Order Placement
5
Stock Reservation
6
Invoice Generation
7
Payment Processing
8
Warehouse Picking
9
Shipment & Tracking
10
Order Completion
11
Audit Trail

Step 1: Bootstrap — Services, Catalog, Customer

import { initDatabase, createServices } from "commercio";

await initDatabase({
  dialect: "postgresql",
  connectionString: process.env.DATABASE_URL,
  runMigrations: true,
});

const services = createServices();

// ── 1a. Build the catalog ──────────────────────────────
const electronics = await services.categoryService.createCategory("Electronics");
const accessories = await services.categoryService.createCategory("Accessories");

const laptop = await services.productService.createProduct(
  "ThinkPad X1 Carbon", "SKU-TP-X1C", electronics.id
);
const charger = await services.productService.createProduct(
  "USB-C Charger 65W", "SKU-CHG-65W", accessories.id
);

// ── 1b. Set up warehouses & stock ──────────────────────
const mainWarehouse = await services.warehouseService.createWarehouse("Berlin HQ");
const dropship    = await services.warehouseService.createWarehouse("Hamburg Fulfillment");

await services.stockService.setStock(laptop.id, mainWarehouse.id, 200);
await services.stockService.setStock(charger.id, mainWarehouse.id, 500);

// ── 1c. Pricing ────────────────────────────────────────
const defaultPrices = await services.pricingService.createPriceList(
  "B2B Standard", { currency: "EUR" }
);
await services.pricingService.setPrice(defaultPrices.id, laptop.id, 129900);  // 1299.00 EUR
await services.pricingService.setPrice(defaultPrices.id, charger.id, 4990);   //   49.90 EUR

// Volume pricing for the charger
await services.pricingService.setTieredPrice(defaultPrices.id, charger.id, [
  { minQuantity: 1,  unitPrice: 4990 },
  { minQuantity: 10, unitPrice: 3990 },
  { minQuantity: 50, unitPrice: 2990 },
]);

// ── 1d. Tax ────────────────────────────────────────────
const vatDE = await services.taxService.createTaxRate(
  "VAT Germany", 19, "DE", { isDefault: true }
);

// ── 1e. Customer onboarding ────────────────────────────
const vipGroup = await services.customerService.createCustomerGroup(
  "VIP Partners", "Enterprise partners", 5
);

const customer = await services.customerService.createCustomer(
  "Acme GmbH",
  { street: "Friedrichstr. 123", city: "Berlin", postalCode: "10117", country: "Germany" },
  { email: "procurement@acme.de", phone: "+49 30 555 0100" },
  { creditLimit: 5000000, paymentTerms: "NET_30", customerGroupId: vipGroup.id }
);

// Additional shipping address
await services.addressService.createAddress(
  customer.id, "SHIPPING",
  "Hafenstr. 42", "Hamburg", "20095", "Germany",
  { label: "Hamburg Office", isDefault: false }
);

// ── 1f. Reorder rules (auto-replenishment) ─────────────
await services.reorderService.createRule(laptop.id, mainWarehouse.id, 20, 100);
await services.reorderService.createRule(charger.id, mainWarehouse.id, 50, 200);

// ── 1g. Webhooks for external systems ──────────────────
await services.webhookService.registerWebhook(
  "https://erp.acme.de/webhooks/orders",
  ["ORDER_CREATED", "ORDER_SHIPPED", "PAYMENT_COMPLETED"],
  { secret: "whsec_acme_2026" }
);

console.log("Setup complete.");