Most payment integrations start out simple. You connect to one payment processor, add its SDK, and configure a few API keys.
But things can quickly become more complicated. You might need a second processor because the first one declines cards from a particular country, then you may want to add payment retries. Over time, the payment logic can end up scattered across multiple services and become difficult to manage.
Hyperswitch helps simplify this by sitting in front of your payment processors and providing a single API to work with them. It is written in Rust, licensed under Apache 2.0, and the complete stack can run on a single Linux server using Docker.
This guide was tested on Ubuntu 26.04 and Rocky Linux 10, but the commands should work on any modern Linux distribution with Docker installed.
What Hyperswitch Actually Is
One thing that can be confusing when you first set up Hyperswitch is that there is no `hyperswitch` package or binary that you install using `apt`. It is not a command-line tool.
Hyperswitch is a payments switch. Your application sends a payment request to Hyperswitch, which then routes that request to the appropriate payment processor, such as Stripe, Adyen, PayPal, or one of the 100+ other supported processors.
The self-hosted setup includes a Rust-based application server, along with PostgreSQL and Redis. It also includes a browser-based dashboard called the Control Center, where you can configure payment processors and set up routing rules.
So, when you install Hyperswitch, what you’re really doing is starting a small group of containers on your Linux server. Once everything is running, your application communicates with Hyperswitch over HTTP.
What You Need Before Installing
Before you start, make sure your server has enough resources. The standard Hyperswitch setup runs several containers, so you should have at least 4 GB of free RAM and 2 CPU cores. If you also plan to enable monitoring with Grafana and Prometheus, you will need more resources.
You will also need git, Docker Engine, and the Docker Compose plugin installed. If you use Podman instead of Docker, the setup script supports that as well.
The following ports must also be available on the server:
8080, 9000, 9050, 5432, and 6379
If another service is already using one of these ports, especially 8080, resolve that before continuing.
Install Docker Engine and Compose
To run Hyperswitch, you need Docker Engine and the Docker Compose plugin. The commands below install Docker from Docker’s official repository.
The sudo command runs each command with administrator privileges, which are required because installing software and managing the Docker service make changes to system directories.
On Ubuntu or Debian, run the following commands:
sudo apt update sudo apt install -y ca-certificates curl git sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
On RHEL or Rocky Linux, run:
sudo dnf install -y dnf-plugins-core git sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
Once Docker is installed, start the Docker service and configure it to start automatically when the system boots:
sudo systemctl enable --now docker docker compose version
If docker compose version displays a version number, Docker Compose is installed and ready to use and if you see an error like permission denied while trying to connect to the Docker daemon socket, your current user does not have permission to access Docker yet.
Add your user to the docker group:
sudo usermod -aG docker $USER
Then log out and log back in for the group change to take effect.
Clone the Repository and Run the Setup Script
Juspay provides a setup script that handles the Docker Compose profiles for you, so you don’t need to manually edit any YAML files when setting up Hyperswitch for the first time.
Run:
git clone --depth 1 --branch latest https://github.com/juspay/hyperswitch cd hyperswitch scripts/setup.sh
Here’s what the first command does:
git clonecopies the Hyperswitch repository to your server.--depth 1downloads only the latest commit instead of the full repository history, which saves time and disk space.--branch latestchecks out the latest tag, so you get a released build rather than the latest changes from the main branch.scripts/setup.shdetects whether you are using Docker or Podman, configures PostgreSQL and Redis, and asks you which deployment profile to use.
The script gives you three options:
- Standard – Includes the app server, Control Center, and web SDK.
- Full – Includes everything in Standard, plus monitoring and the scheduler.
- Standalone App Server – Runs only the core services.
For most first-time setups, choose Standard unless you specifically need one of the other profiles. The first run downloads several container images, so it may take a few minutes, especially on a slower internet connection. After the images are downloaded, future starts should be much faster.
Check What Came Up
Once the setup script finishes, check the containers that are actually running instead of relying only on the script’s summary.
Run:
docker compose ps
You should see output similar to this:
NAME IMAGE STATUS hyperswitch-server .../hyperswitch-router:standalone Up 2 minutes (healthy) hyperswitch-control-center .../hyperswitch-control-center:latest Up 2 minutes hyperswitch-web .../hyperswitch-web:latest Up 2 minutes pg postgres:latest Up 2 minutes (healthy) redis-standalone redis:7 Up 2 minutes (healthy)
The most important line to check is hyperswitch-server. If it shows (healthy), the main Hyperswitch application is running correctly.
This status comes from the container’s built-in health check, which checks the /health endpoint internally. A healthy status also indicates that the Rust application server has connected to PostgreSQL and completed its database migrations.
If hyperswitch-server keeps showing Restarting, check its logs with:
docker compose logs hyperswitch-server
Look near the top of the output for database connection errors or other messages that explain why the container failed to start.
Ports This Stack Opens: The default setup opens the following ports:
8080– The Hyperswitch application server and API that your application will use.9000– The Control Center dashboard, which you access from a web browser.9050– The web checkout SDK, includingHyperLoader.js.5432– PostgreSQL.6379– Redis.
The last two ports need special attention. By default, PostgreSQL and Redis may be published to the host. If you are running this on a public VPS, make sure they are not accessible from the internet unless you specifically need remote access.
Before connecting a domain or exposing the server publicly, secure the server with a firewall such as ufw or firewalld.
Verify the App Server Responds
Before opening the dashboard, it’s a good idea to confirm that the Hyperswitch API itself is running. The health endpoint does not require authentication.
Run:
curl --head --request GET 'http://localhost:8080/health'
You should see a response similar to this:
HTTP/1.1 200 OK content-length: 14 via: HyperSwitch access-control-allow-credentials: true x-request-id: 018cbc59-42c0-755d-a57b-a447f7afc221
The important part is the first line HTTP/1.1 200 OK, the via: HyperSwitch header also confirms that the response is coming from the Hyperswitch app server and not another service using port 8080.
If you get anything other than a 200 response, the container may be running, but the application inside it is not ready yet. If you’re checking the server from another machine, replace localhost with your server’s address.
Throughout this article, anything shown in angle brackets, such as <your-server-ip>, is a placeholder. Replace it with your own value when running the command.
Set Up an Account in the Control Center
Open http://:9000 in your web browser and click Sign Up. The account you create is stored entirely in your own PostgreSQL database.
Once you sign in, go to Payment Processors and add the Dummy Processor first. It lets you simulate approved and declined payments without sending anything to a real payment gateway, which makes it useful for testing your setup.
Next, go to Developers and then API Keys to create a new API key. Copy the key as soon as it is displayed. The Control Center shows the full plaintext value only once, so you won’t be able to view it again later.
Run a Test Payment from the Terminal
This is the step that confirms your Hyperswitch installation is actually working. You’ll create a test payment through the API using the Dummy Processor and the API key you generated earlier.
Run:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'api-key: ' \
--data '{
"amount": 499,
"currency": "USD",
"confirm": true,
"customer_id": "tecmint_test_customer",
"payment_method": "card",
"payment_method_data": {
"card": {
"card_number": "4242424242424242",
"card_exp_month": "12",
"card_exp_year": "30",
"card_holder_name": "Test User",
"card_cvc": "123"
}
}
}'
If everything is working correctly, you should get a response similar to this:
{
"payment_id": "pay_kL9mQ2xR7vTn4bYc",
"status": "succeeded",
"amount": 499,
"currency": "USD",
"connector": "dummy_processor",
"customer_id": "tecmint_test_customer"
}
The two most important fields here are "status" and "connector".
A "status": "succeeded" response means Hyperswitch accepted your payment request, routed it to a payment processor, and received a successful response.
The "connector": "dummy_processor" field tells you which processor handled the payment. This becomes especially useful later when you connect multiple payment processors and start using routing rules.
One important detail: the amount is specified in minor units. So 499 means $4.99, not $499.
Common Mistakes on the First Run
Using the admin key for payment requests. The local admin key is test_admin, which is defined in config/docker_compose.toml. It is meant for account-level operations, such as creating merchants. When creating payments, use the API key you generated from the Control Center.
Assuming the default setup is PCI compliant. It isn’t. This Docker Compose setup is designed for development and evaluation and uses default database credentials in its configuration. If you plan to handle real card data, you need a properly hardened deployment, secure credential storage, and an appropriate compliance program.
Leaving the containers running on a public server. If you’re only testing Hyperswitch, shut everything down when you’re finished:
docker compose down -v
The -v option also removes the Docker volumes, including the stored database data. This means the next time you start the stack, it begins with a clean database.
Conclusion
You now have Hyperswitch running as a self-hosted payment switch on Linux, a health check to confirm the app server is actually ready, a Control Center account backed by your own database, and a test payment that shows both the payment status and the processor that handled it.
Before you close the terminal, try one more thing: add a second processor in the Control Center, create a routing rule that sends payments above a certain amount to it, and then run the same curl command again with a larger amount. Watch the connector field in the response to see which processor Hyperswitch selects.
What made you consider self-hosting a payments switch in the first place? Avoiding processor lock-in, meeting data residency requirements, or something else? Let us know in the comments below.





