Overview
Surcharging lets you pass the cost of accepting a card on to the customer as a separate line added to the payment amount. Adyen supports surcharging for both online (API-only card) payments and in-person terminal payments.
This article covers the technical integration only. For which cards and regions can be surcharged, rate caps, disclosure and signage, and the 30-day acquirer notice, see Surcharging Guidelines for 2026.
Adyen does not enforce the rules. It applies whatever surcharge you configure or send, including on debit cards or above a cap. Your integration is the only safeguard.
Channel | How the surcharge is set | Where the customer sees it |
Online (API-only) | Your server calculates it after a | Your checkout page |
In-person (terminal) | Configuration-based rules in Adyen, or a dynamic amount you send in the Terminal API request | Adyen's on-terminal confirmation screen, or your own disclosure |
How it works
Every surcharged payment follows the same pattern: identify the card, decide whether it can be surcharged, show the customer the amount, then authorise the original amount plus the surcharge. What differs is who does the calculation.
Online payments
Your server does the calculation. This requires an API-only card integration (encrypted card data via the Custom Card Component); Drop-in and standard Components are not supported.
Collect the card number on your checkout page.
Call
/cardDetailsto get the brand, funding source (credit, debit, prepaid), whether it is a commercial card, and the issuing country.Apply your own rules to decide if a surcharge is allowed and calculate it.
Show the surcharge on your checkout page before the customer pays.
Call
/paymentswith the surcharge in asurchargeobject andamount.valueset to the original amount plus the surcharge.
In-person: configuration-based surcharge
The terminal does the calculation from rules you store in Adyen. Your payment request needs no extra fields.
Send a normal Terminal API payment request for the original amount.
The customer presents their card.
The terminal matches the card against your rules and calculates the surcharge.
The customer accepts or cancels on Adyen's confirmation screen (unless you have disabled it).
The payment response returns the surcharge in
TotalFeesAmount.
In-person: dynamic surcharge
You calculate the amount yourself, or with a third-party service, and pass it to the terminal. Use this when you want the same logic online and in store. Requires terminal software v1.118 or later.
Send a card acquisition request to read the card's brand, funding source, commercial flag and issuing country.
Calculate the surcharge from those details.
Send the payment request with
surchargeFeeinSaleToAcquirerData, referencing the card acquisition.The customer accepts or cancels on the confirmation screen.
The payment response returns the surcharge in
TotalFeesAmountand the total inAuthorizedAmount.
You can combine the two in-person methods: set configuration rules as the default and override them with a dynamic amount when needed. Surcharging and Dynamic Currency Conversion (DCC) cannot be applied to the same transaction.
Deciding which cards to surcharge
For online payments and dynamic in-person surcharge, you must decide whether each card can be surcharged and calculate the amount yourself, following the Surcharging Guidelines for 2026. Adyen applies whatever amount you send. Base the decision on these card attributes:
Attribute | Online ( | In-person (card acquisition |
Brand |
|
|
Product | n/a |
|
Funding source |
|
|
Commercial card |
|
|
Issuing country |
|
|
The amount you send in /payments must be the same amount the customer was shown at checkout.
Setup
Pick the section for your channel. All examples use Adyen's test endpoints; switch to your live endpoint prefix when you go live.
Online payments
Requirements: API-only integration with the Custom Card Component (encrypted card data), an API credential with the Checkout webservice role, and Standard webhooks.
Look up the card with
/cardDetails, passing theencryptedCardNumberfrom the Custom Card Component.POST https://checkout-test.adyen.com/v71/cardDetails
x-api-key: ADYEN_API_KEY
content-type: application/json
{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"encryptedCardNumber": "adyenjs_0_1_18$..."
}Use
fundingSource,isCardCommercial,issuingCountryCodeandbrands.typefrom the response to decide eligibility and calculate the amount.Send
/paymentswith the surcharge.amount.valuemust already include it. Amounts are in minor units, so this example is a USD 10.00 order plus a USD 1.00 surcharge.{
"amount": { "currency": "USD", "value": 1100 },
"surcharge": { "value": 100 },
"reference": "YOUR_ORDER_NUMBER",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"paymentMethod": { "type": "scheme", "encryptedCardNumber": "..." }
}Optional but recommended: in the Customer Area, go to Developers > Additional data, select Surcharge amount, and save. The surcharge then appears in the
/paymentsresponseadditionalDataand in AUTHORISATION webhooks.Test with Adyen's test card numbers before going live.
In-person: configuration-based surcharge
Requirements: Terminal API (terminals or Tap to Pay) or a standalone solution; an API credential with Management API Terminal settings read and read-and-write roles. Not supported on SFO1 terminals or NYC1 card readers.
Feature | Minimum terminal software |
Maximum surcharge per transaction | v1.108 |
Commercial vs consumer card rules | v1.112 |
Exclude tips from surcharge | v1.115 |
Surcharge MOTO and manual key entry | v1.117 |
Check your current setup with a GET to
/terminalSettingsat the company, merchant, store or terminal level.List each rule you need: brand, funding source, issuer country, currency, percentage and/or fixed amount, and any cap.
PATCH
/terminalSettingswith asurchargeobject. Rules run top to bottom and the first match wins, so put narrow rules (a specific country or commercial cards) above broad ones.PATCH https://management-test.adyen.com/v3/stores/{storeId}/terminalSettings
x-API-key: YOUR_API_KEY
{
"surcharge": {
"askConfirmation": true,
"excludeGratuityFromSurcharge": true,
"configurations": [
{
"brand": "visa",
"sources": ["Credit"],
"currencies": [{ "currencyCode": "USD", "percentage": "3" }]
},
{
"brand": "mc",
"sources": ["Credit"],
"currencies": [{ "currencyCode": "USD", "percentage": "3" }]
}
]
}
}This example surcharges Visa and Mastercard credit cards at the same 3% rate and leaves debit untouched, as US rules require. Each
currenciesentry needscurrencyCodeplus apercentage, anamount(minor units), or both;maxAmountsets a cap. Setcommercial: trueto surcharge only business cards, for example in the EEA.Send complete data, or the rules won't apply correctly.
Always send the full
configurationsarray with every rule you want active, not only the rule you are changing.Fill in every field that applies to each rule:
brand,sources,currencies, andcountryandcommercialwhere relevant. A field you leave out is treated as "any", so the rule matches more cards than intended. For example, a rule withoutsourcesalso surcharges debit and prepaid cards.After each PATCH, GET
/terminalSettingsat the same level and check thesurchargeobject matches what you sent.
For contactless and Tap to Pay, ask ValPay to enable single tap so customers don't tap twice after accepting the surcharge.
If you already surcharge MOTO or manual-entry payments in your own system, ask ValPay to opt you out for those, to avoid double surcharging.
In-person: dynamic surcharge
Requirements: Terminal API with terminal software v1.118 or later. Ask ValPay to enable single tap, and enable issuer country in API responses.
Set
askConfirmationtotruevia/terminalSettingsto show the confirmation screen.Send a card acquisition request and read
fundingSource,isCardCommercial,issuerCountryandpaymentMethodVariantfromAdditionalResponse.Calculate the surcharge, then send the payment request.
RequestedAmountis the original amount;surchargeFeeis in major units (6.00, not 600)."SaleData": {
"SaleTransactionID": { "TransactionID": "27908", "TimeStamp": "2026-01-05T15:59:49.294Z" },
"SaleToAcquirerData": "surchargeFee=6.00"
},
"PaymentTransaction": {
"AmountsReq": { "Currency": "USD", "RequestedAmount": 620.00 }
},
"PaymentData": {
"CardAcquisitionReference": { "TimeStamp": "...", "TransactionID": "..." }
}
Showing the surcharge in your integration
The disclosure rules themselves are in the guidelines article. These are the technical controls for meeting them.
Terminal confirmation screen. Adyen's terminal screen lets the customer accept the surcharge or cancel. It is controlled by askConfirmation in /terminalSettings. If you turn it off, or use Tap to Pay (where it does not appear), you must disclose the surcharge another way, for example in your POS app.
Online checkout. Show the surcharge as its own line on the payment step after the card number is entered, and update the total before the customer confirms.
Receipts. For in-person payments, the receipt data in the Terminal API response already includes the surcharge line on both merchant and customer copies. Print it unaltered rather than rebuilding the receipt. Online, add the surcharge as its own line in your order confirmation and email receipt, using the amount you sent in surcharge.value.
Captures, refunds and reporting
Treat the surcharge as part of the payment total from authorisation onward.
Captures and refunds (online): pass the full amount including the surcharge. A full refund returns the surcharge to the customer.
Adjustments: surcharges cannot be added to authorisation adjustments or overcaptures, and the captured surcharge can never exceed what the customer was shown at purchase.
Scheme reporting: Adyen reports the surcharge to the card schemes for you. This only works if the surcharge is sent correctly: in the
surchargeobject online, or calculated by the terminal in store. Do not bake it into the item price.Tracking the amount: enable surcharge in additional data (Customer Area > Developers > Additional data) to receive it in AUTHORISATION webhooks. In store, the payment response also carries it in
TotalFeesAmountandsurchargeAmount(minor units).Platforms: by default the surcharge is booked to the liable balance account, not the sub-merchant's.
Troubleshooting and FAQ
Problem | Likely cause and fix |
No surcharge applied on the terminal | No rule matches the card. Check brand, sources, country and currency in |
Debit or prepaid card was surcharged | Your rule omits |
Surcharge charged twice on MOTO or keyed payments | Terminal v1.117+ now surcharges these too. Remove your own logic or ask ValPay to opt you out. |
Commercial-card rule ignored | Requires terminal v1.112+, and is not checked on mobile devices or when the terminal is offline. |
Tip was surcharged | Set |
Customer had to tap twice | Ask ValPay to enable single tap. |
|
|
Dynamic surcharge 100x too high |
|
Issuer country missing in card acquisition | Enable receiving issuer country/region in API responses. |
Can I use surcharging with Drop-in or standard Components? Not online. Online surcharging requires an API-only integration with the Custom Card Component.
Can I combine surcharging with DCC? No. A transaction can have one or the other.
Does Adyen check that my surcharge is legal? No. It applies the amounts you configure or send, even if they break scheme or local rules. Fines are passed on to you.
I need to turn surcharging off (for example in Australia). What do I change? Remove the surcharge configurations at every level they were set (company, merchant, store, terminal), then GET /terminalSettings at each level to confirm nothing is inherited. Online, return 0 from your calculation and stop sending the surcharge object.
Who do I contact? Your ValPay contact, for single tap, the MOTO opt-out, or any other surcharging setup questions.
