Hanzo Reconciliation is an automated transaction matching engine that compares ledger balances against payment provider data to verify financial consistency and identify discrepancies.
Category: Hanzo Ecosystem Related Skills: hanzo/hanzo-numscript.md, hanzo/hanzo-billing.md
Hanzo Reconciliation is an automated transaction matching engine that compares ledger balances against payment provider data to verify financial consistency and identify discrepancies. It runs as a standalone HTTP service backed by PostgreSQL, with policies that define how and when to reconcile ledger and payment data. Part of the Hanzo treasury stack.
driftBalances showing exact differences between ledger and payments--auto-migrate flag or dedicated migrate commandRepo: hanzoai/reconciliation (Formance reconciliation fork). Go module path is github.com/formancehq/reconciliation (upstream module name retained).
hanzo/commerce Storefront, catalog, orders
|
hanzo/payments Payment routing (50+ processors)
|
hanzo/treasury Ledger, reconciliation, wallets <-- this service
|
lux/treasury On-chain treasury, MPC/KMS wallets
| Item | Value | |------|-------| | Go module | github.com/formancehq/reconciliation | | Default port | :8080 | | API version | v1 (prefixed in OpenAPI) | | Default branch | main | | Binary | reconciliation | | Image | ghcr.io/formancehq/base:22.04 (base) | | Repo | github.com/hanzoai/reconciliation |
# Build
go build -o ./bin/reconciliation .
# Run with auto-migrate
./bin/reconciliation serve \
--postgres-uri "postgresql://user:pass@localhost:5432/reconciliation" \
--stack-url "http://localhost:8080" \
--stack-client-id "client-id" \
--stack-client-secret "client-secret" \
--auto-migrate \
--listen ":8080"
curl -X POST http://localhost:8080/policies \
-H "Content-Type: application/json" \
-d '{
"name": "stripe-daily",
"ledgerName": "default",
"ledgerQuery": {"$match": {"metadata[provider]": "stripe"}},
"paymentsPoolID": "stripe-pool"
}'
curl -X POST http://localhost:8080/policies/{policyID}/reconciliation \
-H "Content-Type: application/json" \
-d '{
"reconciledAtLedger": "2026-03-13T00:00:00.000Z",
"reconciledAtPayments": "2026-03-13T00:00:00.000Z"
}'
# List all reconciliation results
curl http://localhost:8080/reconciliations
# Get specific result
curl http://localhost:8080/reconciliations/{reconciliationID}
Policy
|-- id, name, createdAt
|-- ledgerName (which ledger to query)
|-- ledgerQuery (filter for ledger transactions)
|-- paymentsPoolID (which payment pool to compare against)
Reconciliation
|-- id, policyID, createdAt
|-- reconciledAtLedger (point-in-time for ledger snapshot)
|-- reconciledAtPayments (point-in-time for payments snapshot)
|-- status (COMPLETED, FAILED, etc.)
|-- ledgerBalances (map[asset]bigint from ledger)
|-- paymentsBalances (map[asset]bigint from payments)
|-- driftBalances (map[asset]bigint -- the difference)
|-- error (if status is FAILED)
| Method | Path | Purpose | Auth Scope | |--------|------|---------|------------| | GET | /_info | Server version info | reconciliation:read | | POST | /policies | Create a reconciliation policy | reconciliation:write | | GET | /policies | List policies (paginated) | reconciliation:read | | GET | /policies/{policyID} | Get a single policy | reconciliation:read | | DELETE | /policies/{policyID} | Delete a policy | reconciliation:write | | POST | /policies/{policyID}/reconciliation | Run reconciliation | reconciliation:write | | GET | /reconciliations | List reconciliation results | reconciliation:read | | GET | /reconciliations/{reconciliationID} | Get a single result | reconciliation:read |
Cursor-based pagination on list endpoints:
GET /policies?pageSize=15&cursor=base64EncodedCursor
Response includes cursor.hasMore, cursor.next, cursor.previous.
reconciliation serve # Start HTTP server
reconciliation migrate # Run database migrations
reconciliation version # Print version info
--listen HTTP listen address (default ":8080")
--stack-url Formance stack URL (for ledger + payments API)
--stack-client-id OAuth2 client ID for stack API
--stack-client-secret OAuth2 client secret for stack API
--auto-migrate Auto-run database migrations on startup
--postgres-uri PostgreSQL connection string
github.com/hanzoai/reconciliation/
main.go # Entrypoint (calls cmd.Execute())
openapi.yaml # OpenAPI 3.0.3 spec (full API definition)
Justfile # Build commands (test, lint, build, release)
build.Dockerfile # Production container image
scratch.Dockerfile # Minimal scratch-based image
Earthfile # Earthly build definition
.goreleaser.yml # Cross-platform release config
cmd/
root.go # CLI root command, service name, flags
serve.go # HTTP server with fx DI, OAuth2 stack client
migrate.go # Database migration command
version.go # Version info command
internal/
api/
router.go # Chi router setup
module.go # fx HTTP module
policy.go # Policy CRUD handlers
reconciliation.go # Reconciliation run + query handlers
query.go # Query builder helpers
utils.go # HTTP response utilities
backend/ # Backend service interface + mock
service/ # Business logic layer
policy_test.go # Policy handler tests
reconciliation_test.go # Reconciliation handler tests
models/
policy.go # Policy domain model
reconciliation.go # Reconciliation domain model
storage/
store.go # Store interface
module.go # fx storage module
policy.go # Policy DB queries (bun)
reconciliations.go # Reconciliation DB queries (bun)
error.go # Storage error types
ping.go # Database health check
utils.go # Query utilities
migrations/ # SQL migration files
main_test.go # Test harness (dockertest PostgreSQL)
policy_test.go # Policy storage tests
reconciliations_test.go # Reconciliation storage tests
| Issue | Cause | Solution | |-------|-------|----------| | Connection refused on startup | PostgreSQL not reachable | Check --postgres-uri and network | | Migration fails | Schema conflicts | Run reconciliation migrate standalone first | | OAuth2 token error | Wrong stack credentials | Verify --stack-client-id and --stack-client-secret | | Empty drift balances | No matching transactions | Check ledgerQuery filter matches actual ledger data | | Module path confusion | Upstream module name | Import as github.com/formancehq/reconciliation |
hanzo/hanzo-numscript.md - DSL for modeling the transactions being reconciledhanzo/hanzo-billing.md - Billing and subscription managementLast Updated: 2026-03-13 Category: Hanzo Ecosystem Related: fintech, reconciliation, accounting, payments, ledger, go Prerequisites: PostgreSQL 12+, Go 1.24+, Formance stack (ledger + payments)