Overview
Icon for SumUp

SumUp

Process payments in your store with SumUp

SumUp Payments for Medusa

A SumUp payment provider plugin for Medusa V2. Inspired by https://github.com/VariableVic/mollie-payments-medusa and mostly implemented by Claude.

[!WARNING] This plugin has not been tested on a live store. Please conduct thorough testing before using it in a production environment. I am not responsible for any missed or failed payments resulting from the use of this plugin. If you encounter any issues, please report them here.

Table of Contents

  • Features
  • Prerequisites
  • Installation
  • Configuration
    • Configuration Options
    • Environment Variables
  • Usage
  • Client-Side Integration
  • License

Features

  • SumUp Checkout: Creates a hosted SumUp checkout session that customers complete via the SumUp Card Widget or a custom card form.
  • Webhook Support: Receives real-time checkout status updates via SumUp webhooks.
  • Refunds: Supports full and partial refunds via the SumUp Transactions API.
  • Amount verification: A PAID checkout only authorizes/captures the session it was created for — its amount and currency must match the ones stored in the session data.
  • No extra dependencies: Uses the native Node.js Copy to clipboardfetch API — no additional HTTP client needed.

Prerequisites

  • Medusa server v2.3.0 or later
  • Node.js v20 or later
  • A SumUp merchant account with a valid API key and merchant code
[!NOTE] You can find your API key and merchant code in your SumUp Dashboard under Settings → Developer → API Keys.

Installation

npm install medusa-payment-sumup
# or
yarn add medusa-payment-sumup

Configuration

Add the provider to the Copy to clipboard@medusajs/payment module in your Copy to clipboardmedusa-config.ts file:

modules: [
// ... other modules
{
resolve: "@medusajs/payment",
options: {
providers: [
// ... other providers
{
resolve: "medusa-payment-sumup/providers/sumup",
id: "sumup",
options: {
apiKey: process.env.SUMUP_API_KEY,
merchantCode: process.env.SUMUP_MERCHANT_CODE,
medusaUrl: process.env.MEDUSA_BACKEND_URL,
redirectUrl: process.env.SUMUP_REDIRECT_URL,
},
},
],
},
},

Configuration Options

Option Description Required Default Copy to clipboardapiKey Your SumUp API key (e.g. Copy to clipboardsup_sk_...) ✅ — Copy to clipboardmerchantCode Your SumUp merchant code (e.g. Copy to clipboardMXXXXXXX) ✅ — Copy to clipboardmedusaUrl The public URL of your Medusa backend ✅ — Copy to clipboardredirectUrl The default storefront URL to redirect the customer to after payment. Must be a valid Copy to clipboardhttp/Copy to clipboardhttps URL. ✅ — Copy to clipboardredirectUrlAllowedHosts Extra hostnames permitted when a payment session supplies its own Copy to clipboarddata.redirect_url. The host of Copy to clipboardredirectUrl is always allowed. Any override on a non-allowed host is rejected (open-redirect protection). ❌ Copy to clipboard[redirectUrl host] Copy to clipboarddebug Enable verbose debug logging ❌ Copy to clipboardfalse

Per-session redirect URL

A payment session may override the redirect target by passing Copy to clipboarddata.redirect_url (e.g. a locale-specific Copy to clipboardhttps://shop.example.com/us/checkout/complete). The override is accepted only when its host is the same as Copy to clipboardredirectUrl's host or appears in Copy to clipboardredirectUrlAllowedHosts, and its scheme is Copy to clipboardhttp/Copy to clipboardhttps; otherwise the checkout is rejected with Copy to clipboardINVALID_DATA. When omitted, Copy to clipboardredirectUrl is used.

[!IMPORTANT] The storefront's own origin must be an allowed redirect host. A typical storefront sends Copy to clipboarddata.redirect_url = \${location.origin}/${countryCode}/checkout/complete`Copy to clipboardon every payment session. If the storefront's domain is **not** the host of the backend's configuredredirectUrlCopy to clipboard**and** is not listed inredirectUrlAllowedHosts`, session creation fails and customers cannot pay.



This bites most often when the backend Copy to clipboardredirectUrl env and the storefront domain drift apart between environments (e.g. a Copy to clipboard*.sslip.io or preview deploy, or a separate admin vs. storefront domain). Whenever you add a storefront origin, add it to Copy to clipboardredirectUrlAllowedHosts. Example:

options: {
redirectUrl: "https://shop.example.com/checkout/complete",
redirectUrlAllowedHosts: [
"shop.example.com",
"staging.shop.example.com",
"my-preview.sslip.io",
],
}

Environment Variables

Add the following to your Copy to clipboard.env file:

SUMUP_API_KEY=sup_sk_your_api_key
SUMUP_MERCHANT_CODE=YOUR_MERCHANT_CODE
MEDUSA_BACKEND_URL=https://your-medusa-server.com
SUMUP_REDIRECT_URL=https://your-store.com/checkout/payment

Usage

Once installed and configured, the SumUp payment method will be available in your Medusa Admin. To enable it:

  1. Log in to your Medusa Admin
  2. Go to Settings → Regions
  3. Add or edit a region and select SumUp from the payment providers dropdown

The provider ID for the SumUp checkout is:

pp_sumup_sumup

Client-Side Integration

SumUp checkouts are created server-side by Medusa. After a payment session is initiated, the session data will contain a SumUp checkout Copy to clipboardid that you pass to the SumUp Card Widget on your storefront to render the payment form.

Basic flow:

  1. Customer reaches the payment step — Medusa creates a SumUp checkout via Copy to clipboardinitiatePayment
  2. Your storefront receives the checkout Copy to clipboardid from the payment session data
  3. Render the SumUp Card Widget with the checkout ID
  4. SumUp processes the payment and calls the Medusa webhook (Copy to clipboard/hooks/payment/sumup_sumup)
  5. Because SumUp auto-captures, a Copy to clipboardPAID checkout is reported to Medusa as captured at authorize time — the order's payment is marked captured immediately on completion, without waiting for the webhook. The webhook (which the plugin always re-verifies against the SumUp API, since SumUp webhooks are unsigned) acts as a backstop that reconciles status if the browser flow is interrupted.

Example Card Widget integration:

<script src="https://gateway.sumup.com/gateway/ecom/card/v2/sdk.js"></script>
<div id="sumup-card"></div>
<script>
SumUpCard.mount({
checkoutId: "<checkout-id-from-session-data>",
onResponse: function (type, body) {
if (type === "success") {
// Redirect or poll for order completion
}
},
});
</script>

For APMs (iDEAL, Bancontact, etc.), the Copy to clipboardredirectUrl option handles the post-payment redirect automatically.

License

MIT

You may also like

Browse all integrations

Build your own

Develop your own custom integration

Build your own integration with our API to speed up your processes. Make your integration available via npm for it to be shared in our Library with the broader Medusa community.

gift card interface

Ready to build your custom commerce setup?