Juspay Hyperswitch
Unify payment providers with Juspay Hyperswitch
@juspay-tech/medusa-custom-payments
Custom payments provider plugin for Medusa v2. Enables payment processing through multiple connectors — Stripe, Adyen, PayPal, GlobalPay, Braintree, Cybersource, and Mollie — via a single Prism-powered provider.
Powered by Hyperswitch Prism, an open-source unified connector service (UCS) that abstracts connector-specific APIs behind a single interface.
Compatibility
Requirement Version Medusa Copy to clipboard>= 2.15.0 Node.js Copy to clipboard>= 20 Framework Medusa v2
Installation
1npm install @juspay-tech/medusa-custom-payments
Setup
1. Environment variables
12345678910111213141516# StripeSTRIPE_API_KEY=sk_test_...# AdyenADYEN_API_KEY=AQE...ADYEN_MERCHANT_ACCOUNT=YourMerchantAccountADYEN_WEBHOOK_SECRET=... # hex HMAC key — required for webhook processing# PayPalPAYPAL_CLIENT_ID=...PAYPAL_CLIENT_SECRET=...PAYPAL_WEBHOOK_ID=... # webhook ID — required for webhook processing# GlobalPayGLOBALPAY_APP_ID=...GLOBALPAY_APP_KEY=...
2. Register providers in Copy to clipboardmedusa-config.ts
1234567891011121314151617181920import { defineConfig, Modules } from "@medusajs/framework/utils"export default defineConfig({modules: [{key: Modules.PAYMENT,resolve: "@medusajs/payment",options: {providers: [{resolve: "@juspay-tech/medusa-custom-payments",id: "stripe",options: {connector: "stripe",connectorConfig: {apiKey: { value: process.env.STRIPE_API_KEY ?? "" },// Publishable key (not a secret) — surfaced in the payment// session as `publishableKey` for the storefront's Elements.publishableKey: process.env.STRIPE_PUBLISHABLE_KEY ?? "",},
3. Assign providers to regions
In the Medusa Admin, assign each provider to the regions where it should be available.
4. Switch to production
Change Copy to clipboardenvironment per provider when going live:
1environment: process.env.NODE_ENV === "production" ? "PRODUCTION" : "SANDBOX",
5. Start the backend
1npx medusa develop
Plugin Options
Option Type Required Default Description Copy to clipboardconnector Copy to clipboardstring Yes — Copy to clipboard"stripe", Copy to clipboard"adyen", Copy to clipboard"paypal", Copy to clipboard"globalpay", Copy to clipboard"braintree", Copy to clipboard"cybersource", Copy to clipboard"mollie" Copy to clipboardconnectorConfig Copy to clipboardobject Yes — Connector-specific credentials (see examples above) Copy to clipboardenvironment Copy to clipboardstring No Copy to clipboard"SANDBOX" Copy to clipboard"SANDBOX" or Copy to clipboard"PRODUCTION" Copy to clipboardcapture Copy to clipboardboolean No Copy to clipboardfalse Auto-capture on authorization
Connector Credentials Reference
Connector Required fields in Copy to clipboardconnectorConfig Copy to clipboardstripe Copy to clipboardapiKey, Copy to clipboardpublishableKey (optional — surfaced to the storefront) Copy to clipboardadyen Copy to clipboardapiKey, Copy to clipboardmerchantAccount, Copy to clipboardpublishableKey (optional Adyen client key — surfaced to the storefront) Copy to clipboardpaypal Copy to clipboardclientId, Copy to clipboardclientSecret, Copy to clipboardshippingPreference (optional) Copy to clipboardglobalpay Copy to clipboardappId, Copy to clipboardappKey Copy to clipboardbraintree Copy to clipboardpublicKey, Copy to clipboardprivateKey Copy to clipboardcybersource Copy to clipboardapiKey, Copy to clipboardmerchantAccount, Copy to clipboardapiSecret Copy to clipboardmollie Copy to clipboardapiKey
Each credential value is provided as Copy to clipboard{ value: string } to support secret manager integrations.
Connector Support Matrix
Connector Authorize Capture Void Refund Webhook Copy to clipboardadyen ✅ ✅ ✅ ✅ ✅ Copy to clipboardpaypal — ✅ ✅ ✅ ✅ Copy to clipboardstripe ✅ ✅ ✅ ✅ ○ Copy to clipboardglobalpay — ✅ ✅ ✅ ○ Copy to clipboardbraintree ✅ ✅ ✅ ✅ ○ Copy to clipboardcybersource ✅ ✅ ✅ ✅ ○ Copy to clipboardmollie ✅ ✅ ✅ ✅ ○
Legend
Symbol Meaning ✅ Supported ○ Not supported — state driven by synchronous flows — Not a separate step: connector captures funds immediately at authorize time (Copy to clipboardCaptureMethod.AUTOMATIC); payment goes straight to CAPTURED so only Refund is available afterward
Authorize result by connector
- Copy to clipboard
adyen, Copy to clipboardstripe, Copy to clipboardbraintree, Copy to clipboardcybersource, Copy to clipboardmollie→ payment lands as AUTHORIZED (funds reserved; Capture or Void available next) - Copy to clipboard
paypal, Copy to clipboardglobalpay→ payment lands as CAPTURED (funds collected immediately; Refund only)
Note: All flows in the matrix above are tested and verified under the sandbox / test environment of each connector. Production behavior should be validated separately before go-live.
Webhooks
All webhook processing goes through the hyperswitch-prism connector service (Copy to clipboardEventService.HandleEvent) — this provider contains no connector-specific webhook parsing or signature code.
Webhook URL pattern:
- Medusa: Copy to clipboard
{backend_url}/hooks/payment/{provider_id}
Connector Webhook events Source verification Copy to clipboardwebhookSecret value Copy to clipboardadyen payment + refund HMAC-SHA256 Hex HMAC key from Customer Area → Webhooks → Additional settings (required) Copy to clipboardpaypal payment + refund + dispute PayPal Copy to clipboardverify-webhook-signature API Webhook ID from the developer dashboard (required) Copy to clipboardstripe, Copy to clipboardglobalpay, Copy to clipboardbraintree, Copy to clipboardcybersource, Copy to clipboardmollie not supported — unused
For unsupported connectors, incoming webhooks are acknowledged and ignored (Copy to clipboardNOT_SUPPORTED); payment state is driven by the synchronous flows (Copy to clipboardauthorizePayment / Copy to clipboardgetPaymentStatus).
Verification is mandatory
Webhook events that cannot be source-verified are always rejected — in development and production alike. There is no bypass option:
- Without a configured Copy to clipboard
webhookSecret, adyen/paypal webhooks are rejected before reaching the connector service. - An event whose signature fails verification (wrong key, tampered payload, forged request) is acknowledged but never mapped to a payment action.
Setup
Adyen — in the Customer Area create a Standard webhook pointing at your webhook URL, generate an HMAC key under Additional settings, and configure it (hex string, exactly as displayed) as Copy to clipboardwebhookSecret. Set Copy to clipboardADYEN_WEBHOOK_SECRET in your environment.
PayPal — in the developer dashboard create a webhook for your app pointing at your webhook URL, then configure the generated webhook ID as Copy to clipboardwebhookSecret. Set Copy to clipboardPAYPAL_WEBHOOK_ID in your environment.
Configuration example
The webhook URL is derived from the provider Copy to clipboardid you set in Copy to clipboardmedusa-config.ts. With Copy to clipboardidentifier = "hyperswitch-prism", a provider registered as Copy to clipboardid: "adyen" is reachable at:
1{backend_url}/hooks/payment/hyperswitch-prism_adyen
1. Add the secrets to your environment
1234# Adyen — hex HMAC key from Customer Area → Developers → Webhooks → Additional settingsADYEN_WEBHOOK_SECRET=AB12CD34EF...# PayPal — webhook ID from the developer dashboardPAYPAL_WEBHOOK_ID=WH-1AB23456CD789...
2. Pass Copy to clipboardwebhookSecret in the provider options (Copy to clipboardmedusa-config.ts)
1234567891011121314151617181920{resolve: "@juspay-tech/medusa-custom-payments",id: "adyen",options: {connector: "adyen",connectorConfig: {apiKey: { value: process.env.ADYEN_API_KEY ?? "" },merchantAccount: { value: process.env.ADYEN_MERCHANT_ACCOUNT ?? "" },},webhookSecret: process.env.ADYEN_WEBHOOK_SECRET, // required for webhook processingenvironment: "SANDBOX",},},{resolve: "@juspay-tech/medusa-custom-payments",id: "paypal",options: {connector: "paypal",connectorConfig: {clientId: { value: process.env.PAYPAL_CLIENT_ID ?? "" },
3. Register the URL at the connector dashboard
Connector Provider Copy to clipboardid Webhook URL to register Adyen Copy to clipboardadyen Copy to clipboard{backend_url}/hooks/payment/hyperswitch-prism_adyen PayPal Copy to clipboardpaypal Copy to clipboard{backend_url}/hooks/payment/hyperswitch-prism_paypal
Local development — connector dashboards must reach your backend over the public internet. Expose your local server with a tunnel (e.g. Copy to clipboardngrok http 9000) and register the tunnel URL, for example Copy to clipboardhttps://abcd-1234.ngrok.io/hooks/payment/hyperswitch-prism_adyen.
The connector is taken from each provider's Copy to clipboardconnector
Note: Adyen refunds are asynchronous — the REFUND webhook is the settlement confirmation and is logged by the provider (Medusa has no refund webhook action, so it is acknowledged as Copy to clipboardNOT_SUPPORTED).
Test Cards
Stripe
Card Number Expiry CVV Copy to clipboard4242 4242 4242 4242 Copy to clipboard03/2030 Copy to clipboard737
Adyen
Card Number Expiry CVV Copy to clipboard4111 1111 4555 1142 Copy to clipboard03/2030 Copy to clipboard737
GlobalPay
Card Number Expiry CVV Copy to clipboard4263 9700 0000 5262 Copy to clipboard03/2030 Copy to clipboard737
PayPal
Card Number Expiry CVV Copy to clipboard4032 0366 9170 5063 Copy to clipboard10/2028 Copy to clipboard901
Storefront Integration
For React/Next.js storefront integration, see the companion package Copy to clipboard@juspay-tech/medusa-custom-payments-react.
License
Apache-2.0

