Skip to main content

Server-to-Server Processing

The Payment API used in this guide performs authorization and capture in a single step. If you need to separate authorization from capture, use the Authorize API followed by the Capture API instead.

This guide gives you a step-by-step instruction to get started:

  1. How to access your API credentials
  2. How to authenticate to the API
  3. How to create a Payment API request
  4. How to receive postback notifications (webhooks)

1. Accessing your API credentials

Contact your onboarding manager to get access to the Dashboards, where you will find your API credentials for authentication.

After logging in, navigate to My Company to find your Integration Data and API Passwords.

EnvironmentDashboardAPI Base URL
Testhttps://testdashboard.betterpayment.dehttps://testapi.betterpayment.de
Productionhttps://dashboard.betterpayment.dehttps://api.betterpayment.de
tip

Start your integration with the Test environment. Once validated, you will be granted access to Production.

2. Authentication

Before making any API requests, make sure you have your API Key and API Password from the API credentials above available.

Basic Authentication

The API uses Basic Authentication, a simple and widely supported authentication method built into the HTTP protocol. With Basic Auth, the system making the request sends an authorization header that includes the word Basic followed by a space and a Base64-encoded string in the format: username:password.

In this case:

username → your API Key
password → your API Password

For example, to authorize as demo / p@55w0rd, then the encoded header would look like this:

Authorization: Basic ZGVtbzpwQDU1dzByZA==

You don’t need to calculate the Base64 string manually — most HTTP libraries (such as curl, Postman, or your SDK) handle it automatically.

Content-Type Headers

All API requests use Basic Authentication and must include the following HTTP header:

Content-Type: application/json

Every request that sends data (for example, POST or PUT) must include a valid JSON body.

3. Idempotency

Our API supports idempotency to ensure safe retries of requests without unintended side effects. To use this feature, include a unique UUID in one of the following HTTP headers when making POST requests:

X-Idempotency-Key
Idempotency-Key

When a request is received with an idempotency key, the response is cached for 1 hour. Subsequent requests with the same idempotency key within this timeframe will return the cached response, preventing duplicate operations.

Best Practice: We recommend using RFC 4122 compliant UUIDs (version 4) for idempotency keys.

POST https://{testapi|api}.betterpayment.de/rest/payment
Authorization: Basic <base64(api_key:api_password)>
Content-Type: application/json
Idempotency-Key: 9d8f5715-2e7c-4e64-8e34-35f510c12e66
{
"payment_type": "cardecom",
"order_id": "12345678",
"amount": "15.90",
"currency": "EUR",
"additional_transaction_data": "customer_id=123ABC, billing_info=12345678",
"postback_url": "https://your-postback.url.com",
"success_url": "https://your-success.url.com",
"error_url": "https://your-error.url.com",
"card_number": "4761070000000509",
"card_holder": "John Doe",
"card_cvv": "196",
"card_expiry_month": "12",
"card_expiry_year": "2026"
}

4. Create a Payment API request

note

All requests must:

  • Use HTTPS
  • Include the Authorization header (with Basic Auth)
  • Include the Content-Type: application/json header if you are sending data
  • Use valid test or production URLs depending on your environment

The Server-to-Server Processing integration allows merchants or processors to send payment data directly to the Payment API without redirection to a payment page.

Example: Card ECOM

In the following example your system receives cardholder data (PAN, CVV, expiry date, cardholder name) and sends it directly to our API.

caution

This integration requires that you have the required PCI DSS compliance, since cardholder data is handled directly by your infrastructure.

Payment API Request

payment_typeStringrequired
cardecom
order_idStringrequired
Any alphanumeric string to identify the Merchant's order
amountFloatrequired
Amount of the transaction including all taxes and shipping fees
currencyStringrequired
3 letter currency code
postback_urlStringrequired
The URL for updates about transaction status are posted
success_urlStringrequired
Where to redirect the user after a successful transaction
error_urlStringrequired
Where to redirect the user after a failed transaction
card_numberStringrequired
Full card number (PAN) of the cardholder
card_holderStringrequired
Name of the cardholder as printed on the card
card_cvvStringrequired
Card verification value (3 digits on back of card)
card_expiry_monthStringrequired
Expiry month of the card (2 digits, e.g. 01–12)
card_expiry_yearStringrequired
Expiry year of the card (4 digits, e.g. 2026)
additional_transaction_dataString
Additional payment information provided by you. This will be shown in the dashboard as well as when you query for transaction data. It will also be sent back to your postback_url as part of the postback data.
Example Request
POST /rest/payment
Authorization: Basic <base64(api_key:api_password)>
Content-Type: application/json
{
"payment_type": "cardecom",
"order_id": "12345678",
"amount": "15.90",
"currency": "EUR",
"postback_url": "https://your-postback.url.com",
"success_url": "https://your-success.url.com",
"error_url": "https://your-error.url.com",
"card_number": "4761070000000509",
"card_holder": "John Doe",
"card_cvv": "196",
"card_expiry_month": "12",
"card_expiry_year": "2026"
}

Implementation Flow

  1. Make a Payment API request with card data.
  2. Receive API response.
  3. If the response contains a client_action, handle it accordingly:
    • postForm: Build a form on your frontend and POST the fields from action_data to the provided url. This redirects the customer to the 3DS authentication page.
    • redirect: Redirect the customer to the url in action_data.
  4. After 3DS is completed, the customer is returned to your success_url or error_url.
  5. Receive asynchronous postback notification to postback_url with the final transaction status.

Payment API Response

Direct Response (with own MPI)

When threeds_authentication_value and threeds_directory_server_trans_id are provided in the request, the gateway uses the merchant's 3DS results and returns a direct response:

transaction_idString
ID of the created transaction
payment_typeString
Payment type of the transaction
status_codeInteger
Status code of the transaction
statusString
Status of the transaction
order_idString
Order ID of the transaction
messageString
Optional additional information about the transaction result
additional_transaction_dataString
Additional transaction data provided by you. This will be shown in the dashboard as well as when you query for transaction data. It will also be sent back to your postback_url as part of the postback data.
amountFloat
Amount of the transaction
included_feesString
Included fees for the transaction
error_codeInteger
Error code for the response
Example Response — Direct
{
"transaction_id": "938834bc-769f-44e7-ab25-da9aeaad5346",
"payment_type": "cardecom",
"status_code": 3,
"status": "completed",
"order_id": "12345678",
"message": null,
"additional_transaction_data": "",
"amount": 15.90,
"included_fees": "0.00",
"error_code": 0
}

3DS Required Response (without own MPI)

When no 3DS authentication values are provided, the gateway triggers its own 3DS flow. The response will have status: "pending" and a client_action that the merchant must handle:

client_actionString
Indicates the required client-side action after a payment request. Possible values: postForm (build and submit a POST form using the data in action_data) or redirect (redirect to the url in action_data). When not returned, no client-side action is required.
action_dataObject
Present when client_action is specified. Contains: url (target URL of the action) and, in case of a postForm, fields (key/value pairs of the data to be posted).
In this case, the merchant must build a form on their frontend and POST the fields to the provided url in action_data. This will redirect the customer to the 3DS authentication page. Once 3DS is completed, the customer is returned to the merchant's success_url or error_url.
Example Response — 3DS Required
{
"transaction_id": "25634b4d-c3dd-4242-afe3-e7962c33138c",
"payment_type": "cardecom",
"status_code": 2,
"status": "pending",
"order_id": "12345678",
"message": null,
"additional_transaction_data": null,
"amount": 15.90,
"included_fees": "0.00",
"error_code": 0,
"client_action": "postForm",
"action_data": {
"url": "https://3ds-acs-url.example.com/v1/acs/challenge-initiate",
"fields": {
"creq": "eyJ0aHJlZURTU2VydmVyVHJ..."
}
}
}
tip

This example shows a minimal request. For the complete list of supported parameters (billing address, recurring payments, and more), see the Payment API Reference. For integration details on other payment methods, see Payment Methods.

5. Receive postback notifications

After a transaction is processed, the API will send asynchronous HTTP POST notifications (postbacks) to the postback_url you provided in the payment request. This is how your system stays informed about the final result of each transaction — even if the customer does not return to your website.

Payment Postback — Completed

transaction_idString
ID of the transaction
payment_typeString
status_codeInteger
Numeric status code
statusString
Text representation of the transaction status
order_idString
Your internal order or invoice reference
messageString
Optional additional information about the transaction result
remittance_infoString
Remittance information associated with the payment. Sent when a Capture becomes settled. Specific to Wero.
wallet_activity_referenceString
Wallet activity reference. Specific to Wero. Only included when available.
wallet_account_referenceString
Wallet account reference. Specific to Wero. Only included when available.
payer_locationString
Payer location. Specific to Wero. Only included when available.
additional_transaction_dataString
Additional payment information provided by you
amountFloat
Amount of the transaction including all taxes and shipping fees
included_feesString
Fees included in the amount
external_transaction_idString
A reference ID assigned by a payment processor or network. Not available for all payment methods.
checksumString
Checksum of parameters. Use your webhook key to verify message integrity.
Example Postback Completed
{
"transaction_id": "d1bf9fdf-7268-406f-9e08-8d5a9540ab97",
"payment_type": "wero",
"status_code": 3,
"status": "completed",
"order_id": "12345678",
"message": "CAPTURE SETTLED",
"remittance_info": "12345678 - Test Shop",
"wallet_activity_reference": "WARf47ac10b58cc",
"wallet_account_reference": "WAC50000aW12",
"payer_location": "DE",
"additional_transaction_data": "customer_id=123ABC, billing_info=12345678",
"amount": 15.90,
"included_fees": "0.00",
"external_transaction_id": "0I66TOoXap2bNLZ2m89tm1",
"checksum": "73a93b8a2d5260f592d98e386c4e5784ee551d1c"
}

Payment Postback — Declined

transaction_idString
ID of the transaction
payment_typeString
status_codeInteger
Numeric status code
statusString
Text representation of the transaction status
order_idString
Your internal order or invoice reference
messageString
Additional information about the transaction result
reason_codeString
Rejection reason code in ISO format (e.g. AC01)
wallet_activity_referenceString
Wallet activity reference. Specific to Wero. Only included when available.
wallet_account_referenceString
Wallet account reference. Specific to Wero. Only included when available.
payer_locationString
Payer location. Specific to Wero. Only included when available.
additional_transaction_dataString
Additional payment information provided by you
amountFloat
Amount of the transaction including all taxes and shipping fees
included_feesString
Fees included in the amount
checksumString
Checksum of parameters. Use your webhook key to verify message integrity.
Example Postback Declined
{
"transaction_id": "bfe9cff7-8cd9-4976-9236-21253c1f40c1",
"payment_type": "wero",
"status_code": 6,
"status": "declined",
"order_id": "123010",
"message": "CAPTURE REJECTED",
"reason_code": "AC01",
"wallet_activity_reference": "WARf47ac10b58cc",
"wallet_account_reference": "WAC50000aW12",
"payer_location": "DE",
"additional_transaction_data": "customer_id=123ABC, billing_info=12345678",
"amount": 10.00,
"included_fees": "0.00",
"checksum": "d56fe31a1a38e06337672ca781e4cb6f3b83fd11"
}

For retry policy and signature verification, see Postbacks.