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
Prerequisites
- 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 Plugin
Install the package in your Vendure project:
npm install @sumup/vendure-plugin
Configure Vendure
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 the Payment Method
Create a payment method in the Vendure Admin UI with:
Code:sumupHandler:sumup
Optional handler arguments:
merchantCodecheckoutModereturnUrlredirectUrlpaymentDescription
Global defaults can be defined in SumUpPlugin.init() and overridden per payment method when needed.
Storefront Flow
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.
Choose a Checkout Flow
Hosted Checkout
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.
Widget-Oriented Flow
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.
Webhooks
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.
Public Payment Metadata
The plugin exposes these fields in payments[].metadata.public:
| Field | Description |
|---|---|
checkoutId | SumUp checkout ID |
checkoutReference | Merchant checkout reference sent to SumUp |
checkoutMode | hosted or widget |
hostedCheckoutUrl | Hosted Checkout URL when SumUp returns one |
redirectUrl | Redirect URL associated with the checkout |
Configuration Options
| Option | Required | Description |
|---|---|---|
apiKey | Yes | SumUp API key or access token. Keep it server-side. |
merchantCode | Yes | SumUp merchant code that receives the payment. |
defaultLanguageCode | No | Language used for the handler description shown in Vendure. |
checkoutMode | No | Default checkout mode: hosted or widget. Defaults to hosted. |
returnUrl | No | Backend callback URL used by SumUp for checkout status updates. |
redirectUrl | No | URL the shopper is sent to after redirect-based payment flows. |
paymentDescription | No | Default SumUp checkout description. |
timeout | No | SumUp SDK request timeout in milliseconds. |
maxRetries | No | SumUp SDK retry count. |
supportedCurrencies | No | Override the built-in supported currency allowlist. |
client | No | Inject a custom SumUp client implementation. Useful for tests. |
Payment State Mapping
The plugin maps SumUp checkout state to Vendure payment state like this:
- Successful transaction or
PAIDcheckout ->Settled PENDING->AuthorizedFAILED->DeclinedEXPIRED->Cancelled- Anything else ->
Created
Sandbox Checklist
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