Getting Started

Moov's PayGate project provides an HTTP REST endpoint for submitting and receiving ACH payments and builds upon a suite of services offered by Moov, including ACH, Watchman, and FED. Each of these services must be running and reachable by PayGate. We provide several examples of setting up a complete installation using Docker Compose, Kubernetes, or directly using the provided binaries.

Note: This documentation is for the v0.7.x series of PayGate. Please use the latest release (v0.7.3) of that series or use that branch if you're building from source.

Running PayGate locally using Docker Compose (Quickest)

PayGate can be quickly ran using the provided Docker Compose file. Ensur you have installed Docker Compose for your platform

Clone the repository and run docker-compose up within it.

$ git clone
$ cd paygate
$ docker-compose up -d

That's it! The Docker files will be downloaded and ran on your machine. PayGate endpoints will be accessible at http://localhost:8082 and http://localhost:9092. You can verify paygate is running with curl http://localhost:8082/ping and monitor the health with curl http://localhost:9092/live.

Running PayGate using Kubernetes (Advanced)

Moov uses Kubernetes for clustering our production services and we have Helm charts for each application in beta currently. Inside the moov-io/infra repository we have Kubernetes manifests which you can reference also.

Running from source

PayGate can run directly from source using Go, but the required services need to be running as well in order for API calls to complete successfully. The default port 8082 is used unless a CLI flag (e.g. -http.addr=<port>) or environment variable override from our configuration documentation is set when running PayGate.

# With Golang and git installed:
$ git clone
$ cd paygate
$ go run .

API documentation

See our API documentation for Moov PayGate endpoints.

Testing endpoints

In order to check that the services are running, moov provides an api tool (apitest) for testing the endpoints with binaries you can download. Once downloaded running apitest -local will create Customer, Receiver, Depository, and a Transfer against your local docker compose stack.

# For Linux
$ wget
$ mv apitest-linux-amd64 apitest && chmod +x apitest

# For OSX
$ wget
$ mv apitest-darwin-amd64 apitest && chmod +x apitest

# For docker compose setup or the running binaries using default values.
$ ./apitest -local

# For Tilt setup using Kubernetes
$ ./apitest -dev

# For other options, run
$ ./apitest -help

Disable What Isn't Needed

If you don't need (Know Your Customer) KYC checks on Originator or Receiver objects disable the calls to Moov Customers:


If you don't need a general ledger to track accounts and transactions with disable Moov Accounts calls:


Make a Transfer

After confirming that the services are running correctly, there are several things needed before ACH transactions can be created/processed using PayGate. Listed below are the steps necessary:

  1. Setup a Depository for the Originator (ODFI)
  2. Setup a Depository for the Receiver as well (RDFI)
  3. Setup an Originator with customer information
  4. Setup a Receiver with customer information
  5. Setup a Gateway with ODFI gateway information
  6. Then you can create a Transfer between these two FIs


The HTTP header X-User-ID is required and used to isolate objects (such as Depository, Originator, Receiver, Gateway, Transfer) when using paygate in a multi-tenant setup. This is useful if you're managing transfers for multiple customers/users or multiple Financial Institutions. The value for this header can be a UTF-8 string, but typically it is a random alphanumeric string.

Setup FTP

PayGate currently requires the FTP configuration to be manually setup in the database. See here for more information on FTP/SFTP configs. The following will setup paygate to connect to the local FTP server started by make start-ftp-server in the repository.


MySQL is a database which applications or developers connect to over the network. This means to configure paygate's FTP and file upload configuration a developer needs to connect to the database.

# Connect using host, username and password for your setup
$ mysql -h localhost:3306 -u paygate

> INSERT INTO ftp_configs (routing_number, hostname, username, password) VALUES ('000000000', 'localhost:22', 'myusername', 'mypassword');

> INSERT INTO cutoff_times (routing_number, cutoff, location) VALUES ('000000000', '1700', 'America/New_York');

> INSERT INTO file_transfer_configs (routing_number, inbound_path, outbound_path, return_path) VALUES ('000000000', '/inbound', '/outbound', '/returns');


If using the Docker Compose and sqlite (DATABASE_TYPE=sqlite) script above, you need to mount the /data volume of the paygate section in docker-compose.yml file like so:

    image: moov/paygate:v0.5.0-dev
      - "8082:8082"
      - "9092:9092"
    command: ["-http.addr", ":8082"]
      ACCOUNTS_ENDPOINT: 'http://accounts:8085'
      ACH_ENDPOINT: 'http://ach:8080'
      FED_ENDPOINT: 'http://fed:8086'
      CUSTOMERS_ENDPOINT: 'http://customers:8087'
      - .:/data
      - ach
      - accounts
      - fed
      - customers
      - auth
This will attach the /data volume within the image to the same directory in which the docker-compose.yml file resides.

To setup FTP, run the following commands on the now exposed paygate.db file, changing the dummy string values below:

# Setup credentials for sqlite3
$ sqlite3 paygate.db "INSERT INTO ftp_configs (routing_number, hostname, username, password) VALUES ('000000000', 'localhost:22', 'myusername', 'mypassword');"

# Setup cutoff times
$ sqlite3 paygate.db "INSERT INTO cutoff_times (routing_number, cutoff, location) VALUES ('000000000', '1700', 'America/New_York');"

# Setup ftp directories
$ sqlite3 paygate.db "INSERT INTO file_transfer_configs (routing_number, inbound_path, outbound_path, return_path) VALUES ('000000000', '/inbound', '/outbound', '/returns');"
The command may need to be ran with elevated privileges, using sudo or another method. The database will also need to be writable.

Verify FTP configuration

Paygate's admin HTTP interface offers endpoints to check these values were setup (default on port :9092).

curl -s -X GET http://localhost:9092/configs/uploads | jq .
  "cutoffTimes": [
      "RoutingNumber": "121042882",
      "Cutoff": 1700,
      "Location": "America/New_York"
  "ftpConfigs": [
      "RoutingNumber": "121042882",
      "Hostname": "localhost:2121",
      "Username": "admin",
      "Password": "1****6"
  "fileTransferConfigs": [
      "RoutingNumber": "121042882",
      "InboundPath": "inbound/",
      "OutboundPath": "outbound/",
      "ReturnPath": "returned/"