Skip to main content

Saferpay

Unchained payment plugin for Worldline Saferpay, supporting the Payment Page API for various payment methods.

Installation

Express:

import saferpayTransactionsModule from '@unchainedshop/plugins/payment/saferpay';
import '@unchainedshop/plugins/payment/saferpay';
import { saferpayHandler } from '@unchainedshop/plugins/payment/saferpay/handler-express';

const { SAFERPAY_WEBHOOK_PATH = '/payment/saferpay/webhook' } = process.env;

// Add module to platform options
const unchainedApi = await startPlatform({
modules: {
saferpayTransactions: saferpayTransactionsModule,
},
});

// Note: Saferpay uses GET method with query parameters, no body parsing needed
app.get(SAFERPAY_WEBHOOK_PATH, saferpayHandler);

Fastify:

import saferpayTransactionsModule from '@unchainedshop/plugins/payment/saferpay';
import '@unchainedshop/plugins/payment/saferpay';
import { saferpayHandler } from '@unchainedshop/plugins/payment/saferpay/handler-fastify';

const { SAFERPAY_WEBHOOK_PATH = '/payment/saferpay/webhook' } = process.env;

// Add module to platform options
const unchainedApi = await startPlatform({
modules: {
saferpayTransactions: saferpayTransactionsModule,
},
});

// Note: Saferpay uses GET method with query parameters
fastify.route({
url: SAFERPAY_WEBHOOK_PATH,
method: 'GET',
handler: saferpayHandler,
});

Create Provider

mutation CreateSaferpayProvider {
createPaymentProvider(
paymentProvider: {
type: GENERIC
adapterKey: "shop.unchained.payment.saferpay"
configuration: [
{ key: "terminalId", value: "your-terminal-id" }
]
}
) {
_id
}
}

Environment Variables

VariableDefaultDescription
SAFERPAY_BASE_URLhttps://test.saferpay.com/apiAPI base URL. Production: https://www.saferpay.com/api
SAFERPAY_CUSTOMER_ID-Your Saferpay customer ID (required)
SAFERPAY_USER-API username (required)
SAFERPAY_PW-API password (required)
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)

Provider Configuration

KeyDescription
terminalIdYour Saferpay terminal ID (required)

Payment Flow

1. Sign for Checkout

Initialize a Saferpay Payment Page:

mutation SignPayment {
signPaymentProviderForCheckout(
orderPaymentId: "order-payment-id"
transactionContext: {
description: "Order Payment"
}
)
}

Returns a JSON string:

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

2. Redirect to Payment Page

const result = JSON.parse(signResult);
window.location.href = result.location;

3. Handle Return

After payment, users are redirected to:

EMAIL_WEBSITE_URL + SAFERPAY_RETURN_PATH?transactionId=<hex-id>

4. Complete Checkout

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

Webhook Notifications

The webhook receives success notifications automatically:

ROOT_URL/payment/saferpay/webhook?orderPaymentId=<id>&signature=<sig>&transactionId=<hex-id>

The signature is verified server-side for security.

Payment States

Saferpay StatusDescriptionAction
AUTHORIZEDPayment authorizedReady for capture
CAPTUREDPayment capturedOrder complete

Confirm and Cancel

Capture Payment

After successful checkout with AUTHORIZED status:

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

Cancel Authorization

Before capture:

mutation CancelOrder {
rejectOrder(orderId: "order-id") {
_id
status
}
}

Multiple Terminals

Create multiple providers with different terminal IDs:

mutation CreateCHFTerminal {
createPaymentProvider(
paymentProvider: {
type: GENERIC
adapterKey: "shop.unchained.payment.saferpay"
configuration: [
{ key: "terminalId", value: "chf-terminal-id" }
]
}
) {
_id
}
}

Transaction Context Options

Available options in transactionContext:

KeyDescription
descriptionPayment description shown to user
PaymentOverride payment details
ReturnUrlOverride return URL

Testing

Use test credentials:

  • Set SAFERPAY_BASE_URL=https://test.saferpay.com/api
  • Use Saferpay test credentials
  • Test cards available in Saferpay documentation

Features

  • Payment Page API integration
  • Multiple terminal support
  • Authorization with deferred capture
  • Signature-verified webhooks
  • Cancellation support

Adapter Details

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