How moov-io/achgateway works
Purpose and runtime
ACH Gateway is a Go service that accepts ACH files over HTTP and Kafka, queues and transforms them, then uploads optimized files to an ODFI at configured cutoff times. It also retrieves and processes inbound ODFI files (returns, reconciliations, corrections, prenotes). The executable entry point is cmd/achgateway/main.go; service assembly and HTTP serving are centered in internal/server.go and internal/environment.go.
Service configuration and tenancy
Configuration defines storage, database, inbound/outbound transport, schedules, events, notifications, encryption, and shard mappings. Shards isolate tenant/file-processing scope and map requests or Kafka records to processing configuration. Core paths: configs/config.default.yml, internal/service/model_config.go, internal/shards/service_shard_mapping.go. Persistent shard and file metadata is supported through MySQL or Google Cloud Spanner migrations in migrations/001_shard_mappings.up.mysql.sql, migrations/002_files.up.spanner.sql.
File ingestion boundary
Public ingestion accepts Nacha ACH or Moov ACH JSON files under shard-scoped HTTP APIs, validates/normalizes them, and places accepted files into repository-backed pending storage. Kafka can provide the same asynchronous input channel. Relevant paths: internal/incoming/web/api_files.go, internal/pipeline/file_receiver.go, internal/kafka/kafka.go. This boundary separates caller-facing receipt from deferred cutoff-time delivery.
Outbound pipeline
The pipeline coordinates pending-file discovery, aggregation/merging, cutoff execution, formatting, transformation, and transfer. At cutoff, eligible shard files are merged where configured, rendered as Nacha or encoded/encrypted output, then sent through a selected transfer agent. Main orchestration paths: internal/pipeline/pipeline.go, internal/pipeline/merging.go, internal/pipeline/aggregate.go. Scheduling is implemented in internal/schedule/cutoff.go and manually triggerable through internal/pipeline/manual_cutoff_times.go.
Storage, security, and delivery adapters
Storage is abstracted behind blob/filesystem implementations and may encrypt persisted data. Before upload, files can be transformed with GPG; destination delivery supports FTP and SFTP, including retry and network-security handling. Paths: internal/storage/storage.go, internal/transform/gpg.go, internal/upload/ftp.go, internal/upload/sftp.go. These adapters are the primary boundaries to local/blob storage, cryptographic key material, and ODFI-hosted file servers.
Inbound ODFI processing
A periodic or manually triggered processor downloads remote inbound directories, classifies ACH artifacts, emits domain outcomes, and cleans up remote files after handling. ODFI-specific flows cover returns, corrections, prenotes, reconciliation, audits, and download lifecycle. Paths: internal/incoming/odfi/incoming.go, internal/incoming/odfi/processor.go, internal/incoming/odfi/returns.go, internal/incoming/odfi/cleanup.go.
Events, audit, and operational integrations
Domain events are delivered via stream/Kafka or webhooks; audit records can be retained through blob storage. Notifications and alerts target email, Kafka, Slack, and PagerDuty. Prometheus metrics are served separately on the metrics/admin listener, with manual operational triggers including cutoff and inbound processing. Paths: internal/events/service.go, internal/events/service_webhook.go, internal/audittrail/storage_blob.go, internal/notify/multi.go, internal/alerting/alerter.go.
Deployment
The service targets Go 1.19+ and is distributed as a Docker image. Local/container deployment is defined by Dockerfile, docker-compose.yml, and examples/getting-started/docker-compose.yml; default Docker-oriented configuration is in configs/config.docker.yml.
Main entry points: pipeline.go Outbound pipeline · service_shard_mapping.go Shard mapping · server.go Service assembly & HTTP · api_files.go Shard-scoped file API
Components 21
Service Runtime
- ACH Gateway executable
cmd/achgateway/main.go - Service assembly & HTTP · Builds service dependencies and serves public/admin listeners.
internal/server.go - Runtime environment
internal/environment.go - Gateway configuration · Defines transports, schedules, security, events, and shard mappings.
internal/service/model_config.go - Shard mapping · Maps HTTP requests and Kafka records to tenant processing configuration.
internal/shards/service_shard_mapping.go - Shard & file metadata · MySQL or Spanner stores shard and file state.
migrations/001_shard_mappings.up.mysql.sql
File Ingestion
- Shard-scoped file API
internal/incoming/web/api_files.go - Kafka input
internal/kafka/kafka.go - File receiver · Accepts Nacha or Moov ACH JSON and queues valid files.
internal/pipeline/file_receiver.go - Pending file storage · Blob or filesystem storage can encrypt persisted files.
internal/storage/storage.go
Outbound Delivery
- Cutoff scheduler
internal/schedule/cutoff.go - Manual cutoff trigger
internal/pipeline/manual_cutoff_times.go - Outbound pipeline · Discovers eligible files and coordinates delivery processing.
internal/pipeline/pipeline.go - Merge & aggregate · Combines eligible shard files where configured.
internal/pipeline/merging.go - Output transform · Renders or encrypts output before transfer.
internal/transform/gpg.go - ODFI transfer agents · Uploads optimized files with retry and network-security handling.
internal/upload/sftp.go
Inbound ODFI
- Inbound ODFI processor · Downloads, classifies, handles, and cleans up inbound ACH artifacts.
internal/incoming/odfi/processor.go - Inbound outcomes · Processes returns, corrections, prenotes, reconciliation, and audits.
internal/incoming/odfi/returns.go
Operations
- Domain event delivery
internal/events/service.go - Audit trail
internal/audittrail/storage_blob.go - Notifications & alerts · Delivers email, Kafka, Slack, and PagerDuty notifications.
internal/notify/multi.go
Connections 23
- ACH Gateway executable → Service assembly & HTTP: starts
- Service assembly & HTTP → Runtime environment: initializes
- Runtime environment → Gateway configuration: loads
- Gateway configuration → Shard mapping: defines
- Shard mapping → Shard & file metadata: persists mappings
- Service assembly & HTTP → Shard-scoped file API: serves
- Shard-scoped file API → Shard mapping: resolves shard
- Shard-scoped file API → File receiver: submits file
- Kafka input → Shard mapping: resolves shard
- Kafka input → File receiver: submits file
- File receiver → Pending file storage: stores pending file
- Cutoff scheduler → Outbound pipeline: triggers
- Manual cutoff trigger → Outbound pipeline: triggers
- Outbound pipeline → Pending file storage: discovers pending files
- Outbound pipeline → Merge & aggregate: aggregates eligible files
- Merge & aggregate → Output transform: renders output
- Output transform → ODFI transfer agents: sends prepared file
- Inbound ODFI processor → ODFI transfer agents: downloads from ODFI
- Inbound ODFI processor → Inbound outcomes: classifies and processes
- Outbound pipeline → Domain event delivery: emits outcomes
- Inbound outcomes → Domain event delivery: emits outcomes
- Outbound pipeline → Audit trail: records audit data
- Domain event delivery → Notifications & alerts: drives alerts