We do not recommend using Terminal API in combination with a classic POS library. In addition, you cannot use Terminal API with older eVo terminal models. Refer to the overview of terminals that support Terminal API.
Our Terminal API is based on the nexo Retailer Protocol.
See our official Terminal API reference.
The Adyen Terminal API lets you make payments, issue refunds, collect shopper information, and perform other shopper-terminal interactions using a payment terminal supplied by Adyen.
Before you make any point-of-sale payments, it is important to understand how Terminal API works and how requests and responses are structured.
Enable Terminal API
Before you can use Terminal API in your test environment, you need to enable it:
- Log in to your test Customer Area.
- Go to In-person payments > Terminal settings and select Integrations.
- Select the option to Enable Terminal API.
- Select Save.
When you switch to your live environment, follow the same steps in your live Customer Area.
Use the correct endpoint
The endpoints you need to use, and how you authenticate requests depends on how your integration connects to the Adyen payments platform:
Local communications
If your integration uses local communications, API requests are made from a POS app directly to a terminal's IP address. The terminal listens for POST requests to /nexo
on port 8443. For example, if your terminal has the IP address 198.51.100.1 you would make API requests to: https://198.51.100.1:8443/nexo
.
If your integration uses Android devices and the POS app is installed on the terminal itself, you can send POST requests to either localhost or 127.0.0.1 from that app.
Alternatively, if you assign a hostname to your terminal, you can make requests to the resolvable hostname of the terminal.
You should either use DHCP reservation for the terminal IP addresses, or manually configure static IP addresses. This helps to prevent connection issues when the terminal or your network reboots.
To protect local communications, you need to add Adyen's certificate to your POS app, and encrypt your messages.
Cloud communications
If your integration uses cloud communications, your POS app makes API requests to the Adyen payments platform. Our platform then forwards the request to the terminal.
The endpoint you need to use depends on two things:
- Whether your integration will receive transaction results synchronously or asynchronously.
- Whether you are making test transactions or live transactions.
Test endpoints
Use these endpoints for all test transactions.
Test endpoints - all locations | |
---|---|
Synchronous result: | https://terminal-api-test.adyen.com/sync |
Asynchronous result: | https://terminal-api-test.adyen.com/async |
Live endpoints
When you are ready to go live, you need to switch to a live transaction endpoint. For the best performance, use an endpoint that is geographically closest to the location of your store.
If you previously built an integration and are now repeating that in a new region, make sure to change the live endpoint to the one for the new region.
While the regional endpoints impact the communication between your POS app and the payment terminal, the communication between your payment terminal and our back-end also depends on the data center used.
To ensure that the communication between your payment terminal and our back-end is optimal, make sure to select the data center closest to your geographical location in your Customer Area under Developers > API URLs > Select a data center, for example AU for Australia.
Live endpoints - Australia | |
---|---|
Synchronous result: | https://terminal-api-live-au.adyen.com/sync |
Asynchronous result: | https://terminal-api-live-au.adyen.com/async |
Live endpoints - East Asia | |
---|---|
Synchronous result: | https://terminal-api-live-apse.adyen.com/sync |
Asynchronous result: | https://terminal-api-live-apse.adyen.com/async |
Live endpoints - Europe | |
---|---|
Synchronous result: | https://terminal-api-live.adyen.com/sync |
Asynchronous result: | https://terminal-api-live.adyen.com/async |
Live endpoints - US | |
---|---|
Synchronous result: | https://terminal-api-live-us.adyen.com/sync |
Asynchronous result: | https://terminal-api-live-us.adyen.com/async |
Get your API key
You need to include an Adyen API key in the request header for:
- Terminal API requests with cloud communications.
- Requests to other Adyen APIs. For example, for manual capture, authorization adjustment, and automating terminal management.
To get an API key for your test environment:
- Log in to your Customer Area.
- Go to Developers > API credentials, and select the API credential username for your integration, for example ws@Company.[YourCompanyAccount].
- Under Server settings > Authentication select the API key tab.
- Select Generate API key.
- Select the copy icon and store your API key securely in your system.
- Select Save changes.
When you switch to your live environment, follow the same steps in your live Customer Area.
Add the value of the API key to the request header using the key: x-API-key
API structure
Our Terminal API communicates with the terminal using JSON messages. All requests and responses have the following message header-body structure:
- Message header: identifies the type of transaction, the terminal being used, and unique transaction identifiers.
- Body: a request or response object, depending on the type of transaction. For example, when you make a payment request this is a
PaymentRequest
object, and when you receive a payment response this is aPaymentResponse
object.
The message header and body of Terminal API requests and responses are described in more detail below.
Requests
Each Terminal API request you make is contained in a SaletoPOIRequest
object. In this, you need to provide a:
MessageHeader
object.- Request body object corresponding to the type of transaction. For example, this is a
PaymentRequest
object when you are making a payment, or anInputRequest
object when you are requesting shopper input.
Request MessageHeader
In each request MessageHeader
, specify the following:
Name | Required | Type | Description |
---|---|---|---|
ProtocolVersion |
String | Version of Adyen's Terminal API. The current version is 3.0 |
|
MessageClass |
Enum | This is almost always Service, but it can also be Device or Event. We will specify which MessageClass is required throughout our documentation. |
|
MessageCategory |
Enum | The type of transaction. For example, Payment for a payment request. We will specify which MessageCategory is required throughout our documentation. |
|
MessageType |
Enum | This is always Request. | |
ServiceID |
String | Your unique ID for this request, consisting of 1-10 alphanumeric characters. Must be unique within the last 48 hours for the terminal (POIID ) being used. |
|
SaleID |
String | Your unique ID for the system where you send this request from. | |
POIID |
String | The unique ID of the terminal that you send this request to. Format: [device model]-[serial number]. For example, P400‑123456789. To find the POIID, see Get the terminal ID. |
The example below shows the header for making a payment.
Request body
The values you need to include in the request body depends on the type of transaction you are making. We provide examples and reference information for each transaction type throughout our point-of-sale documentation.
Responses
Each terminal API response you receive is contained in a SaleToPOIResponse
object, and includes a:
MessageHeader
object: echoes the MessageHeader values you provided in the API request.- Response body object: corresponds to the type of transaction request you made.
For example, when you make aPaymentRequest
you receive aPaymentResponse
object.
In a cloud integration that receives results asynchronously, you only receive an ok
response from the Terminal API. The MessageHeader
and response body are sent in an event notification instead.
Response MessageHeader
The MessageHeader
you receive in the response echoes the values you provided in the request. The only exception is the MessageType
, which is Response.
The following example shows the header you would receive in response to the example payment request provided above.
Response body
The values you receive in the response body depends on the type of transaction request you made. We provide examples and reference information for each transaction type throughout our point-of-sale documentation.
The response body will often include a unique transaction identifier, and data you can use to generate your receipts.
Transaction identifier
Every API request that creates a transaction or interacts with your money flow (such as a payment or refund) returns a unique transaction identifier in the POITransactionID.TransactionID
:
This identifier contains two values, separated by a dot:
- Tender reference: a unique value generated by the terminal for the transaction.
- PSP reference: a unique alphanumeric value generated by the Adyen payments platform for the transaction.
If you use Adyen for online payments or an omnichannel strategy, the PSP reference is the equivalent of the
pspReference
that you receive for transactions made online.
You should store each transaction identifier you receive, as you will need it to:
- Make a refund.
- Make a payment with acquired card details.
- Identify the transaction in your Customer Area, or in reports generated by Adyen.
Transaction identifiers for offline payments
If your integration uses local communications, your terminals will be able to make Offline EMV and store-and-forward transactions. When you experience a network issue, an Approved payment will only generate a transaction identifier with the tender reference:
Once the terminal is able to connect to the internet again, the Adyen payments platform will process the payment and generate an alphanumeric PSP reference. The PSP reference and tender reference can be found in your Customer Area, and in reports generated by Adyen.
Receipt data
When you make a transaction such as a payment, the payment result contains a PaymentReceipt
object. You can add the key-value pairs from this object to the receipt that you print, display, or email to your shopper.
For more information, see our receipts documentation.
Get the terminal ID
When you make a Terminal API request, you need to indicate which payment terminal you want to use. To do so, you populate the POIID
field in the MessageHeader
with the unique identifier of the payment terminal in the format [device model]-[serial number]. For example, P400‑123456789.
There are several ways to get the unique ID (POIID) of a payment terminal:
Get the serial number from the terminal
To construct the POIID of the payment terminal:
- Find the serial number of the payment terminal:
- On the back of the payment terminal.
- On the payment terminal screen under Settings > Device info.
- Take the device model, for example, P400, and combine it with the serial number.
- Add a dash between the device model and the serial number.
- Remove any dashes from the serial number.
Get the serial number from your Customer Area
In your Customer Area, go to In-person payments > Terminals and select the payment terminal.
Make an API call
If your integration uses cloud communications, you can get the terminal ID with an API call:
- Make a POST
/connectedTerminals
request, specifying your merchant account and optionally a store belonging to that merchant account. - In the response, get the
POIID
from theuniqueTerminalIds
array.
This array contains aPOIID
for every terminal that has a live cloud connection and belongs to the specified merchant account or store.
Use a diagnosis request
If your integration uses local communications, you can get the terminal ID using a diagnosis request.
-
Make a diagnosis request with a placeholder
MessageHeader.POIID
, for example xxxx-123456789.
The request will fail. -
In the
DiagnosisResponse
, find the correctPOIID
inside theMessageHeader
.
This is thePOIID
of the terminal that you sent the diagnosis request to.
Use an Android function
For Android payment terminals with your app installed on the terminal:
-
Get the
POIID
of the terminal by calling the following function: