All projects
Orderflow banner
Order Ops / Workflow Automation · 2026 Open source

Orderflow

Order management with first-class n8n automation: place an order, watch a workflow run, see the order update itself via signed callbacks.

Tech stack
PHP 8.2 Laravel 11 Livewire 3 Alpine.js Tailwind DaisyUI PostgreSQL 16 Redis 7 Horizon n8n Mailpit Pest Docker Compose

The problem

Most order tools either run pure manual ops in a CRUD UI or push everything through external SaaS automation you cannot inspect. The result: ops teams cannot tell whether a workflow ran, retried, or quietly failed; engineers cannot version or replay the automation; buyers cannot self-host. Orderflow rejects that split and treats the workflow layer as code you control.

Goals

  • Keep the order CRUD surface inside a Laravel app the team owns
  • Park automation in a self-hosted n8n instance the same team can edit
  • Sign every outbound event so n8n can verify Laravel before acting
  • Let n8n call back into Laravel safely with token auth and idempotency
  • Show every workflow step to the operator inside the order view, no log diving

The solution

  • Livewire 3 order surface for customers, orders, and line items with live total recompute
  • Four domain events (OrderPlaced, OrderPaid, OrderShipped, OrderCancelled) queued through Horizon on a dedicated n8n queue
  • WebhookDispatcher with HMAC-SHA256 over deeply sorted-key canonical JSON, sent with X-Orderflow-Event and X-Orderflow-Signature
  • Inbound REST API at /api/orders/* behind a token middleware (hash_equals Bearer check) and a Redis-backed idempotency middleware with 24h TTL and X-Idempotency-Replay on cache hits
  • AutomationLog model rendered as a polling timeline in the order view; invoice number badge updates from n8n's PATCH within seconds
  • Production workflow committed at n8n/workflows/order-placed.json so anyone cloning the repo gets the same round trip
  • Whole stack (Laravel, Postgres, Redis, n8n, Mailpit) boots from a single docker-compose, no external hosting to demo

My role

  • Solo architect and engineer, requirements to deploy
  • Domain model (customers, orders, items, automation logs) plus Livewire surfaces and the Horizon queue topology
  • Outbound integration: events, listener, SyncToN8nJob, HmacSigner with stable canonical JSON, WebhookDispatcher
  • Inbound integration: token middleware, idempotency middleware on Redis, AutomationLog timeline polling
  • n8n production workflow JSON, demo seeder, recorded demo gif, Pest suite (45 passing)

UI direction

An ops-facing Livewire surface in Tailwind plus DaisyUI: dashboard with KPI tiles, an orders list with debounced search, and an order detail page where the automation timeline fills in live as n8n posts callbacks.

User flows

Order placed, automation round-trips

  1. 1 Ops user creates an order in the Livewire UI with line items and totals
  2. 2 Laravel dispatches OrderPlaced; the listener queues SyncToN8nJob on the n8n queue
  3. 3 Horizon's worker POSTs the signed payload to the order-placed webhook in n8n
  4. 4 n8n branches on total (over $500 fires a Slack alert), sends a Mailpit confirmation, generates an invoice number, and PATCHes the order back
  5. 5 Each step logs to /api/orders/{id}/automation-log; the Livewire order view shows the invoice badge and timeline within seconds

Inbound API with idempotency

  1. 1 n8n calls back into Laravel with Authorization: Bearer and an Idempotency-Key header
  2. 2 Token middleware compares with hash_equals; mismatch returns 401
  3. 3 Idempotency middleware checks Redis for the key under orderflow:idempotency:<key>
  4. 4 On a fresh key the handler runs and the response body, status, and headers cache in Redis for 24h
  5. 5 A retried n8n execution hits the cache and gets the same body back with X-Idempotency-Replay: true, no double-apply

Screenshots

Click any image to open at full size.

Key learnings

  • HMAC verification fails the moment two sides serialize JSON differently; deeply sorting keys (while preserving list order) gives n8n a deterministic canonical form to verify
  • Idempotency-Key handling belongs in middleware on Redis, not in each controller, so every write endpoint inherits it the moment it's registered
  • Horizon with predis ran cleanly once REDIS_CLIENT=predis was set explicitly; relying on phpredis being installed on the host wastes a day
  • n8n 2.18 will not register webhook routes for an active workflow until the owner account exists; POST /rest/owner/setup is the one-liner that unblocks headless imports
  • A polling Livewire timeline (wire:poll.5s) is the smallest piece of UI that makes the automation feel alive without a websocket dependency

Want something like Orderflow?

I'm open to senior contract work. Let's talk about what you're building.

Get in touch