Customers & accounts
B2B Commerce Platform
Indicative price, not an offer: EUR 500-1500/year or EUR 2000-3000 one-off
Generated from docs/plan/paid/b2b-commerce-platform/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
B2B Commerce Platform provides a complete B2B selling system with approval workflows, tiered customer account hierarchies, negotiated pricing, and business credit terms (Net 30/60/90).
The problem
B2B selling requires approval workflows, negotiated pricing, and tiered customer groups.
What it does
- Multi-level hierarchy: parent company to divisions to departments to employees
- Division and department management
- Multi-step approval (employee to manager to director)
- Negotiated pricing: custom per customer/sku override defaults
- Bulk order discounts: % or fixed if order > X EUR
- Business credit terms: Net 30/60/90 (customer pays invoice after N days)
- Customer groups: define groups (Gold Partners), apply group pricing
- Purchase order mandatory: customer must provide PO, order held until matched
- Order limits: per-customer daily limits (10k EUR/day max)
- Invoice generation: PDF for customer payment
- Payment plans: split invoice into installments (1k EUR due date, 1k EUR +15d, 1k EUR +30d)
- Approval notifications (assumed via email system)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Advanced credit scoring (auto-calculate limit) — separate credit-management module
- Automatic credit hold (late payment blocks orders) — credit management
- Buyer journey customization (different catalog per customer) — global catalog
- Complex tiered pricing formulas (base_price - qty*0.1%) — simple tier tables
- White-label/multi-tenant — out of scope entirely
Data model
CustomerHierarchy: customer_id, parent_id, hierarchy_level (1=company, 2=div, 3=dept, 4=employee), is_active. ApprovalStep: order_id, step_number, approver_id, status, approved_at, rejection_reason. NegotiatedPrice: id, customer_id, sku, unit_price, effective_from/to, created_by. CustomerGroup: id, store_id, name, discount_percent, pricing_tier. OrderLimit: customer_id, period (daily/monthly), limit_amount. Invoice: id, order_id, invoice_number, issued_date, due_date, amount_due, amount_paid, payment_status. PaymentPlan: invoice_id, installment_number, amount, due_date, paid_date. Migration: add 7+ tables.
API
- POST /admin/customers/{id}/hierarchy/children
- GET /admin/customers/{id}/hierarchy
- POST /admin/orders/{id}/approval/step/{step}/approve
- POST /admin/orders/{id}/approval/step/{step}/reject
- POST /admin/customers/{id}/negotiated-prices
- POST /admin/customer-groups
- POST /admin/customer-groups/{id}/members
- GET /admin/customers/{id}/order-limit
- PATCH /admin/customers/{id}/order-limit
- POST /admin/invoices/{id}/payment-plan
- GET /admin/invoices/{id}/payment-plan
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Hierarchy UI: tree of parent to divisions to departments to employees; drag-to-move. Approval queue: orders by step; approve/reject. Price editor: customer/sku table; bulk CSV. Groups: create, add members, set discount. Order limit: set daily 50k EUR for ACME. Invoice viewer: list per customer, due date, status; generate PDF. Payment plan: split into installments.
The seam — why this is paid
Core owns: customer data, order data, approval hooks (order.created to approval chain). Paid module owns: hierarchy mgmt, approval UI, negotiated pricing, group mgmt, order limit enforcement, invoice gen, payment plans, pricing overrides.
Requires complex approval workflows and business credit terms. High support commitment for B2B-specific processes.
Dependencies
- b2b-suite (recommended)
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Hierarchy: ACME Corp to North America to Sales to john@acme.com
- john@acme.com places 5000 EUR order; step 1 awaits manager (30min SLA)
- Manager approves 10min later; step 2 awaits director (2hr SLA)
- Director approves; order to payment
- 1000 EUR order, negotiated 900 EUR/unit vs 1000 EUR default; invoice shows 900 EUR
- Gold Partners group 10% discount; member orders 1000 EUR to invoice 900 EUR
- Daily limit 10k EUR: order 8k EUR, then 3k EUR causes 2nd blocked (exceeds 10k EUR)
- Invoice 1000 EUR split: 3x333.33 EUR+1 EUR, each 15 days apart
- Payment plan: each installment due_date tracked separately
Risks
Approval chain broken (step 1 approver deleted) causes order stuck forever. Negotiated price wrong sku. Group discount + negotiated = double discount (precedence conflict). Limit not enforced via API. Payment plan overpayment (3x600 EUR = 1800 EUR vs 1000 EUR). Invoice never created. Approval email never sent.
Commercial context
| Suggested price | EUR 500-1500/year or EUR 2000-3000 one-off |
| Rival anchor | Mageplaza B2B Solution, Webkul Purchase Order |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.