Comgate
Comgate payment provider for Medusa v2
medusa-plugin-comgate
Comgate payment provider for Medusa v2. Comgate is a Czech payment gateway (cards, Apple Pay / Google Pay, Czech & Slovak bank buttons, Twisto, etc).
Disclaimer: This is an unofficial, community-built integration. It is not affiliated with, endorsed by, or maintained by Comgate Payments, a.s. "Comgate" and the Comgate logo are trademarks of their respective owner, used here only to identify the payment gateway this plugin integrates with.
npm | Medusa integrations listing | Comgate API docs | Medusa Payment Module
Features
- Redirect (background / ) checkout flow.
- Optional pre-authorization mode (reserve now, capture later).
- Capture, cancel, refund from the admin dashboard.
- Background notification (webhook) handling via Medusa's endpoint.
Install
Configure
Add the provider to the Payment Module in :
Options
| Option | Required | Default | Description |
|---|---|---|---|
| yes | — | Comgate e-shop identifier. | |
| yes | — | Password for background communication. | |
| no | Test mode. | ||
| no | Create pre-authorizations; capture later. | ||
| no | Gateway / e-mail language (ISO 639-1). | ||
| no | Payer country (ISO 3166-1). | ||
| no | Statement label, 1–16 chars. | ||
| no | Payment method, or to let the payer choose. | ||
| / / | no | — | Return URLs. See note below — bake your own order id into them. |
| no | API base url (the version prefix is part of each path). Point it at an IPv4 relay if your host egresses over IPv6 — Comgate whitelists IPv4 only and answers otherwise. | ||
| no | — | Shared secret for the relay behind , sent as on every API call. Leave unset when calling Comgate directly. |
Each attempt times out after 15 s. Network errors (no HTTP response) are retried up to 4 attempts with 1 s / 2 s / 3 s backoff, so a relay waking from auto-suspend does not fail the call. Refunds and pre-auth captures retry only when the connection was never established (refused, DNS, connect timeout) — a drop mid-request may already have moved money, so it is surfaced instead. A request that got any HTTP response is never retried. Credentials (, the Basic token, ) are redacted from every thrown or logged message.
Pre-authorization
To run both a direct-capture and a pre-auth provider, register the module twice with different s and :
The provider id used in the storefront / API is (and ).
How it works
Uses the Comgate REST v2.0 JSON API (, HTTP Basic auth).
- → . Returns — send the payer there. The Medusa payment session id is passed as Comgate .
- The payer pays on the Comgate gateway.
- Webhook → Comgate POSTs a background notification (JSON or form-encoded) to . :
- rejects a present-but-wrong (constant-time compare);
- takes the canonical status, price, currency and from , not from the PUSH body. If that API is unreachable it falls back to the PUSH body only when its verified; otherwise it does nothing;
- requires Comgate's to equal the PUSH (the Medusa payment session id), and the session's stored to be absent or equal to the PUSH ;
- requires the canonical price and currency to equal the session's amount and currency (anti-tamper);
- maps , , , , with converted from Comgate minor units to Medusa's decimal. Any failed check returns (no state change) and logs an error. Medusa ignores , so a late after changes nothing, and a repeated is a no-op capture.
- → no-op for direct capture (already ); in pre-auth mode.
- → if the amount or currency changes, the plugin cancels the old Comgate payment and creates a new payment with the same . Comgate cannot change the amount of a payment.
- → , sending the flag the payment was created with (a mismatch is Comgate error 1402). → (storno, PENDING only) or in pre-auth mode.
Per Comgate's spec, order fulfillment must be driven by the background notification, not the payer's browser redirect, since redirect params are user-controlled. Comgate retries the PUSH up to 1000× until it gets a 2xx — Medusa's webhook handling is idempotent.
Comgate authenticates the PUSH by echoing the merchant in the body (no HMAC header). Restrict the webhook to Comgate's IP ranges () as a first layer; the secret check is the second.
Comgate Client Portal setup
In the Client Portal → Integrace → Nastavení obchodů → Přidat propojení obchodu:
| Field (CS) | Field (EN) | Value |
|---|---|---|
| Heslo | Password | → your |
| Povolený způsob založení platby | Payment creation method | HTTP POST protokol - backend (recommended) |
| Url pro předání výsledku platby | Background result URL (PUSH) | |
| Url zaplacený | Paid redirect | storefront order-confirmation page |
| Url zrušený | Cancelled redirect | storefront cart / retry page |
| Url nevyřízený | Pending redirect | storefront "payment processing" page |
| Povolené IP adresy / Povolit všechny IP | Allowed IPs | your backend's egress IP, or allow-all |
The PUSH URL is mandatory — without it payments never confirm in Medusa. When you save the connection, the portal probes the PUSH URL with a ; the plugin answers on that path (Medusa's own webhook route is -only), so the check passes. The three redirect URLs are browser-facing only and non-authoritative (the payer can forge their params); never mark an order paid from them. Order state is driven solely by the PUSH webhook.
Storefront redirect URLs (Medusa Next.js starter)
The return page must know which order it is. Comgate supports (Comgate transId) and (your reference) placeholders, case-sensitive — but only in the Comgate client-portal return-URL fields, where Comgate substitutes them at redirect time. The API / / request fields are used verbatim (no substitution, no params appended), so if you set the URLs via the API you must bake the identifier in yourself.
Portal (recommended — Comgate substitutes the placeholders):
API options (verbatim — bake in your own id):
url_paid: https://<storefront>/${countryCode}/order/confirmed?refId=<order-id>is the Medusa payment session id. The return page reads it and looks the order up. The redirect is non-authoritative regardless — the storefront must re-query order/payment status server-side before showing "paid".
Web/Mobile Checkout SDK checkboxes: leave off. This provider uses Comgate's hosted redirect flow, not the embedded checkout SDKs.
Configure the webhook
In the Comgate portal set the background-notification URL ("Url pro předání výsledku platby") to:
https://<your-backend>/hooks/payment/comgate_comgateDevelopment
Formatting and linting use oxc: writes, checks. runs format/lint checks on staged files pre-commit and typecheck/test pre-push — the hooks only check, they never rewrite files mid-commit. If the format check fails, run and re-stage.
Live smoke test against the Comgate v2.0 test API (no Medusa backend needed):
It creates a test payment and prints the URL — open it and pay with a Comgate test card to see the status flip to . Your IP must be allowed on the shop link (portal → Povolené IP adresy / Povolit všechny IP).
License
MIT
This project is an independent, unofficial integration and is not affiliated with or endorsed by Comgate Payments, a.s. All Comgate trademarks and logos are the property of their respective owner.

