Skip to content

Vendure

Accept SumUp payments in Vendure with the SumUp plugin.

The SumUp plugin for Vendure adds SumUp as a payment integration for Vendure. It creates SumUp checkouts from Vendure’s payment flow while keeping your SumUp credentials on the server side.

The plugin supports:

  • Hosted Checkout, where the customer is redirected to a SumUp-hosted payment page
  • Widget-oriented storefront integrations that use a returned checkoutId
  • Webhook-driven payment updates through Vendure’s payment flow

View Vendure Plugin Repository

  • Active SumUp account
  • SumUp API key
  • SumUp merchant code
  • Vendure ^3.6.4
  • A Vendure server with payment methods enabled

Before going live, make sure your SumUp account is fully verified and your business model is supported according to our allowed businesses article.

Install the package in your Vendure project:

npm install @sumup/vendure-plugin

Register the plugin and payment handler in your Vendure config:

import { VendureConfig } from "@vendure/core";
import {
SumUpPlugin,
sumUpPaymentHandler,
} from "@sumup/vendure-plugin";
export const config: VendureConfig = {
plugins: [
SumUpPlugin.init({
apiKey: process.env.SUMUP_API_KEY!,
merchantCode: process.env.SUMUP_MERCHANT_CODE!,
checkoutMode: "hosted",
returnUrl: "https://your-vendure.example/payments/sumup/webhook",
redirectUrl: "https://storefront.example/checkout/sumup/return",
}),
],
paymentOptions: {
paymentMethodHandlers: [sumUpPaymentHandler],
},
};

returnUrl should be a publicly reachable URL that SumUp can call with checkout status updates. In most setups that should be your Vendure server’s /payments/sumup/webhook route.

Create a payment method in the Vendure Admin UI with:

  • Code: sumup
  • Handler: sumup

Optional handler arguments:

  • merchantCode
  • checkoutMode
  • returnUrl
  • redirectUrl
  • paymentDescription

Global defaults can be defined in SumUpPlugin.init() and overridden per payment method when needed.

Once the order is in ArrangingPayment, call addPaymentToOrder with method: "sumup" and any SumUp-specific metadata you need:

mutation AddPaymentToOrder {
addPaymentToOrder(
input: {
method: "sumup"
metadata: {
checkout_mode: "hosted"
checkout_reference: "ORDER-1001"
}
}
) {
... on Order {
id
state
payments {
transactionId
metadata
}
}
... on ErrorResult {
errorCode
message
}
}
}

The plugin stores SumUp data on the Vendure payment and exposes a safe subset through payments[].metadata.public.

Use checkout_mode: "hosted" or set checkoutMode: "hosted" in the plugin or payment-method config.

After addPaymentToOrder, redirect the shopper to:

payments[].metadata.public.hostedCheckoutUrl

Use your backend payment state as the source of truth. The redirect alone should not be treated as proof of a successful payment.

Use checkout_mode: "widget" if your storefront will mount SumUp’s checkout UI itself.

After addPaymentToOrder, read:

payments[].metadata.public.checkoutId

Use that checkoutId in your storefront’s SumUp client integration. The plugin still treats the webhook callback or a later checkout lookup as the source of truth for the final payment state.

If you need a lower-level widget implementation reference, see the Payment Widget guide.

The plugin exposes a notification endpoint at:

POST /payments/sumup/webhook

When SumUp calls this endpoint, the plugin re-fetches the checkout from SumUp and updates the matching Vendure payment from the checkout state.

The plugin exposes these fields in payments[].metadata.public:

FieldDescription
checkoutIdSumUp checkout ID
checkoutReferenceMerchant checkout reference sent to SumUp
checkoutModehosted or widget
hostedCheckoutUrlHosted Checkout URL when SumUp returns one
redirectUrlRedirect URL associated with the checkout
OptionRequiredDescription
apiKeyYesSumUp API key or access token. Keep it server-side.
merchantCodeYesSumUp merchant code that receives the payment.
defaultLanguageCodeNoLanguage used for the handler description shown in Vendure.
checkoutModeNoDefault checkout mode: hosted or widget. Defaults to hosted.
returnUrlNoBackend callback URL used by SumUp for checkout status updates.
redirectUrlNoURL the shopper is sent to after redirect-based payment flows.
paymentDescriptionNoDefault SumUp checkout description.
timeoutNoSumUp SDK request timeout in milliseconds.
maxRetriesNoSumUp SDK retry count.
supportedCurrenciesNoOverride the built-in supported currency allowlist.
clientNoInject a custom SumUp client implementation. Useful for tests.

The plugin maps SumUp checkout state to Vendure payment state like this:

  • Successful transaction or PAID checkout -> Settled
  • PENDING -> Authorized
  • FAILED -> Declined
  • EXPIRED -> Cancelled
  • Anything else -> Created

Before enabling the plugin in production, verify the following in a sandbox environment:

  • One successful Hosted Checkout payment
  • One successful widget-oriented payment flow
  • At least one webhook-driven payment update
  • SumUp’s deliberate failure path with amount 11
  • Expired or canceled checkouts mapping cleanly back into Vendure payment state