Skip to main content

Saferpay

Payment plugin for Worldline Saferpay, using the Payment Page API.

Installation​

Included in the all preset — registerAllPlugins() registers the plugin together with its webhook route and database module.

To register it individually:

import { pluginRegistry } from '@unchainedshop/core';
import { SaferpayPlugin } from '@unchainedshop/plugins/payment/saferpay';

pluginRegistry.register(SaferpayPlugin);

Register before startPlatform(). At startup, the plugin adds the saferpayTransactions database module and enables GET /payment/saferpay/webhook (path configurable via SAFERPAY_WEBHOOK_PATH). The Express/Fastify connector mounts the route. Initialization logs a warning and skips this plugin's adapter and route unless SAFERPAY_CUSTOMER_ID, SAFERPAY_TERMINAL_ID, SAFERPAY_API_USER, and SAFERPAY_API_PASSWORD are all set (including the credential fallbacks below); its database module has already been initialized.

Environment Variables​

VariableDefaultDescription
SAFERPAY_CUSTOMER_ID-Saferpay customer ID (required at initialization and by the API client)
SAFERPAY_TERMINAL_ID-Saferpay terminal ID (required at initialization; the adapter itself reads the terminalId provider configuration)
SAFERPAY_API_USER-API username (required at initialization and by the API client)
SAFERPAY_API_PASSWORD-API password (required at initialization, by the API client, and for webhook signatures)
SAFERPAY_BASE_URLhttps://test.saferpay.com/apiAPI base URL. Production: https://www.saferpay.com/api
SAFERPAY_WEBHOOK_PATH/payment/saferpay/webhookWebhook endpoint path
SAFERPAY_RETURN_PATH/saferpay/returnUser return URL path after payment
ROOT_URLhttp://localhost:4010Base URL for webhook notifications
EMAIL_WEBSITE_URL-Base URL for user redirects (falls back to ROOT_URL)

The v4.8 names SAFERPAY_USER / SAFERPAY_PW are still read as deprecated fallbacks for SAFERPAY_API_USER / SAFERPAY_API_PASSWORD.

Create Provider​

mutation CreateSaferpayProvider {
createPaymentProvider(
paymentProvider: {
type: GENERIC
adapterKey: "shop.unchained.payment.saferpay"
}
) {
_id
}
}

mutation ConfigureSaferpayProvider {
updatePaymentProvider(
paymentProviderId: "provider-id"
paymentProvider: {
configuration: [
{ key: "terminalId", value: "your-terminal-id" }
]
}
) {
_id
}
}

Provider configuration:

KeyDescription
terminalIdSaferpay terminal ID (required — the provider is inactive without it)

To use multiple terminals (e.g. one per currency), create multiple providers with different terminalId values.

Payment Flow​

Follows the standard checkout flow. Saferpay specifics:

signPaymentProviderForCheckout initializes a Payment Page and returns a JSON string:

{
"location": "https://test.saferpay.com/vt2/api/PaymentPage/...",
"token": "saferpay-token",
"transactionId": "hex-transaction-id"
}

Redirect the user to location. After payment, the user returns to EMAIL_WEBSITE_URL + SAFERPAY_RETURN_PATH?transactionId=<hex-id>, and Saferpay notifies the webhook (ROOT_URL + SAFERPAY_WEBHOOK_PATH?orderPaymentId=<id>&signature=<sig>&transactionId=<hex-id>, signature verified server-side), which checks out the cart. Fallback — checkout with the transaction id:

mutation {
checkoutCart(paymentContext: { transactionId: "hex-transaction-id" }) {
_id
status
}
}

The charge succeeds when the Saferpay transaction amount and currency match the order and its status is AUTHORIZED or CAPTURED.

Optional transactionContext fields for signPaymentProviderForCheckout: description (payment description, default "Bestellung"), Payment (override payment details), ReturnUrl (override return URL). Additional fields are forwarded to the Payment Page Initialize request.

Capture and Cancel​

AUTHORIZED transactions are captured on confirmOrder and cancelled on rejectOrder:

mutation ConfirmOrder {
confirmOrder(orderId: "order-id") {
_id
status
}
}

Adapter Details​

PropertyValue
Keyshop.unchained.payment.saferpay
TypeGENERIC
Version1.38.0
Sourcepayment/saferpay/