With an integration that uses local communications, your POS app and the terminal communicate with each other over your local network:
- Your POS app makes an API request to the terminal, to initiate the payment on the device.
- The terminal routes the request to the Adyen payments platform for processing.
- Optional: you receive display notifications in your POS app, to inform store staff on the progress of the transaction and the result.
- You receive the result of the transaction synchronously.
To build a local integration, you need to:
- Configure your network.
- Optionally install an API library.
- Protect local communications. This is optional for test transactions, but required for live transactions.
- Build your payment flow.
- Learn how to handle network issues.
Step 1: Configure your network
To enable your POS app to connect directly to the terminal:
Add Adyen's domains to your firewall's allowlist.
Configure your firewall to allow outgoing HTTPS traffic from the IP addresses of your POS apps and terminals to:
Allowlisting should be based on the DNS name of these URLs. Your firewall should dynamically check for IP address updates, at least every 60 seconds.
Do not hard-code Adyen's IP addresses, because these can change over time. We do not share a list of our IP addresses publicly.
- Open the ports:
- tcp/443 to the internet.
- tcp/8443 on your LAN.
For more information, see Network and connectivity.
Step 2 (optional): Install an API library
On our GitHub, we provide server-side API libraries in several languages. Installing a GitHub library is not required, but can save you development time, because a library includes all Terminal API models so you can use these to create requests. Most libraries also send requests to Adyen using a built-in HTTP client, construct the correct TEST and LIVE endpoints, and help to protect local communications.
The following Adyen GitHub libraries are available for a local Terminal API integration:
- .NET - adyen-dotnet-api-library
- iOS - adyen-terminal-api-ios
- Java - adyen-java-api-library
- Node - adyen-node-api-library
These GitHub libraries work with Terminal API and are completely separate from the classic libraries, which are being deprecated.
Step 3: Protect local communications
While you are building a test integration, we don't enforce this step. This allows you to develop the functional and security aspects in parallel. However, you will not be able to process live transactions until you have secured the requests between your POS app and your terminal.
If your integration uses local communications, you need to protect your integration against man-in-the-middle attacks, eavesdropping, and tampering. The steps you need to take are:
- Install Adyen's root certificate.
- Set up a shared key.
- Add code to validate the terminal certificate against the root certificate and encrypt communications using the shared key.
Install Adyen's root certificate
The root certificate contains information about Adyen's public key, which is used to sign other certificates such as the certificate on the terminal. To verify the certificate on the terminal against the public key, you have to add Adyen's root certificate to a trust store that is available to your POS app.
The instructions differ depending on the operating system. Select one of the tabs below.
Download the Adyen public root certificates:
adyen-terminalfleet-test.pem. This is the test root certificate for validating the certificate on TEST terminals.
adyen-terminalfleet-live.pem. This is the live root certificate for validating the certificate on LIVE terminals.
If your system requires another format, such as .crt or .cer, you can use OpenSSL commands to convert the certificates. For example:
openssl x509 -outform der -in adyen-terminalfleet-test.pem -out adyen-terminalfleet-test.crt
Verify that the SHA-256 fingerprint (also called thumbprint) of the root certificates matches the following:
- TEST root certificate:
3A 33 C3 34 C3 0F 69 46 E9 75 4B 6B B1 67 2B 54 6F BA A9 66 FB 6A 4B 58 AA 4E 3A BE 80 A7 EC BE
LIVE root certificate:
06 D4 86 41 95 4B 95 7D 7A F5 F5 E4 5A 58 D8 61 DB 0D E3 CC ED BB 98 36 60 BB 01 6C E6 14 2D A1
To get the SHA-256 fingerprint, you can use the following OpenSSL command:
openssl x509 -in adyen-terminalfleet-test.pem -noout -sha256 -fingerprint
- TEST root certificate:
Install the Adyen root certificates in the trust store of your POS app, following your vendor's instructions.
You can add root certificates to the user or system trust store. At the user level, it is easier to import a certificate.
Set up a shared key
To prevent others from being able to read messages sent between your POS app and the payment terminal, you need to encrypt the communications. For that, you first need to create a key passphrase and share it with Adyen. Both your code (or the Adyen GitHub library you're using) and the terminal will apply a key derivation function to the passphrase, and use the resulting key material to encrypt communications.
You can create a shared key manually in your Customer Area or with an API call. For both options, you can set up the shared key at the company, merchant, store, or terminal level. If your use case does not specifically require it, we recommend setting up a shared key at the highest possible level. For more information, see Settings at different levels and Inheritance of settings.
Add code to protect local communications
Your integration must:
- Validate the terminal certificate: this confirms that your POS app is communicating directly with an Adyen-supplied payment terminal, and not an impostor.
- Encrypt communications: this prevents intruders from reading the messages transmitted between your POS app and the terminal.
There are two ways to get this done: use one of our GitHub libraries, or write your own code. For instructions, select one of the options below.
Use a GitHub library
Handle the protection of local communications through a library.
Do it yourself
Write your own code to handle the protection of local communications.
Step 4: Build your payment flow
Adyen-supplied payment terminals listen for Terminal API POST requests to
/nexo on port 8443. For example, if your terminal has the IP address 198.51.100.1 you make API requests to:
When you make a payment, the result is provided through a synchronous API response. To receive the synchronous response, your POS app needs to make HTTPS requests to the terminal using a time-out of more than 120 seconds. During this time the connection is kept alive and a synchronous response will follow.
When building your payment flow, also consider:
- How you want to handle the synchronous response, including how you provide a receipt to the shopper.
- Whether you want your POS app to show messages that keep your staff up to date with the progress of the transaction.
- Optionally installing a server-side API library.
Handling the synchronous response
The synchronous Terminal API response includes:
- The result of the payment.
- Adyen's unique transaction reference.
- Your unique transaction reference.
- Data that you can use to generate a receipt. You can either generate a printed receipt, display it on-screen, or email it to the shopper.
Showing display notifications in your POS app
During a transaction or tender, the payment terminal generates display notifications. You can show these in your POS app to keep your staff up-to-date on the progress of the tender. For example, whether the customer has selected Dynamic Currency Conversion, or finished entering their PIN.
To set this up, see Display notifications.
Step 5: Handle network issues
To make your integration more resilient in case of connection issues, your integration should automatically make a transaction status request when it does not receive a synchronous payment response from Adyen.
Payment requests time out after 120 seconds. If you do not receive a payment response (or you receive a response indicating a time-out) after 150 seconds, your integration should automatically make a transaction status request.
Showing the result of the transaction status request in your POS app reduces the risk that your store staff will unnecessarily try to cancel or refund the transaction, or make a duplicate transaction.
You can optionally request the status of a transaction before 120 seconds. For example, you may also want to let store staff manually request the status of a payment at any time from the POS app.