zahls.ch payment provider for Medusa v2 (TWINT, cards, PostFinance).
zahls.ch payment provider for Medusa v2.
This plugin lets a Medusa application create and manage zahls.ch Gateway checkouts from the backend. It supports:
The plugin never handles raw card data directly. zahls.ch credentials remain on the Medusa backend.
npm install @zahls/medusa-pluginRegister the plugin and payment provider in :
1import { defineConfig } from "@medusajs/framework/utils"2
3export default defineConfig({4 plugins: [5 {6 resolve: "@zahls/medusa-plugin",7 options: {},8 },9 ],10 modules: [11 {12 resolve: "@medusajs/medusa/payment",13 options: {14 providers: [15 {16 resolve: "@zahls/medusa-plugin/providers/zahls",17 id: "zahls",18 options: {19 apiKey: process.env.ZAHLS_API_KEY,20 instance: process.env.ZAHLS_INSTANCE,21 webhookSecret: process.env.ZAHLS_WEBHOOK_SECRET,22 successRedirectUrl: process.env.ZAHLS_SUCCESS_URL,23 failedRedirectUrl: process.env.ZAHLS_FAILED_URL,24 cancelRedirectUrl: process.env.ZAHLS_CANCEL_URL,25 },26 },27 ],28 },29 },30 ],31})After the application starts, enable zahls.ch for the relevant region in Medusa Admin → Settings → Regions. Per Medusa's payment-provider model, the resulting provider identifier is when the service identifier is and the configured provider is .
| Option | Required | Description |
|---|---|---|
| Yes | Instance API secret from zahls.ch → API & Integrations. Keep it server-side. | |
| Yes | Instance name ( for ). | |
| Yes | Signing key for verification. Webhooks are rejected without it. | |
| No | Storefront URL after a successful payment. | |
| No | Storefront URL after a failed payment. | |
| No | Storefront URL after the customer cancels. | |
| No | Skip the zahls.ch result page (default ). |
Auth uses the header (recommended by the zahls.ch / Payrexx REST API).
The plugin creates a zahls.ch Gateway and stores the returned checkout in the payment-session data. The storefront should redirect the customer to that URL:
1const link = paymentSession.data?.link2if (typeof link === "string") {3 window.location.href = link4}Use backend / webhook state as the source of truth. The storefront should not treat the redirect alone as proof of payment success.
When available, customer name, email, company, and billing address from the Medusa payment context are prefilled on the Gateway.
Medusa provides a built-in webhook listener route for payment providers at:
/hooks/payment/[identifier]_[provider]For this plugin, with service identifier and provider , add this URL in the zahls.ch merchant backend (Webhooks), with JSON content type:
https://your-medusa-backend.com/hooks/payment/zahls_zahlsThe plugin verifies when is set, loads the Gateway from zahls.ch, maps the status to a Medusa payment action, and returns the payment session reference () back to Medusa.
| zahls.ch status | Medusa webhook action |
|---|---|
| / | |
| / |
on the Gateway is set to the Medusa payment session id so webhooks can resolve the session.
The payment-session data returned by the provider includes:
1npm run build2npm run dev1npm run test:unit2npm run test:integration:modulesModule integration tests need PostgreSQL (, , , ). Defaults: , user .
Publish locally with , then in a Medusa app:
npx medusa plugin:add @zahls/medusa-plugin