Not every order needs to live on a blockchain — but audit trails that no single party can tamper with? That’s a different story. I built a Blockchain Order Management System that combines the speed of PostgreSQL with the immutability of Hyperledger Fabric.
Code: BlockChainOms on GitHub. This post covers why a hybrid design made sense and how the pieces fit together.
The requirement
Stakeholders wanted:
- Fast dashboards — filter thousands of orders by date, status, customer
- Tamper-evident history — proof that order records weren’t altered after settlement
- Multi-party trust — supplier, distributor, and auditor reading the same truth
Pure on-chain storage fails the first requirement. Pure PostgreSQL fails the second. The answer is a hybrid ledger.
Architecture overview
Client (JS) → REST API (Node.js)
├── PostgreSQL (operational data, queries)
└── Fabric SDK (hash + anchor to ledger)
PostgreSQL layer
Stores everything the UI needs day-to-day: orders, line items, customers, statuses, timestamps. Normal indexes, JOINs, reporting — all the stuff blockchains are bad at.
Hyperledger Fabric layer
When an order reaches a milestone (created, approved, shipped, completed), the API writes a compact event record to the chain:
- Order ID
- Status transition
- Hash of the canonical order snapshot
- Timestamp and actor identity
We don’t store full order payloads on-chain — only fingerprints. Verification re-hashes the PostgreSQL record and compares to the ledger entry.
Write path
- API validates and persists order to PostgreSQL inside a transaction
- On success, enqueue a Fabric transaction (async to avoid blocking the user)
- Chaincode appends immutable record; callback updates
ledger_tx_idon the order row - If Fabric is temporarily down, retry queue holds events — operational DB stays available
This was key: the app stays usable even when the ledger is slow or unavailable. Blockchain augments trust; it doesn’t block business.
Verification flow
Auditors pick an order ID. The system:
- Loads current row from PostgreSQL
- Recomputes SHA-256 of the canonical JSON snapshot
- Queries Fabric for the matching order event chain
- Compares hashes — mismatch flags potential tampering
Chaincode design
Smart contract methods were intentionally minimal:
RecordOrderEvent(orderId, status, hash, actor)GetOrderHistory(orderId)
No complex business logic on-chain — that stays in the API where it’s easier to test and iterate.
Trade-offs (honest)
Pros: Immutable audit trail, multi-org trust, fast queries via SQL.
Cons: Fabric ops are heavy (peers, CAs, channels). Eventual consistency between DB and chain. Not worth it for a simple CRUD app — only when auditability is a real requirement.
What I learned
- Put blockchain at the edge of your domain — anchoring and verification — not at the center
- Design for ledger downtime from day one
- Hash snapshots, don’t dump JSON on-chain
- Document the verification story for non-blockchain stakeholders