By NewProWeb
Strapi plugin for Payone payment gateway integration
released September 30, 2026
npm install strapi-plugin-payone-providerA comprehensive Strapi plugin that integrates the Payone payment gateway into your Strapi application. This plugin provides both backend API integration and an admin panel interface for managing payment transactions.
Before installing this plugin, ensure you have:
You will need the following credentials from your Payone account:
ℹ️ How to get Payone credentials: Log into your Payone Merchant Interface (PMI) and navigate to Configuration → Payment Portals → [Your Portal] → Advanced Tab to find these credentials.
Important: Choose the correct version based on your Strapi version:
^5.x.x^4.x.x# npm
npm install strapi-plugin-payone-provider
# yarn
yarn add strapi-plugin-payone-provider
# pnpm
pnpm add strapi-plugin-payone-provider
Version Compatibility: Make sure to install the correct plugin version that matches your Strapi version. Using an incompatible version may cause errors or unexpected behavior.
After installation, you need to configure your Payone credentials:
Test for testing or Live for production (switching to Live asks for confirmation)3.10 (default)The admin page has three tabs:
⚠️ Important: Apple Pay requires a registered domain with HTTPS. It does NOT work on localhost. For testing, use a production domain with HTTPS or test on a device with Safari (iOS/macOS).
Apple Pay requires a domain verification file to be placed on your server. This file must be accessible at:
https://yourdomain.com/.well-known/apple-developer-merchantid-domain-associationSteps to set up the domain verification file:
Download the file from Payone:
Place the file in Strapi:
public/.well-known/ (if it doesn't exist)public/.well-known/apple-developer-merchantid-domain-associationPlace the file in your Frontend (if separate):
public/.well-known/ (if it doesn't exist)public/.well-known/apple-developer-merchantid-domain-associationVerify accessibility:
https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association⚠️ Critical: Without this file, Apple Pay will NOT work on your domain. The file must be accessible via HTTPS and must match exactly what Payone provides.
Apple Pay requires Content Security Policy (CSP) configuration in config/middlewares.js to allow Apple Pay scripts. Without this configuration, Apple Pay will NOT work on your strapi admin for make test transaction.
Required CSP directives:
module.exports = [
"strapi::logger",
"strapi::errors",
{
name: "strapi::security",
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
"script-src": [
"'self'",
"'unsafe-inline'",
"'unsafe-eval'",
"https://applepay.cdn-apple.com", // Apple Pay SDK
"https://www.apple.com", // Apple Pay manifest
],
"connect-src": [
"'self'",
"https:",
"https://applepay.cdn-apple.com", // Apple Pay API
"https://www.apple.com", // Apple Pay manifest
],
"frame-src": [
"'self'",
"https://applepay.cdn-apple.com", // Apple Pay iframe
],
},
},
},
},
// ... other middlewares
];⚠️ Important: Without this middleware configuration, Apple Pay scripts will be blocked and Apple Pay will NOT work!
Google Pay requires Content Security Policy (CSP) configuration in config/middlewares.js to allow Google Pay scripts. Without this configuration, Google Pay will NOT work on your strapi admin for make test transactions.
Required CSP directives:
module.exports = [
"strapi::logger",
"strapi::errors",
{
name: "strapi::security",
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
"script-src": [
"'self'",
"'unsafe-inline'",
"'unsafe-eval'",
"https://pay.google.com", // Google Pay SDK
],
"connect-src": [
"'self'",
"https:",
"https://pay.google.com", // Google Pay API
],
"frame-src": [
"'self'",
"https://pay.google.com", // Google Pay iframe
],
},
},
},
},
// ... other middlewares
];⚠️ Important: Without this middleware configuration, Google Pay scripts will be blocked and Google Pay will NOT work!
All API endpoints are available at:
Content API (Frontend): /api/strapi-plugin-payone-provider
Admin API: /strapi-plugin-payone-provider
⚠️ Authentication Required: All endpoints require authentication. Include your Bearer token in the Authorization header.
{
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_AUTH_TOKEN"
}All responses include:
status: Transaction status (APPROVED, ERROR, REDIRECT, etc.)txid: Transaction ID (for successful transactions)errorcode: Error code (if status is ERROR)errormessage: Error message (if status is ERROR)This section provides detailed API documentation for each supported payment method. Click on any payment method below to see the full implementation details:
Endpoints:
POST /api/strapi-plugin-payone-provider/preauthorizationPOST /api/strapi-plugin-payone-provider/authorizationRequest Body:
{
"amount": 1000,
"currency": "EUR",
"reference": "PAY1234567890ABCDEF",
"clearingtype": "cc",
"cardtype": "V",
"cardpan": "4111111111111111",
"cardexpiredate": "2512",
"cardcvc2": "123",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"telephonenumber": "+4917512345678",
"street": "Main Street 123",
"zip": "12345",
"city": "Berlin",
"country": "DE",
"successurl": "https://www.example.com/success",
"errorurl": "https://www.example.com/error",
"backurl": "https://www.example.com/back",
"salutation": "Herr",
"gender": "m",
"ip": "127.0.0.1",
"language": "de",
"customer_is_present": "yes"
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789",
"userid": "987654321"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/captureRequest Body:
{
"txid": "123456789",
"amount": 1000,
"currency": "EUR",
"sequencenumber": 1
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/refundRequest Body:
{
"txid": "123456789",
"amount": -1000,
"currency": "EUR",
"reference": "REF1234567890ABCDEF",
"sequencenumber": 2
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoints:
POST /api/strapi-plugin-payone-provider/preauthorizationPOST /api/strapi-plugin-payone-provider/authorizationRequest Body:
{
"amount": 1000,
"currency": "EUR",
"reference": "PAY1234567890ABCDEF",
"clearingtype": "wlt",
"wallettype": "PPE",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"telephonenumber": "+4917512345678",
"street": "Main Street 123",
"zip": "12345",
"city": "Berlin",
"country": "DE",
"shipping_firstname": "John",
"shipping_lastname": "Doe",
"shipping_street": "Main Street 123",
"shipping_zip": "12345",
"shipping_city": "Berlin",
"shipping_country": "DE",
"successurl": "https://www.example.com/success",
"errorurl": "https://www.example.com/error",
"backurl": "https://www.example.com/back",
"salutation": "Herr",
"gender": "m",
"ip": "127.0.0.1",
"language": "de",
"customer_is_present": "yes"
}Response:
{
"data": {
"status": "REDIRECT",
"txid": "123456789",
"redirecturl": "https://secure.pay1.de/redirect/..."
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/captureRequest Body:
{
"txid": "123456789",
"amount": 1000,
"currency": "EUR",
"sequencenumber": 1,
"capturemode": "full"
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/refundRequest Body:
{
"txid": "123456789",
"amount": -1000,
"currency": "EUR",
"reference": "REF1234567890ABCDEF",
"sequencenumber": 2
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Google Pay integration requires obtaining an encrypted payment token from Google Pay API and sending it to Payone. The token must be Base64 encoded before sending to Payone.
1. Include Google Pay Script
<script async src="https://pay.google.com/gp/p/js/pay.js"></script>2. Initialize Google Pay
const paymentsClient = new google.payments.api.PaymentsClient({
environment: "TEST", // or "PRODUCTION" for live mode
});
const baseRequest = {
apiVersion: 2,
apiVersionMinor: 0,
};
const allowedCardNetworks = ["MASTERCARD", "VISA"];
const allowedAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];
const tokenizationSpecification = {
type: "PAYMENT_GATEWAY",
parameters: {
gateway: "payonegmbh",
gatewayMerchantId: "YOUR_PAYONE_MERCHANT_ID", // Use your Payone MID or Portal ID
},
};
const cardPaymentMethod = {
type: "CARD",
parameters: {
allowedCardNetworks,
allowedAuthMethods,
},
tokenizationSpecification,
};
const isReadyToPayRequest = Object.assign({}, baseRequest);
isReadyToPayRequest.allowedPaymentMethods = [cardPaymentMethod];
paymentsClient.isReadyToPay(isReadyToPayRequest).then(function (response) {
if (response.result) {
// Google Pay is available, show button
}
});3. Create Payment Button and Get Token
const paymentDataRequest = Object.assign({}, baseRequest);
paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod];
paymentDataRequest.transactionInfo = {
totalPriceStatus: "FINAL",
totalPrice: "10.00",
currencyCode: "EUR",
};
paymentDataRequest.merchantInfo = {
merchantId: "YOUR_GOOGLE_MERCHANT_ID", // Optional: from Google Console
merchantName: "Your Merchant Name",
};
const button = paymentsClient.createButton({
onClick: async () => {
try {
const paymentData = await paymentsClient.loadPaymentData(
paymentDataRequest
);
const token = paymentData.paymentMethodData.tokenizationData.token;
// Token is a JSON string, encode it to Base64 for Payone
const base64Token = btoa(unescape(encodeURIComponent(token)));
// Send to your backend
await fetch("/api/strapi-plugin-payone-provider/preauthorization", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer YOUR_TOKEN",
},
body: JSON.stringify({
amount: 1000,
currency: "EUR",
reference: "PAY1234567890ABCDEF",
googlePayToken: base64Token,
}),
});
} catch (error) {
console.error("Google Pay error:", error);
}
},
});
document.getElementById("google-pay-button").appendChild(button);Token Format
The token from Google Pay is a JSON string with the following structure:
{
"signature": "MEUCIFr4ETGzv0uLZX3sR+i1ScARXnRBrncyYFDX/TI/VSLCAiEAvC/Q4dqXMQhwcSdg/ZvXj8+up0wXsfHja3V/6z48/vk=",
"intermediateSigningKey": {
"signedKey": "{\"keyValue\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7PWUi+e6WPUhNmTSQ2WN006oWlcWy0FtBWizw9sph1wvX9XcXUNRLcfcsmCBfI5IsKQkjAmYxpCSB+L5sIudLw\\u003d\\u003d\",\"keyExpiration\":\"1722393105282\"}",
"signatures": [
"MEUCIQCpU30A3g2pP93IBE5NxgO9ZcJlGF9YPzCZS7H4/IR1CQIgF6+I5t8olT8YsRDUcj7w3R1bvX4ZCcyFXE2+YXa+3H0="
]
},
"protocolVersion": "ECv2",
"signedMessage": "{\"encryptedMessage\":\"...\",\"ephemeralPublicKey\":\"...\",\"tag\":\"...\"}"
}Important: The token must be Base64 encoded before sending to Payone.
Endpoints:
POST /api/strapi-plugin-payone-provider/preauthorizationPOST /api/strapi-plugin-payone-provider/authorizationRequest Body:
{
"amount": 1000,
"currency": "EUR",
"reference": "PAY1234567890ABCDEF",
"clearingtype": "wlt",
"wallettype": "GGP",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"telephonenumber": "+4917512345678",
"street": "Main Street 123",
"zip": "12345",
"city": "Berlin",
"country": "DE",
"shipping_firstname": "John",
"shipping_lastname": "Doe",
"shipping_street": "Main Street 123",
"shipping_zip": "12345",
"shipping_city": "Berlin",
"shipping_country": "DE",
"successurl": "https://www.example.com/success",
"errorurl": "https://www.example.com/error",
"backurl": "https://www.example.com/back",
"googlePayToken": "BASE64_ENCODED_TOKEN",
"salutation": "Herr",
"gender": "m",
"ip": "127.0.0.1",
"language": "de",
"customer_is_present": "yes"
}Payone Request Parameters (automatically added by plugin):
{
"request": "preauthorization",
"amount": 1000,
"currency": "EUR",
"reference": "PAY1234567890ABCDEF",
"clearingtype": "wlt",
"wallettype": "GGP",
"add_paydata[paymentmethod_token_data]": "BASE64_ENCODED_TOKEN",
"add_paydata[paymentmethod]": "GGP",
"add_paydata[paymentmethod_type]": "GOOGLEPAY",
"add_paydata[gatewayid]": "payonegmbh",
"add_paydata[gateway_merchantid]": "YOUR_PAYONE_MERCHANT_ID",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"street": "Main Street 123",
"zip": "12345",
"city": "Berlin",
"country": "DE",
"shipping_firstname": "John",
"shipping_lastname": "Doe",
"shipping_street": "Main Street 123",
"shipping_zip": "12345",
"shipping_city": "Berlin",
"shipping_country": "DE",
"successurl": "https://www.example.com/success",
"errorurl": "https://www.example.com/error",
"backurl": "https://www.example.com/back"
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/captureRequest Body:
{
"txid": "123456789",
"amount": 1000,
"currency": "EUR",
"sequencenumber": 1
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/refundRequest Body:
{
"txid": "123456789",
"amount": -1000,
"currency": "EUR",
"reference": "REF1234567890ABCDEF",
"sequencenumber": 2
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}clearingtype: Must be "wlt" (wallet)wallettype: Must be "GGP" (Google Pay)add_paydata[paymentmethod_token_data]: Base64 encoded Google Pay token (automatically added by plugin)add_paydata[paymentmethod]: "GGP" (automatically added by plugin)add_paydata[paymentmethod_type]: "GOOGLEPAY" (automatically added by plugin)add_paydata[gatewayid]: "payonegmbh" (automatically added by plugin)add_paydata[gateway_merchantid]: Your Payone Merchant ID (automatically added by plugin)Endpoints:
POST /api/strapi-plugin-payone-provider/preauthorizationPOST /api/strapi-plugin-payone-provider/authorizationRequest Body:
{
"amount": 1000,
"currency": "EUR",
"reference": "PAY1234567890ABCDEF",
"clearingtype": "wlt",
"wallettype": "APL",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"telephonenumber": "+4917512345678",
"street": "Main Street 123",
"zip": "12345",
"city": "Berlin",
"country": "DE",
"shipping_firstname": "John",
"shipping_lastname": "Doe",
"shipping_street": "Main Street 123",
"shipping_zip": "12345",
"shipping_city": "Berlin",
"shipping_country": "DE",
"successurl": "https://www.example.com/success",
"errorurl": "https://www.example.com/error",
"backurl": "https://www.example.com/back",
"salutation": "Herr",
"gender": "m",
"ip": "127.0.0.1",
"language": "de",
"customer_is_present": "yes"
}Response:
{
"data": {
"status": "REDIRECT",
"txid": "123456789",
"redirecturl": "https://secure.pay1.de/redirect/..."
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/captureRequest Body:
{
"txid": "123456789",
"amount": 1000,
"currency": "EUR",
"sequencenumber": 1,
"capturemode": "full"
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/refundRequest Body:
{
"txid": "123456789",
"amount": -1000,
"currency": "EUR",
"reference": "REF1234567890ABCDEF",
"sequencenumber": 2
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoints:
POST /api/strapi-plugin-payone-provider/preauthorizationPOST /api/strapi-plugin-payone-provider/authorizationRequest Body:
{
"amount": 1000,
"currency": "EUR",
"reference": "PAY1234567890ABCDEF",
"clearingtype": "elv",
"iban": "DE89370400440532013000",
"bic": "COBADEFFXXX",
"bankaccountholder": "John Doe",
"bankcountry": "DE",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"telephonenumber": "+4917512345678",
"street": "Main Street 123",
"zip": "12345",
"city": "Berlin",
"country": "DE",
"salutation": "Herr",
"gender": "m",
"ip": "127.0.0.1",
"language": "de",
"customer_is_present": "yes"
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789",
"userid": "987654321"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/captureRequest Body:
{
"txid": "123456789",
"amount": 1000,
"currency": "EUR",
"sequencenumber": 1
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/refundRequest Body:
{
"txid": "123456789",
"amount": -1000,
"currency": "EUR",
"reference": "REF1234567890ABCDEF",
"sequencenumber": 2
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/preauthorizationPOST /api/strapi-plugin-payone-provider/authorizationRequest Body:
{
"amount": 1000,
"currency": "EUR",
"reference": "PAY1234567890ABCDEF",
"clearingtype": "sb",
"onlinebanktransfertype": "PNT",
"bankcountry": "DE",
"firstname": "John",
"lastname": "Doe",
"email": "john.doe@example.com",
"telephonenumber": "+4917512345678",
"street": "Main Street 123",
"zip": "12345",
"city": "Berlin",
"country": "DE",
"successurl": "https://www.example.com/success",
"errorurl": "https://www.example.com/error",
"backurl": "https://www.example.com/back",
"salutation": "Herr",
"gender": "m",
"ip": "127.0.0.1",
"language": "de",
"customer_is_present": "yes"
}Response:
{
"data": {
"status": "REDIRECT",
"txid": "123456789",
"redirecturl": "https://secure.pay1.de/redirect/..."
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/captureRequest Body:
{
"txid": "123456789",
"amount": 1000,
"currency": "EUR",
"sequencenumber": 1
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}Endpoint:
POST /api/strapi-plugin-payone-provider/refundRequest Body:
{
"txid": "123456789",
"amount": -1000,
"currency": "EUR",
"reference": "REF1234567890ABCDEF",
"sequencenumber": 2
}Response:
{
"data": {
"status": "APPROVED",
"txid": "123456789"
}
}The Payone platform provides an asynchronous way of notifying your system of changes to a transaction. These notifications are called "TransactionStatus" and are automatically handled by this plugin.
TransactionStatus notifications are POST requests sent from Payone's servers to your endpoint when transaction status changes occur. This is especially important for:
TSOK to confirm receiptThe plugin automatically provides the TransactionStatus endpoint at:
URL: POST /api/strapi-plugin-payone-provider/transaction-status
No authentication required - The endpoint is secured by:
You need to configure this endpoint in your Payone Merchant Interface (PMI):
https://yourdomain.com/api/strapi-plugin-payone-provider/transaction-status⚠️ Important: The endpoint must be accessible via HTTPS. Payone will not send notifications to HTTP endpoints.
The plugin automatically verifies:
IP Address: Only accepts requests from Payone's IP ranges:
185.60.20.0/2454.246.203.105User-Agent: Must be exactly "PAYONE FinanceGate"
Hash Signature: Verifies MD5 hash using your Portal Key:
MD5(portalid + aid + txid + sequencenumber + price + currency + mode + key)Credentials: Verifies that portalid and aid match your configured settings
📖 Reference: For more details, see Payone TransactionStatus Notification Documentation
For additional information and updates, please refer to the official Payone documentation:
Payone Documentation: https://docs.payone.com/payment-methods
Share your work with the community and get it listed in the Strapi ecosystem for everyone to discover and use.
Submit
