# Hyperswitch Payments for GoCommerce — Open-Source Module

> Route payments through Hyperswitch, the open-source payments router, from a GoCommerce store: keys, payment links, webhook URL, refunds and limits.

- Canonical: https://kitcommerce.store/integrations/payments-hyperswitch/
- Last updated: 2026-09-25

---

Payments

## Hyperswitch payments for GoCommerce

A Go package that creates a Hyperswitch payment link at checkout and marks the GoCommerce order paid when Hyperswitch’s signed webhook says the payment succeeded. Which gateway takes the money is Hyperswitch’s routing decision, not the module’s.

- **Payments** module
- **7** settings
- **8** tests
- **ext/payments-hyperswitch**

### What it does

The module registers “hyperswitch” as a payment method. At checkout it creates a payment with payment_link switched on, for the order’s total in minor units, and answers with a redirect intent carrying the hosted link. The client secret comes along too, for a storefront that would rather mount Hyperswitch’s own SDK.

The package is clear about what Hyperswitch is: not a gateway but a router in front of gateways — Stripe, Adyen, Checkout.com, a local acquirer — chosen by rules in the Hyperswitch dashboard. Connector choice, retries and 3DS behaviour are configuration over there, and the module does not second-guess them. The engine still owns the order: Hyperswitch says money arrived, and the engine decides what that does.

In the admin it describes itself as “Payment links through Hyperswitch, the open-source payments router, with its signed webhook marking orders paid.” It talks to Hyperswitch’s hosted API by default, or to your own router when BaseURL points at it.

### Configuration

Two settings are required: the merchant API key and the business profile’s payment response hash key. A return URL is needed as well, in Config or on each checkout. Set them in Config from your own main(), or under Settings › Payment methods.

*Hyperswitch module settings — 7 settings, 2 required*

| Setting | Environment variable | Required | What it does |
| --- | --- | --- | --- |
| `APIKey` API key | `HYPERSWITCH_API_KEY` | Yes | The merchant API key, sent as the api-key header. Not sent to the storefront. |
| `ResponseHashKey` Payment response hash key | `HYPERSWITCH_RESPONSE_HASH_KEY` | Yes | The business profile’s key, which signs outgoing webhooks. Required because, as the code puts it, without it any caller could mark orders paid. |
| `ProfileID` Profile ID | — | No | The business profile to charge against. Only needed when the merchant has more than one; then leaving it empty is a 400 at the first checkout. |
| `ReturnURL` Return URL | — | No | Where the shopper lands after paying, when the checkout did not send return_url. Hyperswitch requires one of the two for a payment link. |
| `SessionExpirySeconds` Link expiry (seconds) | — | No | How long the hosted link stays payable. Zero leaves Hyperswitch’s own default. |
| `BaseURL` API base URL | — | No | Defaults to https://api.hyperswitch.io. The sandbox is https://sandbox.hyperswitch.io; a self-hosted router is its own address. |
| `Client` | — | No | Replaces the HTTP client, which otherwise times out after 20 seconds. Go only; not in the panel. |

The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own `main()` you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.

### Setting it up

1. **Prepare the profile** — On the Hyperswitch business profile, make sure payment links are enabled, point the webhook at https://your-api-host/api/checkout/hyperswitch/webhook, and note the response hash key.
2. **Install the module** — Import it and pass hyperswitch.New to gocommerce.New, as below — or run the reference binary with -gateways, which installs every payment module idle.
3. **Configure it** — API key, hash key and a return URL, in Config or under Settings › Payment methods. Point BaseURL at the sandbox while testing.
4. **Take a payment** — POST /api/checkout/hyperswitch answers with a redirect intent whose url is the payment link. The payment_succeeded webhook marks the order paid.

main.go

```
import (
	"os"

	"github.com/itswadesh/gocommerce/core"
	hyperswitch "github.com/itswadesh/gocommerce/ext/payments-hyperswitch"
)

app, err := gocommerce.New(cfg,
	hyperswitch.New(hyperswitch.Config{
		APIKey:          os.Getenv("HYPERSWITCH_API_KEY"),
		ResponseHashKey: os.Getenv("HYPERSWITCH_RESPONSE_HASH_KEY"),
		BaseURL:         "https://sandbox.hyperswitch.io",
	}),
)
```

The package doc’s own example, with its imports; cfg is your gocommerce.Config. It points at the sandbox; drop BaseURL for Hyperswitch’s hosted API, or set it to your own router. Import path `github.com/itswadesh/gocommerce/ext/payments-hyperswitch`.

### How it works

- **Signed with SHA-512**

  X-Webhook-Signature-512 is checked as a hex HMAC-SHA512 of the raw body, keyed on the response hash key, in constant time. The module does not fall back to the weaker 256-bit header the router can also send.

- **Each event once**

  Claims are keyed on Hyperswitch’s event_id, which is stable across retries; routers that send none fall back to event type plus payment id. A repeat is answered 200 and changes nothing.

- **Succeeded or failed**

  payment_succeeded and payment_captured mark the order paid. payment_failed, payment_cancelled and payment_expired mark the payment failed, with Hyperswitch’s reason.

- **A failed update is retried**

  If the engine cannot apply an event, the claim is released and the webhook answers 500, so the retry finds work to do.

- **Instant refunds**

  A refund posts to /refunds as an instant refund for the amount asked, so it either refunds or fails now, and the refund id is recorded. A scheduled refund would answer “accepted” and could still be declined later.

- **Reconcilable by order number**

  The order number goes as merchant_order_reference_id — what an operator searches for in the dashboard. Extra data from the storefront travels in metadata under client\_… keys, so it cannot overwrite the order id.

### What it does not do

Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.

- **A return URL is required** — Hyperswitch will not create a payment link without one. With neither Config.ReturnURL nor a return_url on the checkout, the module refuses to start the payment.
- **Replays are bounded by the claim** — The signature carries no timestamp, so a captured delivery stays valid for ever. The idempotency claim is the only thing stopping it applying twice.
- **Links, not the SDK** — The default is a redirect to the hosted link. A storefront that wants Hyperswitch’s web SDK gets the client_secret in the intent and builds that itself.
- **Dashboard refunds are only logged** — refund_succeeded is logged, not applied. A refund started in the Hyperswitch dashboard does not change the GoCommerce order.
- **No routing settings here** — Which connector takes a payment, retries and 3DS are set in Hyperswitch. The module has no settings for them, by design.
- **No test switch** — There is no sandbox flag. In Hyperswitch the environment is the host you talk to, so it is BaseURL.

FAQ

### Questions about the Hyperswitch module

**Is Hyperswitch a payment gateway?**

Not in the package’s words: it is a router in front of gateways, and which one takes a payment is decided by rules in the Hyperswitch dashboard. The module sends the payment to Hyperswitch and lets the router choose.

**Can I point it at a self-hosted Hyperswitch?**

Yes. BaseURL defaults to Hyperswitch’s hosted API; set it to your own router’s address, or to https://sandbox.hyperswitch.io for the sandbox.

**What is the webhook URL?**

POST /api/checkout/hyperswitch/webhook on the host that serves your GoCommerce API — a route the engine owns. The module verifies the X-Webhook-Signature-512 header on every delivery.

**Can I use it without writing Go?**

Yes. The reference binary’s -gateways flag installs every payment module with an empty Config. Switch Hyperswitch on under Settings › Payment methods and fill in the key, the hash key and a return URL there.

**Is this a Hyperswitch partnership?**

No. The module calls Hyperswitch’s public API with keys you supply. Hyperswitch does not endorse GoCommerce, and no store is known to run this module in production yet.

### Source

Everything on this page is read from [`ext/payments-hyperswitch`](https://github.com/itswadesh/gocommerce/tree/main/ext/payments-hyperswitch) in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.Hyperswitch is a trademark of its owner; this module talks to its public API and implies no endorsement. See [trademarks](https://kitcommerce.store/about/#trademarks).

- [ext/payments-hyperswitch on GitHub](https://github.com/itswadesh/gocommerce/tree/main/ext/payments-hyperswitch)
- [Hyperswitch](https://hyperswitch.io)
- [All GoCommerce modules](https://kitcommerce.store/integrations/)

### Try it against a store of your own

The one-command stack gives you GoCommerce’s API and admin on your own machine in minutes. Add this module to it and try it on test orders before a real one depends on it.

[Deploy in minutes](https://kitcommerce.store/#one-command) · [Read the module](https://github.com/itswadesh/gocommerce/tree/main/ext/payments-hyperswitch) · [All integrations](https://kitcommerce.store/integrations/)
