Jesse A. Green / notebook

Hyperswitch User Guide

Generated June 2026 from juspay/hyperswitch at 67585f7

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Hyperswitch is composable, open-source payments infrastructure written in Rust. It sits between your application and 100+ payment processors (Stripe, Adyen, Braintree, Worldpay, Checkout.com, Cybersource, PayPal, and more), giving you one API and one dashboard to accept payments, route transactions intelligently, save payment methods, issue refunds and payouts, and observe everything — without rebuilding an integration for each processor or locking yourself to a single vendor.

This guide shows you how to run Hyperswitch, connect a payment processor, and process payments end to end using the REST API, the Control Center dashboard, and the checkout SDKs. It documents only what exists in the source at the referenced commit.

Note

Hyperswitch is the "app server" — the core payments engine. It works alongside companion services (a PCI card vault, an encryption service, a merchant dashboard, and client SDKs) that are described throughout this guide. You can run just the app server, or the full suite.


1. Quick Start

The fastest way to try Hyperswitch is the one-click local setup, which runs the app server and Control Center in Docker.

Important

Prerequisites: Docker or Podman installed and running, git, and roughly 4 GB of free RAM for the standard profile. The setup script detects your container engine automatically.

macOS / Linux

git clone --depth 1 --branch latest https://github.com/juspay/hyperswitch
cd hyperswitch
scripts/setup.sh

Windows (WSL2)

# Run inside a WSL2 Ubuntu shell with Docker Desktop's WSL integration enabled
git clone --depth 1 --branch latest https://github.com/juspay/hyperswitch
cd hyperswitch
bash scripts/setup.sh

The script prompts you to choose a deployment profile:

1) Standard Setup:   [Recommended] App server + Control Center. Ideal for a quick trial.
2) Full Stack Setup: Everything in Standard, plus Monitoring and Scheduler.
3) Minimal Setup:    Standalone App server only.

When it finishes, it prints access links. The defaults are:

Service URL What it is
App server (API) http://localhost:8080 The REST API you integrate against
Health check http://localhost:8080/health Liveness probe
Control Center http://localhost:9000 Merchant dashboard (configure connectors, view payments)
Web checkout demo http://localhost:9060 A sample checkout page using the web SDK

Tip

Verify the server is up before integrating:

curl http://localhost:8080/health
health is good

To stop the standard stack:

docker compose down

If you chose Full Stack, stop it with the full profile list (the script prints the exact command):

docker compose --profile scheduler --profile monitoring --profile olap --profile full_setup down

2. What You Can Do with Hyperswitch

Hyperswitch is modular — adopt the whole payment suite, or integrate only the modules you need on top of an existing stack.

Module What it gives you
Unified payments API One API to authorize, capture, void, refund, and sync payments across 100+ processors.
Intelligent Routing Route each transaction to the processor with the best predicted success rate; fall back and retry automatically across processors.
Vault PCI-compliant storage for cards, tokens, wallets, and bank credentials. Supports bring-your-own-vault (VGS, TokenEx) without re-tokenizing.
Alternate Payment Methods (APMs) Drop-in support for PayPal, Apple Pay, Google Pay, Samsung Pay, Pay by Bank, and BNPL providers such as Klarna.
Payouts Send money out (disbursements, refunds-to-source) through supported payout processors.
Subscriptions Create and manage recurring billing subscriptions.
Revenue Recovery Smart retry strategies tuned by card BIN, region, and method to combat passive churn.
Reconciliation Automated 2-way and 3-way reconciliation with scheduled, customizable outputs.
Cost Observability Dashboards to audit and optimize payment costs, downgrades, and penalties.

Note

Each module is independent. A common starting point is moving from a single Stripe or Braintree integration to multi-processor routing, while keeping your existing vault intact.


3. Installation & Deployment Options

You have several ways to run Hyperswitch depending on whether you want to trial it, develop against it, or run it yourself in production.

3.1 Hosted Sandbox (no setup)

Sign up for the fully hosted sandbox — no installation required. You get the full Control Center, can configure connectors, and can test payments from the UI or API.

Environment Base URL
Hosted sandbox https://sandbox.hyperswitch.io
Hosted production https://api.hyperswitch.io

Dashboard: https://app.hyperswitch.io.

3.2 Local Docker (self-hosted trial / development)

Use scripts/setup.sh as shown in Quick Start. Under the hood it runs docker compose with one or more profiles:

Profile Adds
(none) App server, PostgreSQL, Redis, Control Center, web SDK, migrations runner
scheduler Producer + consumer (deferred task processing)
monitoring Grafana, Loki, Tempo, Prometheus, OpenTelemetry collector, RedisInsight
olap Analytics stack: Kafka, ClickHouse, OpenSearch, Kafka UI
full_setup Mailhog (email testing) and related extras
clustered_redis Redis cluster nodes instead of a single Redis
full_kv Key-value (KV) mode services for the write-through cache

Tip

To bring up everything at once without the interactive menu:

docker compose --profile scheduler --profile monitoring --profile olap --profile full_setup up -d

3.3 Cloud (Kubernetes / Terraform)

For production, deploy to AWS, GCP, or Azure:

  • Helm charts — hyperswitch-helm deploys the stack to any Kubernetes cluster.
  • Terraform suite — hyperswitch-suite wires together the core, vault, Control Center, and web SDK as a full-suite deployment. This is the recommended starting point for the complete stack.

Important

Production deployment, configuration hardening, secrets/KMS, and the card vault are covered in depth in the Hyperswitch Admin Guide. This section is only an orientation.

3.4 The Hyperswitch ecosystem

The app server in this repository is the center of gravity. These companion repositories extend it:

Repository Role
hyperswitch (this repo) App server: routing, retries, vaulting, observability. Rust.
hyperswitch-card-vault PCI-compliant card storage. Rust.
hyperswitch-encryption-service Encryption, decryption, key management. Rust.
hyperswitch-control-center Full merchant dashboard. ReScript.
hyperswitch-web Primary web checkout SDK. ReScript → React, distributed on npm.
hyperswitch-sdk-android / -ios / react-native-hyperswitch / flutter_hyperswitch Mobile checkout SDKs.
hyperswitch-prism Standalone unified connector library (use processors directly without running the full switch).

4. Core Concepts

A few objects appear throughout the API. Understanding them makes the rest of the guide straightforward.

Merchant account : Your top-level account on a Hyperswitch deployment. Holds API keys, connectors, and profiles. Created with an Admin API key.

Connector (Merchant Connector Account) : A configured link to one payment processor (e.g. your Stripe credentials). You can attach many connectors and route between them.

Profile (Business Profile) : A logical grouping under a merchant — for example, one per brand, region, or business unit. Routing rules, webhooks, and settings can differ per profile.

Customer : An end user you bill. Customers can have saved payment methods.

Payment : A payment object (sometimes called the payment intent) that moves through a lifecycle from creation to a terminal state. Each processing try is a payment attempt.

Payment method : How the customer pays — card, wallet, bank_transfer, pay_later, etc. A specific instance (a saved card) can be tokenized in the vault for reuse.

Note

Hyperswitch exposes two API versions. v1 (paths like /payments) is the established, widely used API and powers the hosted sandbox. v2 (paths like /v2/payments) is a newer, more resource-oriented API that splits intent creation from confirmation. This guide focuses on v1 and flags v2 where it differs.


5. Authentication

Hyperswitch authenticates API requests with keys. There are five key types; you mostly use the first three.

Key type Example prefix Where you use it
Secret (API) key snd_…, prod_… Server-to-server requests, in the api-key header. Keep it secret.
Admin API key (deployment config value) System operations: creating merchant and connector accounts.
Publishable key pk_snd_… Client-side (web/mobile) code. Safe to expose.
Ephemeral key (short-lived) Temporary, scoped access to a single customer object.
JWT bearer (Authorization: Bearer …) Control Center sessions and user authentication. Issued during login.

Server-side requests pass the secret key in the api-key header:

curl http://localhost:8080/payments \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{"amount": 6540, "currency": "USD"}'

Caution

Never expose your secret key or admin key in browser or mobile code. Use the publishable key for any client-side call.

The Admin API key is not generated from the dashboard — it is a value you set when you deploy. For Docker Compose it lives in config/docker_compose.toml:

# config/docker_compose.toml
admin_api_key = "your_admin_key_here"

For Helm, set it in your values.yaml:

# values.yaml
adminApiKey: your_admin_key_here

Important

On the hosted sandbox/production environments, admin API keys are managed by Juspay and are not provided publicly. The admin key matters when you self-host and need to bootstrap merchant and connector accounts via the API.


6. Your First Payment (API)

A payment moves through a predictable lifecycle. These are the statuses you will see:

Status Meaning
requires_payment_method Payment created; no payment method attached yet.
requires_confirmation A payment method is attached; awaiting confirmation.
requires_customer_action Confirmed, but the customer must complete authentication (e.g. 3DS redirect).
requires_capture Authorized; awaiting a separate capture (manual capture mode).
processing Being processed by the connector (automatic capture).
succeeded Completed successfully.
failed The processor reported a processing failure.

Additional terminal/partial states include partially_captured, partially_captured_and_capturable, conflicted (an amount/currency discrepancy, possible with crypto or EU bank-transfer flows), and expired.

6.1 Create a payment

The minimal request needs only an amount (in the currency's minor unit — e.g. cents) and a currency:

curl http://localhost:8080/payments \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "amount": 6540,
    "currency": "USD"
  }'

You can include customer details, a description, and metadata in the same call:

curl http://localhost:8080/payments \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "amount": 6540,
    "currency": "USD",
    "customer": {
      "id": "cus_abcdefgh",
      "email": "[email removed]",
      "name": "John Dough",
      "phone": "9123456789"
    },
    "description": "My first payment request",
    "metadata": { "udf1": "some-value" }
  }'

The response contains the payment payment_id, a client_secret (used by the SDK on the client side), the current status, and the list of available payment methods.

Tip

amount is always an integer in the minor unit of the currency: 6540 means USD 65.40. Hyperswitch never uses floating-point amounts.

6.2 Confirm the payment

Attach a payment method and confirm. The example below confirms with raw card data (only do this from a PCI-compliant server; otherwise use the SDK):

curl http://localhost:8080/payments/{payment_id}/confirm \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "payment_method": "card",
    "payment_method_data": {
      "card": {
        "card_number": "4242424242424242",
        "card_exp_month": "10",
        "card_exp_year": "25",
        "card_cvc": "123",
        "card_holder_name": "Joseph Doe"
      }
    }
  }'

Note

You can collapse create + confirm into one call by adding "confirm": true (and the payment method fields) to the create request. Separating them is useful when the client attaches the payment method.

If the connector requires customer authentication (such as 3D Secure), the payment moves to requires_customer_action and the response includes a redirect URL. After the customer completes it, they return to your return_url with query parameters:

?status=succeeded&payment_intent_client_secret=pay_..._secret_...&amount=10000&manual_retry_allowed=false&signature=...&signature_algorithm=HMAC-SHA512

Tip

Verify the signature parameter using your profile's payment_response_hash_key before trusting the redirect result. Never treat the redirect query string as authoritative without verifying the HMAC.

6.3 Capture (manual capture mode)

If you created the payment with "capture_method": "manual", authorize now and capture later. Capture the full amount with an empty body, or a partial amount:

# Partial capture
curl http://localhost:8080/payments/{payment_id}/capture \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{ "amount_to_capture": 654 }'
# Full capture
curl http://localhost:8080/payments/{payment_id}/capture \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{}'

6.4 Retrieve / sync a payment

curl http://localhost:8080/payments/{payment_id} \
  -H 'api-key: snd_your_secret_key'

Use the /payments/{payment_id} GET to fetch the latest known state. To force a status refresh from the connector, use the sync endpoint (POST /payments/sync).

6.5 Make a 3DS payment

Request 3D Secure explicitly at creation:

curl http://localhost:8080/payments \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "amount": 6540,
    "currency": "USD",
    "authentication_type": "three_ds"
  }'

7. Refunds

Refund a succeeded payment. refund_type: "instant" attempts an immediate refund; omit amount to refund the whole payment.

# Partial refund
curl http://localhost:8080/refunds \
  -H 'api-key: snd_your_secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "payment_id": "pay_the_payment_id",
    "amount": 654,
    "refund_type": "instant",
    "reason": "Customer returned product"
  }'

Retrieve a refund:

curl http://localhost:8080/refunds/{refund_id} \
  -H 'api-key: snd_your_secret_key'

Note

A deployment limits refunds per payment via the refund.max_attempts setting (default 10) and the maximum refundable age via refund.max_age (default 365 days). See the Admin Guide.


8. Connectors (Payment Processors)

A connector is your configured credentials for one processor. Hyperswitch ships integrations for 100+ processors including Stripe, Adyen, PayPal, Checkout.com, Cybersource, Bank of America, Worldpay, Braintree, and Global Payments.

The easiest way to add a connector is the Control Center (http://localhost:9000): open Connectors → Add a payment processor, choose the processor, and enter its credentials. You can also create one through the API using an Admin API key (the MerchantConnectorAccount endpoints).

Important

When you self-host, every connector you intend to use must have a valid base URL configured in the server config. The [connectors] section of config/config.example.toml lists the sandbox base URLs for each processor (for example adyen.base_url, stripe.base_url). Empty or invalid base URLs cause requests to that connector to fail.

Restricting payment methods per connector

You can limit which payment methods a connector offers based on currency and country using payment method filters ([pm_filters.<connector>]):

[pm_filters.stripe]
paypal = { currency = "USD,INR", country = "US" }

This restricts Stripe's PayPal method to USD/INR in the US. If you omit currency or country, all values are accepted. See the Admin Guide for the full filter reference.


9. Routing

Routing decides which connector processes a transaction. Hyperswitch supports static and dynamic strategies, configured per profile through the API (or the Control Center's visual workflow builder).

Common routing operations (under /routing):

Operation Endpoint
Create a routing config POST /routing
List routing configs GET /routing
Activate a config POST /routing/{algorithm_id}/activate
Retrieve the active config GET /routing/active
Set the default config POST /routing/default
Decision manager (3DS / surcharge rules) PUT/GET/DELETE /routing/decision, /routing/decision/surcharge
Evaluate a routing rule POST /routing/rule/evaluate

Tip

Intelligent (success-rate-based) routing continuously sends transactions to the processor with the highest predicted authorization rate and retries failures on alternates. Enable and tune it from the Control Center; the underlying configuration is exposed through these endpoints.


10. Other Everyday Tasks

10.1 Saving payment methods and mandates

  • Save a payment method for a customer so they can pay again without re-entering details (vaulted via the card vault). Pass customer_acceptance on confirm to record consent.
  • Mandates authorize recurring or merchant-initiated transactions. Manage them under /mandates (retrieve, revoke) and via a customer's mandates (GET /customers/{customer_id}/mandates).

10.2 Payouts

Send money out (if your deployment is built with the payouts feature and a payout-capable connector):

Operation Endpoint
Create a payout POST /payouts/create
Confirm / fulfill POST /payouts/{payout_id}/confirm, /fulfill
Cancel POST /payouts/{payout_id}/cancel
Retrieve GET /payouts/{payout_id}
List GET /payouts/list

10.3 Subscriptions

Recurring billing under /subscriptions:

Operation Endpoint
Create POST /subscriptions/create
Create & confirm POST /subscriptions
Confirm POST /subscriptions/{subscription_id}/confirm
Pause / resume / cancel POST /subscriptions/{subscription_id}/pause · /resume · /cancel
Estimate GET /subscriptions/estimate

10.4 Webhooks (receiving events)

Hyperswitch sends outgoing webhooks to your server for payment, refund, dispute, and other events when webhooks.outgoing_enabled is on. Configure your webhook endpoint per profile in the Control Center. Incoming webhooks from connectors are received at the /webhooks endpoints.

Tip

Webhook deliveries can be inspected and replayed via the webhook-events endpoints, and the dashboard surfaces delivery attempts. Always verify webhook signatures before acting on an event.

10.5 Disputes and fraud

  • Disputes (chargebacks) are tracked under /disputes (list, retrieve, submit evidence).
  • Blocklist lets you block specific cards/fingerprints (/blocklist).
  • If built with the fraud (frm) feature, fraud-management checks run inline on payments.

11. Accepting Payments in a Browser or App (SDKs)

For most integrations you should not send raw card data to your own server. Instead, collect payment details with a Hyperswitch checkout SDK, which tokenizes them directly:

  1. On your server, create a payment (POST /payments) and return its client_secret to your front end.
  2. On the client, initialize the SDK (hyperswitch-web for browsers; the Android/iOS/React Native/Flutter SDKs for mobile) with your publishable key and the client_secret.
  3. The SDK renders a unified checkout, collects and tokenizes the payment method, and confirms the payment.
  4. Handle the result (and any 3DS redirect) via the SDK callbacks.

Note

The react-demo-app bundled in the local setup (http://localhost:9060) is a working example of this flow against your local server.


12. Troubleshooting

Error: health endpoint not responding

Cause: The app server container is still starting, failed to start, or the database/Redis dependencies are not ready. Solution: Check container status with docker compose ps and logs with docker compose logs hyperswitch-server. The server depends on PostgreSQL and Redis being healthy first. Prevention: Wait for the migrations runner to finish on first boot; the database schema must be applied before the server accepts traffic.

Error: {"error":{"type":"api","message":"Failed to fetch currency exchange rate","code":"HE_00"}} — Could not acquire the lock for cache entry

Cause: A stale forex cache lock in Redis after enabling currency conversion. Solution: Remove the lock key, then restart the application:

redis-cli del "{forex_cache}_lock"

Prevention: This typically appears only right after first enabling forex. It is self-resolving once the lock clears.

Error: requests to a connector fail immediately

Cause: The connector's base_url is empty or invalid in your config, or the connector credentials are wrong. Solution: Confirm the [connectors].<connector>.base_url value is set (the [connectors] section of config.example.toml lists valid sandbox URLs), and re-check the credentials you entered in the Control Center. Prevention: Connector base URLs are not optional when self-hosting — set every one you use.

Error: payment stuck in requires_customer_action

Cause: The customer has not completed the required authentication (e.g. a 3DS challenge), or your return_url was not reachable. Solution: Ensure the customer is redirected to the URL returned on confirm, and that your return_url is publicly reachable. Retrieve the payment to see the latest status. Prevention: Always supply a valid return_url for flows that may require authentication.

Error: payment created but no connector attempted it

Cause: No connector is configured/enabled for the requested payment method, currency, or country, or a pm_filters rule excluded it. Solution: Add or enable a connector for that method in the Control Center, and check your [pm_filters.<connector>] rules. Prevention: Review payment-method filters when onboarding a new connector or currency.

Error: 401/403 on an API call

Cause: Wrong key for the operation — using a publishable key for a server call, or a regular API key where an admin key is required (creating merchant/connector accounts). Solution: Use the secret api-key for server requests; use the admin API key for account-creation endpoints. Prevention: See the key reference in Authentication.


13. FAQ

Q: Is Hyperswitch free and open source? Yes — it is licensed under the Apache 2.0 License. You can self-host it at no license cost.

Q: Do I need a PCI certification to use it? To send raw card numbers to your own server, yes. If you do not hold PCI certification, collect card data with the Hyperswitch checkout SDK (Unified Checkout) so card data never touches your server.

Q: How many payment processors does it support? 100+ out of the box, including Stripe, Adyen, PayPal, Checkout.com, Cybersource, Worldpay, Braintree, Bank of America, and Global Payments.

Q: What's the difference between the v1 and v2 APIs? v1 (/payments) is the established API used by the hosted sandbox. v2 (/v2/payments) is newer and splits intent creation (/create-intent) from confirmation (/confirm-intent). Pick one and stay consistent; this guide uses v1.

Q: Are amounts in dollars or cents? Always the minor unit (cents for USD). 6540 = USD 65.40.

Q: Can I run only the payment API without the dashboard, analytics, and scheduler? Yes — choose the Minimal profile in scripts/setup.sh (or build the server with only the oltp feature) to run a standalone app server.

Q: Do I have to send card data through Hyperswitch's API? No. The recommended path is the SDK, which tokenizes on the client. Server-side raw-card confirm exists for PCI-certified integrators.

Q: How do I save a card for future payments? Confirm the payment with a customer_acceptance object and a customer.id. The card is vaulted and can be reused via the customer's saved payment methods.

Q: Where do I configure routing rules? In the Control Center's routing workflow builder, or via the /routing API endpoints. Rules are scoped per business profile.

Q: How do I move from sandbox to production? Switch the base URL to https://api.hyperswitch.io (hosted) or your production deployment, and use prod_-prefixed keys with live connector credentials. Review the go-live checklist in the official API reference.

Q: Can I send money out, not just collect it? Yes, if your deployment is built with the payouts feature and a payout-capable connector. See Payouts.

Q: Where are the full request/response schemas? In the OpenAPI specification shipped with the project (api-reference/v1/openapi_spec_v1.json and the v2 spec) and the hosted API reference.


14. Reference

14.1 Default local ports

Port Service
8080 App server (REST API)
9000 Control Center dashboard
9050 Web checkout SDK
9060 React demo checkout app
5432 PostgreSQL
6379 Redis
8025 Mailhog (email testing UI)
3000 Grafana (monitoring profile)
8123 ClickHouse (olap profile)
9200 OpenSearch (olap profile)
8090 Kafka UI (olap profile)

14.2 Key payment endpoints (v1)

Method Path Purpose
POST /payments Create a payment (optionally confirm).
POST /payments/{payment_id}/confirm Attach a payment method and confirm.
POST /payments/{payment_id}/capture Capture an authorized payment (full or partial).
POST /payments/{payment_id}/cancel Cancel/void a payment.
GET /payments/{payment_id} Retrieve a payment.
POST /payments/sync Force a status sync from the connector.
GET /payments/list List payments.
POST /payments/{payment_id}/incremental_authorization Increase an authorization.
POST /refunds Create a refund.
GET /refunds/{refund_id} Retrieve a refund.
POST /customers Create a customer.
GET /customers/{customer_id} Retrieve a customer.
POST /payouts/create Create a payout.
POST /routing Create a routing configuration.
GET /health Liveness check.
GET /health/ready Readiness (deep health) check.

Note

v2 equivalents live under /v2/... (for example POST /v2/payments/create-intent and POST /v2/payments/{payment_id}/confirm-intent). The full, version-specific surface is in the bundled OpenAPI specs.

14.3 Where to go next

  • Self-hosting, configuration, security, and operations: the Hyperswitch Admin Guide.
  • Full request/response schemas: the bundled OpenAPI specifications.
  • Connector-specific setup: the official connector guides linked from the project README.