{"title":"Terminal API","category":"default","creationDate":1560352500,"content":"<div class=\"additional-info-block output-inline\">\n<div class=\"additional-info-block__body\"><p>Our Terminal API is based on the <a href=\"https:\/\/www.nexo-standards.org\/standards\/nexo-retailer-protocol\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">nexo Retailer Protocol<\/a>. <br> See our official  <a href=\"https:\/\/docs.adyen.com\/api-explorer\/terminal-api\/latest\/overview\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Terminal API<\/a> reference.<\/p><\/div><\/div>\n\n<p>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.<\/p>\n<p>Before you make any point-of-sale payments, it is important to understand how Terminal API works and how requests and responses are structured.<\/p>\n<h2 id=\"enable-terminal-api\">Enable Terminal API<\/h2>\n<p>Before you can use Terminal API in your test environment, you need to enable it:<\/p>\n<ol>\n<li>Log in to your <a href=\"https:\/\/ca-test.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">test Customer Area<\/a>.<\/li>\n<li>Go to <strong>In-person payments<\/strong> &gt; <strong>Terminal settings<\/strong> and select <strong>Integrations<\/strong>.<\/li>\n<li>Select the option to <strong>Enable Terminal API<\/strong>.<\/li>\n<li>Select <strong>Save<\/strong>.<\/li>\n<\/ol>\n<p>When you switch to your live environment, follow the same steps in your <a href=\"https:\/\/ca-live.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">live Customer Area<\/a>.<\/p>\n<h2 id=\"endpoints\">Use the correct endpoint<\/h2>\n<p>The endpoints you need to use, and how you authenticate requests depends on how your integration connects to the Adyen payments platform:<\/p>\n<ul>\n<li><a href=\"#local\">Local communications<\/a>.<\/li>\n<li><a href=\"#cloud\">Cloud communications<\/a>.<\/li>\n<\/ul>\n<h3 id=\"local\">Local communications<\/h3>\n<p>If your integration uses <a href=\"\/point-of-sale\/design-your-integration\/choose-your-architecture\/local\">local communications<\/a>, API requests are made from a POS app directly to a terminal's IP address. The terminal listens for POST requests to <code>\/nexo<\/code> on port <strong>8443<\/strong>. For example, if your terminal has the IP address <strong>198.51.100.1<\/strong> you would make API requests to: <code>https:\/\/198.51.100.1:8443\/nexo<\/code>.<\/p>\n<div class=\"notices yellow\">\n<p>If your integration uses <strong>Android devices<\/strong> and the POS app is installed on the terminal itself, you can send POST requests to either <span translate=\"no\"><strong>localhost<\/strong><\/span> or <span translate=\"no\"><strong>127.0.0.1<\/strong><\/span> from that app.<\/p>\n<\/div>\n<p>Alternatively, if you assign a hostname to your terminal, you can make requests to the resolvable hostname of the terminal.<\/p>\n<p>You should either use <a href=\"\/point-of-sale\/design-your-integration\/network-and-connectivity\/network-configuration#configuring-the-terminal-IP-address\">DHCP reservation<\/a> for the terminal IP addresses, or manually configure static IP addresses. This helps to prevent connection issues when the terminal or your network reboots.<\/p>\n<p>To protect local communications, you need to <a href=\"\/point-of-sale\/design-your-integration\/choose-your-architecture\/local#install-root-cert\">add Adyen's certificate<\/a> to your POS app, and <a href=\"\/point-of-sale\/design-your-integration\/choose-your-architecture\/local#protect-communications\">encrypt your messages<\/a>.<\/p>\n<h3 id=\"cloud\">Cloud communications<\/h3>\n<p>If your integration uses <a href=\"\/point-of-sale\/design-your-integration\/choose-your-architecture\/cloud\">cloud communications<\/a>, your POS app makes API requests to the Adyen payments platform. Our platform then forwards the request to the terminal.<\/p>\n<p>The endpoint you need to use depends on two things:<\/p>\n<ul>\n<li>Whether your integration will receive transaction results synchronously or asynchronously.<\/li>\n<li>Whether you are making test transactions or live transactions.<\/li>\n<\/ul>\n<h4>Test endpoints<\/h4>\n<p>Use these endpoints for all test transactions.<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\"><\/th>\n<th style=\"text-align: left;\">Test endpoints - all locations<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">Synchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-test.adyen.com\/sync<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Asynchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-test.adyen.com\/async<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Live endpoints<\/h4>\n<p>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.<\/p>\n<p>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.<\/p>\n<p>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.<\/p>\n<p>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 <a href=\"https:\/\/ca-test.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Customer Area<\/a> under <strong>Developers<\/strong> &gt; <strong>API URLs<\/strong> &gt; <strong>Select a data center<\/strong>, for example <span translate=\"no\"><strong>AU<\/strong><\/span> for Australia.<\/p>\n<p>See the available regional live endpoints below or <a href=\"#find-regional-data-centers\">use this overview to identify<\/a> which region and URL insert applies to your terminal's location.<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\"><\/th>\n<th style=\"text-align: left;\">Live endpoints - Australia<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">Synchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live-au.adyen.com\/sync<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Asynchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live-au.adyen.com\/async<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\"><\/th>\n<th style=\"text-align: left;\">Live endpoints - East Asia<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">Synchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live-apse.adyen.com\/sync<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Asynchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live-apse.adyen.com\/async<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\"><\/th>\n<th style=\"text-align: left;\">Live endpoints  - Europe<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">Synchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live.adyen.com\/sync<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Asynchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live.adyen.com\/async<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\"><\/th>\n<th style=\"text-align: left;\">Live endpoints - US<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">Synchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live-us.adyen.com\/sync<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Asynchronous result:<\/td>\n<td style=\"text-align: left;\"><code>https:\/\/terminal-api-live-us.adyen.com\/async<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Find regional data centers<\/h2>\n<p>Find the country of your terminal's location in the table below to identify which regional data center endpoint to use.<\/p>\n<div class=\"accordion-shortcode adl-accordion adl-accordion--max-height-transition\" data-expand=\"true\" data-ignore=\"anchorjs-link\">\n    \n    <div class=\"adl-accordion__item\" style=\"\">\n        <div tabindex=\"0\" role=\"item\" aria-expanded=\"false\" class=\"adl-accordion__header\">\n            <i class=\"adl-accordion__toggle adl-icon-chevron-down\"><\/i>\n            <div class=\"adl-accordion__title-wrapper\" data-accordion=\"#regional-data-center-overview\">\n                                    <h3 class=\"adl-accordion__title\">Regional data center overview<\/h3>\n                            <\/div>\n        <\/div>\n        <div role=\"region\" class=\"adl-accordion__content\">\n            \n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Country of terminal location <\/th>\n<th style=\"text-align: left;\">Country code<\/th>\n<th style=\"text-align: left;\">Data center region<\/th>\n<th style=\"text-align: left;\">Data center prefix<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\"><strong>Europe\/Middle East (EU)<\/strong><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Austria<\/td>\n<td style=\"text-align: left;\"><code>AT<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Belgium<\/td>\n<td style=\"text-align: left;\"><code>BE<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Bulgaria<\/td>\n<td style=\"text-align: left;\"><code>BG<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Croatia<\/td>\n<td style=\"text-align: left;\"><code>HR<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Cyprus<\/td>\n<td style=\"text-align: left;\"><code>CY<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Czech Republic<\/td>\n<td style=\"text-align: left;\"><code>CZ<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Denmark<\/td>\n<td style=\"text-align: left;\"><code>DK<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Estonia<\/td>\n<td style=\"text-align: left;\"><code>EE<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Finland<\/td>\n<td style=\"text-align: left;\"><code>FI<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">France<\/td>\n<td style=\"text-align: left;\"><code>FR<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Germany<\/td>\n<td style=\"text-align: left;\"><code>DE<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Greece<\/td>\n<td style=\"text-align: left;\"><code>GR<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Hungary<\/td>\n<td style=\"text-align: left;\"><code>HU<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Iceland<\/td>\n<td style=\"text-align: left;\"><code>IS<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Ireland<\/td>\n<td style=\"text-align: left;\"><code>IE<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Italy<\/td>\n<td style=\"text-align: left;\"><code>IT<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Latvia<\/td>\n<td style=\"text-align: left;\"><code>LV<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Liechtenstein<\/td>\n<td style=\"text-align: left;\"><code>LI<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Lithuania<\/td>\n<td style=\"text-align: left;\"><code>LT<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Luxembourg<\/td>\n<td style=\"text-align: left;\"><code>LU<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Malta<\/td>\n<td style=\"text-align: left;\"><code>MT<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Netherlands<\/td>\n<td style=\"text-align: left;\"><code>NL<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Norway<\/td>\n<td style=\"text-align: left;\"><code>NO<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Poland<\/td>\n<td style=\"text-align: left;\"><code>PL<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Portugal<\/td>\n<td style=\"text-align: left;\"><code>PT<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Romania<\/td>\n<td style=\"text-align: left;\"><code>RO<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Slovakia<\/td>\n<td style=\"text-align: left;\"><code>SK<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Slovenia<\/td>\n<td style=\"text-align: left;\"><code>SI<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Spain<\/td>\n<td style=\"text-align: left;\"><code>ES<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Sweden<\/td>\n<td style=\"text-align: left;\"><code>SE<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Switzerland<\/td>\n<td style=\"text-align: left;\"><code>CH<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">United Arab Emirates<\/td>\n<td style=\"text-align: left;\"><code>AE<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">United Kingdom<\/td>\n<td style=\"text-align: left;\"><code>GB<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Guernsey<\/td>\n<td style=\"text-align: left;\"><code>GG<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Isle of Man<\/td>\n<td style=\"text-align: left;\"><code>IM<\/code><\/td>\n<td style=\"text-align: left;\">EU<\/td>\n<td style=\"text-align: left;\"><code>live<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong>Americas (US)<\/strong><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">United States of America<\/td>\n<td style=\"text-align: left;\"><code>US<\/code><\/td>\n<td style=\"text-align: left;\">US<\/td>\n<td style=\"text-align: left;\"><code>live-us<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Canada<\/td>\n<td style=\"text-align: left;\"><code>CA<\/code><\/td>\n<td style=\"text-align: left;\">US<\/td>\n<td style=\"text-align: left;\"><code>live-us<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Mexico<\/td>\n<td style=\"text-align: left;\"><code>MX<\/code><\/td>\n<td style=\"text-align: left;\">US<\/td>\n<td style=\"text-align: left;\"><code>live-us<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Brazil<\/td>\n<td style=\"text-align: left;\"><code>BR<\/code><\/td>\n<td style=\"text-align: left;\">US<\/td>\n<td style=\"text-align: left;\"><code>live-us<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Puerto Rico<\/td>\n<td style=\"text-align: left;\"><code>PR<\/code><\/td>\n<td style=\"text-align: left;\">US<\/td>\n<td style=\"text-align: left;\"><code>live-us<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong>Australia (AU)<\/strong><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Australia<\/td>\n<td style=\"text-align: left;\"><code>AU<\/code><\/td>\n<td style=\"text-align: left;\">AU<\/td>\n<td style=\"text-align: left;\"><code>live-au<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">New Zealand<\/td>\n<td style=\"text-align: left;\"><code>NZ<\/code><\/td>\n<td style=\"text-align: left;\">AU<\/td>\n<td style=\"text-align: left;\"><code>live-au<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong>Asia Pacific (APSE)<\/strong><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<td style=\"text-align: left;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Hong Kong<\/td>\n<td style=\"text-align: left;\"><code>HK<\/code><\/td>\n<td style=\"text-align: left;\">APSE<\/td>\n<td style=\"text-align: left;\"><code>live-apse<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Japan<\/td>\n<td style=\"text-align: left;\"><code>JP<\/code><\/td>\n<td style=\"text-align: left;\">APSE<\/td>\n<td style=\"text-align: left;\"><code>live-apse<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Malaysia<\/td>\n<td style=\"text-align: left;\"><code>MY<\/code><\/td>\n<td style=\"text-align: left;\">APSE<\/td>\n<td style=\"text-align: left;\"><code>live-apse<\/code><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Singapore<\/td>\n<td style=\"text-align: left;\"><code>SG<\/code><\/td>\n<td style=\"text-align: left;\">APSE<\/td>\n<td style=\"text-align: left;\"><code>live-apse<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n        <\/div>\n    <\/div>\n<\/div>\n\n<h2 id=\"api-key\">Get your API key<\/h2>\n<p>You need to include an Adyen API key in the request header for:<\/p>\n<ul>\n<li>Terminal API requests when using <strong>cloud communications<\/strong>.<\/li>\n<li>Requests to other Adyen APIs. For example, for <a href=\"\/point-of-sale\/capturing-payments#manual-capture\">manual capture<\/a>, <a href=\"\/point-of-sale\/pre-authorisation#adjust-auth\">authorization adjustment<\/a>, and <a href=\"\/point-of-sale\/automating-terminal-management\">automating terminal management<\/a>.<\/li>\n<\/ul>\n<p>To get an API key for your test environment:<\/p>\n<ol>\n<li>\n<p>Log in to your <a href=\"https:\/\/ca-test.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Customer Area<\/a>.<\/p>\n<\/li>\n<li>\n<p>Go to <strong>Developers<\/strong> &gt; <strong>API credentials<\/strong> and select the <strong>Payments<\/strong> tab.<\/p>\n<\/li>\n<li>\n<p>If you do not have an Adyen API key yet, or if you want to create a new API key without affecting an existing Adyen API key that you already have, first create a \"credential\":<\/p>\n<ol>\n<li>Select <strong>Create new credential<\/strong>.<\/li>\n<li>In the dialog, on the <strong>Payments<\/strong> tab, select <strong>Web service user<\/strong> and enter a description for the API key.<\/li>\n<li>Save the generated <strong>Username<\/strong>, for example <strong>ws_123456@Company.[YourCompanyAccount]<\/strong>. You will need this later if you need to <a href=\"\/development-resources\/api-credentials\">manage API keys<\/a>.<\/li>\n<li>Select <strong>Create credential<\/strong>.<\/li>\n<\/ol>\n<div class=\"notices green\">\n<p>The <strong>Configure API credentials<\/strong> page appears.<\/p>\n<\/div>\n<\/li>\n<li>\n<p>Alternatively, if you want to replace your existing Adyen API key with a new one, select the API credential username for your integration, for example <strong>ws_123456@Company.[YourCompanyAccount]<\/strong>.<\/p>\n<div class=\"notices green\">\n<p>The <strong>Configure API credentials<\/strong> page appears.<\/p>\n<\/div>\n<\/li>\n<li>\n<p>On the <strong>Configure API credentials<\/strong> page, under <strong>Server settings<\/strong> &gt; <strong>Authentication<\/strong> select the <strong>API key<\/strong> tab.<\/p>\n<\/li>\n<li>\n<p>Select <strong>Generate API key<\/strong>.<\/p>\n<\/li>\n<li>\n<p>Select the copy icon <i class=\"adl-icon-copy\"><\/i> and store your API key securely in your system.<\/p>\n<\/li>\n<li>\n<p>Select <strong>Save changes<\/strong>.<\/p>\n<\/li>\n<\/ol>\n<p>When you switch to your live environment, follow the same steps in your <a href=\"https:\/\/ca-live.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">live Customer Area<\/a>.<\/p>\n<div class=\"notices yellow\">\n<p>Add the value of the API key to the request header using the key: <span translate=\"no\"><strong>x-API-key<\/strong><\/span><\/p>\n<\/div>\n<h2>API structure<\/h2>\n<p>Our Terminal API communicates with the terminal using JSON messages. All requests and responses have the following <strong>message&nbsp;header<\/strong>-<strong>body<\/strong> structure:<\/p>\n<ul>\n<li><strong>Message header<\/strong>: identifies the type of transaction, the terminal being used, and unique transaction identifiers.<\/li>\n<li><strong>Body<\/strong>: a request or response object, depending on the type of transaction. For example, when you make a payment request this is a <code>PaymentRequest<\/code> object, and when you receive a payment response this is a <code>PaymentResponse<\/code> object.<\/li>\n<\/ul>\n<p>The message header and body of Terminal API <a href=\"#requests\">requests<\/a> and <a href=\"#responses\">responses<\/a> are described in more detail below.<\/p>\n<h2 id=\"requests\">Requests<\/h2>\n<p>Each Terminal API request you make is contained in a <code>SaletoPOIRequest<\/code> object. In this, you need to provide a:<\/p>\n<ul>\n<li><a href=\"#request-message-header\"><code>MessageHeader<\/code> object<\/a>.<\/li>\n<li><a href=\"#request-body\">Request body object<\/a> corresponding to the type of transaction. For example,  this is a <code>PaymentRequest<\/code> object when you are making a payment, or an <code>InputRequest<\/code> object when you are requesting shopper input.<\/li>\n<\/ul>\n<h3 id=\"request-message-header\">Request MessageHeader<\/h3>\n<p>In each request <code>MessageHeader<\/code>, specify the following:<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Name<\/th>\n<th style=\"text-align: center;\">Required<\/th>\n<th style=\"text-align: left;\">Type<\/th>\n<th style=\"text-align: left;\">Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\"><code>ProtocolVersion<\/code><\/td>\n<td style=\"text-align: center;\"><img title=\"-white_check_mark-\" alt=\"-white_check_mark-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/white_check_mark.png\" \/><\/td>\n<td style=\"text-align: left;\">String<\/td>\n<td style=\"text-align: left;\"><p>Version of the Nexo protocol that Terminal API is based on.<\/p> <p>The current protocol version is <strong>3.0<\/strong><\/p><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><code>MessageClass<\/code><\/td>\n<td style=\"text-align: center;\"><img title=\"-white_check_mark-\" alt=\"-white_check_mark-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/white_check_mark.png\" \/><\/td>\n<td style=\"text-align: left;\">Enum<\/td>\n<td style=\"text-align: left;\">This is almost always <span translate=\"no\"><strong>Service<\/strong><\/span>, but it can also be <span translate=\"no\"><strong>Device<\/strong><\/span> or <span translate=\"no\"><strong>Event<\/strong><\/span>. We will specify which <code>MessageClass<\/code> is required throughout our documentation.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><code>MessageCategory<\/code><\/td>\n<td style=\"text-align: center;\"><img title=\"-white_check_mark-\" alt=\"-white_check_mark-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/white_check_mark.png\" \/><\/td>\n<td style=\"text-align: left;\">Enum<\/td>\n<td style=\"text-align: left;\">The type of transaction. For example, <code>Payment<\/code> for a payment request. We will specify which <code>MessageCategory<\/code> is required throughout our documentation.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><code>MessageType<\/code><\/td>\n<td style=\"text-align: center;\"><img title=\"-white_check_mark-\" alt=\"-white_check_mark-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/white_check_mark.png\" \/><\/td>\n<td style=\"text-align: left;\">Enum<\/td>\n<td style=\"text-align: left;\">This is always <span translate=\"no\"><strong>Request<\/strong><\/span>.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><code>ServiceID<\/code><\/td>\n<td style=\"text-align: center;\"><img title=\"-white_check_mark-\" alt=\"-white_check_mark-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/white_check_mark.png\" \/><\/td>\n<td style=\"text-align: left;\">String<\/td>\n<td style=\"text-align: left;\">Your unique ID for this request, consisting of 1-10 alphanumeric characters. Must be unique within the last 48 hours for the terminal (<code>POIID<\/code>) being used.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><code>SaleID<\/code><\/td>\n<td style=\"text-align: center;\"><img title=\"-white_check_mark-\" alt=\"-white_check_mark-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/white_check_mark.png\" \/><\/td>\n<td style=\"text-align: left;\">String<\/td>\n<td style=\"text-align: left;\">Your unique ID for the system where you send this request from.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><code>POIID<\/code><\/td>\n<td style=\"text-align: center;\"><img title=\"-white_check_mark-\" alt=\"-white_check_mark-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/white_check_mark.png\" \/><\/td>\n<td style=\"text-align: left;\">String<\/td>\n<td style=\"text-align: left;\"><p>The unique ID of the terminal that you send this request to. Format: <em>[device model]-[serial number]<\/em>. For example, <strong>P400&#8209;123456789<\/strong>.<\/p><p>To find the POIID, see <a href=\"#get-the-terminal-id\">Get the terminal ID<\/a>.<\/p><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The example below shows the header for making a payment.<\/p>\n<div data-component-wrapper=\"code-sample\">\n    <code-sample :title=\"'Request MessageHeader'\" :id=\"''\" :code-data='[{\"language\":\"JSON\",\"tabTitle\":\"\",\"content\":\"{\\n  \\\"SaleToPOIRequest\\\":{\\n    \\\"MessageHeader\\\":{\\n      \\\"ProtocolVersion\\\":\\\"3.0\\\",\\n      \\\"MessageClass\\\":\\\"Service\\\",\\n      \\\"MessageCategory\\\":\\\"Payment\\\",\\n      \\\"MessageType\\\":\\\"Request\\\",\\n      \\\"SaleID\\\":\\\"POSSystemID12345\\\",\\n      \\\"ServiceID\\\":\\\"0207111104\\\",\\n      \\\"POIID\\\":\\\"V400m-324688179\\\"\\n    },\\n    \\\"PaymentRequest\\\":{...}\\n  }\\n}\"}]' :enable-copy-link-to-code-block=\"true\" :code-sample-card-size=\"'fullsize'\"><\/code-sample>\n<\/div>\n<h3 id=\"request-body\">Request body<\/h3>\n<p>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.<\/p>\n<h2 id=\"responses\">Responses<\/h2>\n<p>Each terminal API response you receive is contained in a <code>SaleToPOIResponse<\/code> object, and includes a:<\/p>\n<ul>\n<li><a href=\"#response-message-header\"><code>MessageHeader<\/code> object<\/a>: echoes the <strong>MessageHeader<\/strong> values you provided in the <a href=\"#request-message-header\">API request<\/a>.<\/li>\n<li><a href=\"#response-body\">Response body object<\/a>: corresponds to the type of transaction request you made.<br \/>\nFor example, when you make a <code>PaymentRequest<\/code> you receive a <code>PaymentResponse<\/code> object.<\/li>\n<\/ul>\n<div class=\"notices yellow\">\n<p>In a cloud integration that receives results asynchronously, you only receive an <code>ok<\/code> response from the Terminal API. The <code>MessageHeader<\/code> and response body are sent in an <a href=\"\/point-of-sale\/design-your-integration\/notifications\/event-notifications\">event notification<\/a> instead.<\/p>\n<\/div>\n<h3 id=\"response-message-header\">Response MessageHeader<\/h3>\n<p>The <code>MessageHeader<\/code> you receive in the response echoes the values you provided in the request. The only exception is the <code>MessageType<\/code>, which is <span translate=\"no\"><strong>Response<\/strong><\/span>.<\/p>\n<p>The following example shows the header you would receive in response to the <a href=\"#request-message-header\">example payment request provided above<\/a>.<\/p>\n<div data-component-wrapper=\"code-sample\">\n    <code-sample :title=\"'Response MessageHeader'\" :id=\"''\" :code-data='[{\"language\":\"JSON\",\"tabTitle\":\"\",\"content\":\"{\\n  \\\"SaleToPOIResponse\\\":{\\n    \\\"MessageHeader\\\":{\\n      \\\"ProtocolVersion\\\":\\\"3.0\\\",\\n      \\\"MessageClass\\\":\\\"Service\\\",\\n      \\\"MessageCategory\\\":\\\"Payment\\\",\\n      \\\"MessageType\\\":\\\"Response\\\",\\n      \\\"SaleID\\\":\\\"POSSystemID12345\\\",\\n      \\\"ServiceID\\\":\\\"0207111104\\\",\\n      \\\"POIID\\\":\\\"V400m-324688179\\\"\\n    },\\n    \\\"PaymentResponse\\\":{...}\\n  }\\n}\"}]' :enable-copy-link-to-code-block=\"true\" :code-sample-card-size=\"'fullsize'\"><\/code-sample>\n<\/div>\n<h3 id=\"response-body\">Response body<\/h3>\n<p>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.<\/p>\n<p>The response body will often include a unique <a href=\"#transaction-identifier\">transaction identifier<\/a>, and data you can use to <a href=\"#receipt-data\">generate your receipts<\/a>.<\/p>\n<h4 id=\"transaction-identifier\">Transaction identifier<\/h4>\n<p>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 <code>POITransactionID.TransactionID<\/code>:<\/p>\n<p><img alt=\"Transaction identifier\" src=\"\/user\/pages\/docs\/03.point-of-sale\/04.design-your-integration\/08.terminal-api\/ReferenceForOnline.svg?decoding=auto&amp;fetchpriority=auto\" \/><\/p>\n<p>This identifier contains two values, separated by a dot:<\/p>\n<ul>\n<li><strong>Tender reference<\/strong>: a unique value generated by the terminal for the transaction.<\/li>\n<li><strong>PSP reference<\/strong>: a unique alphanumeric value generated by the Adyen payments platform for the transaction.\n<div class=\"notices blue\">\n<p>If you use Adyen for <a href=\"\/online-payments\">online payments<\/a> or an omnichannel strategy, the <strong>PSP reference<\/strong> is the equivalent of the <code>pspReference<\/code> that you receive for transactions made online.<\/p>\n<\/div><\/li>\n<\/ul>\n<p>You should store each transaction identifier you receive, as you will need it to:<\/p>\n<ul>\n<li>Make a refund.<\/li>\n<li>Make a payment with acquired card details.<\/li>\n<li>Identify the transaction in your <a href=\"https:\/\/ca-test.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Customer Area<\/a>, or in <a href=\"\/reporting\">reports<\/a> generated by Adyen.<\/li>\n<\/ul>\n<h4>Transaction identifiers for offline payments<\/h4>\n<p>If your integration uses <a href=\"\/point-of-sale\/design-your-integration\/choose-your-architecture\/local\">local communications<\/a>, 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:<\/p>\n<p><img alt=\"Transaction identifier for offline payments\" src=\"\/user\/pages\/docs\/03.point-of-sale\/04.design-your-integration\/08.terminal-api\/ReferenceForOffline.svg?decoding=auto&amp;fetchpriority=auto\" \/><\/p>\n<p>When 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 <a href=\"https:\/\/ca-test.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Customer Area<\/a>, and in <a href=\"\/reporting\">reports<\/a> generated by Adyen.<\/p>\n<h4 id=\"receipt-data\">Receipt data<\/h4>\n<p>When you make a transaction such as a payment, the payment result contains a <code>PaymentReceipt<\/code> object. You can add the key-value pairs from this object to the receipt that you print, display, or email to your shopper.<\/p>\n<p>For more information, see our <a href=\"\/point-of-sale\/basic-tapi-integration\/generate-receipts\">receipts documentation<\/a>.<\/p>\n<h2>Get the terminal ID<\/h2>\n<p>When you make a Terminal API request, you need to indicate which payment terminal you want to use. To do so, you populate the <code>POIID<\/code> field in the <code>MessageHeader<\/code> with the unique identifier of the payment terminal in the format <em>[device model]-[serial number]<\/em>. For example, <strong>P400&#8209;123456789<\/strong>.<\/p>\n<p>There are several ways to get the unique ID (POIID) of a payment terminal:<\/p>\n<h3>Get the serial number from the terminal<\/h3>\n<p>To construct the POIID of the payment terminal:<\/p>\n<ol>\n<li>Find the serial number of the payment terminal:\n<ul>\n<li>On the back of the payment terminal.<\/li>\n<li>On the payment terminal screen under <strong>Settings<\/strong> &gt; <strong>Device info<\/strong>.<\/li>\n<\/ul><\/li>\n<li>Take the device model, for example, <strong>P400<\/strong>, and combine it with the serial number.<\/li>\n<li>Add a dash between the device model and the serial number.<\/li>\n<li>Remove any dashes from the serial number.<\/li>\n<\/ol>\n<h3>Get the serial number from your Customer Area<\/h3>\n<p>In your <a href=\"https:\/\/ca-test.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Customer Area<\/a>: <\/p>\n<ol>\n<li>Go to <strong>In-person payments<\/strong> &gt; <strong>Payment devices<\/strong>, and select the <strong>Terminals<\/strong> tab.  <\/li>\n<li>Select the payment terminal.<\/li>\n<\/ol>\n<h3 id=\"connected-terminals\">Make an API call<\/h3>\n<p>If your integration uses <a href=\"\/point-of-sale\/design-your-integration\/choose-your-architecture\/cloud\">cloud communications<\/a>, you can get the terminal ID with an API call:<\/p>\n<ol>\n<li>Make a POST <a href=\"\/point-of-sale\/diagnostics\/check-cloud-connection\/#use-an-api-call\">\n  <code>\/connectedTerminals<\/code>\n<\/a> request, specifying your merchant account and optionally a store belonging to that merchant account.<\/li>\n<li>In the response, get the <code>POIID<\/code> from the <code>uniqueTerminalIds<\/code> array.<br \/>\nThis array contains a <code>POIID<\/code> for every terminal that has a live cloud connection and belongs to the specified merchant account or store.<\/li>\n<\/ol>\n<h3 id=\"diagnosis\">Use a diagnosis request<\/h3>\n<p>If your integration uses <a href=\"\/point-of-sale\/design-your-integration\/choose-your-architecture\/local\">local communications<\/a>, you can get the terminal ID using a diagnosis request.<\/p>\n<ol>\n<li>\n<p>Make a <a href=\"\/point-of-sale\/diagnostics\/request-diagnosis\">diagnosis request<\/a> with a placeholder <code>MessageHeader.POIID<\/code>, for example <strong>xxxx-123456789<\/strong>.<br \/>\nThe request will fail.<\/p>\n<\/li>\n<li>\n<p>In the <code>DiagnosisResponse<\/code>, find the correct <code>POIID<\/code> inside the <code>MessageHeader<\/code>.<br \/>\nThis is the <code>POIID<\/code> of the terminal that you sent the diagnosis request to.<\/p>\n<\/li>\n<\/ol>\n<h3 id=\"android-function\">Use an Android function<\/h3>\n<p>For Android payment terminals with your app installed on the terminal:<\/p>\n<ul>\n<li>\n<p>Get the <code>POIID<\/code> of the terminal by calling the following function:<\/p>\n<div data-component-wrapper=\"code-sample\">\n<code-sample :title=\"'Get the terminal ID'\" :id=\"''\" :code-data='[{\"language\":\"raw\",\"tabTitle\":\"\",\"content\":\"Settings.Global.getString(context.contentResolver, Settings.Global.DEVICE_NAME)\"}]' :enable-copy-link-to-code-block=\"true\" :code-sample-card-size=\"'fullsize'\"><\/code-sample>\n<\/div>\n<\/li>\n<\/ul>","url":"https:\/\/docs.adyen.com\/point-of-sale\/design-your-integration\/terminal-api","articleFields":{"description":"Learn about our Terminal API, including the endpoints and structure.","parameters":{"integration_type":"IPP"},"next_steps":[{"title":"Payment flow","description":"Implement the Terminal API requests needed in a basic integration.","url":"\/point-of-sale\/basic-tapi-integration","required":false},{"title":"Handle responses","description":"Resolve Terminal API errors and handle declined payments.","url":"\/point-of-sale\/error-scenarios","required":false},{"title":"Terminal API reference","description":"View our implementation of the nexo standard.","url":"https:\/\/docs.adyen.com\/api-explorer\/terminal-api\/1\/overview","required":false}],"last_edit_on":"11-07-2023 11:17","feedback_component":true,"filters_component":false},"algolia":{"url":"https:\/\/docs.adyen.com\/point-of-sale\/design-your-integration\/terminal-api","title":"Terminal API","content":"\nOur Terminal API is based on the nexo Retailer Protocol.  See our official  Terminal API reference.\n\nThe 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.\nBefore you make any point-of-sale payments, it is important to understand how Terminal API works and how requests and responses are structured.\nEnable Terminal API\nBefore you can use Terminal API in your test environment, you need to enable it:\n\nLog in to your test Customer Area.\nGo to In-person payments &gt; Terminal settings and select Integrations.\nSelect the option to Enable Terminal API.\nSelect Save.\n\nWhen you switch to your live environment, follow the same steps in your live Customer Area.\nUse the correct endpoint\nThe endpoints you need to use, and how you authenticate requests depends on how your integration connects to the Adyen payments platform:\n\nLocal communications.\nCloud communications.\n\nLocal communications\nIf 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.\n\nIf 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.\n\nAlternatively, if you assign a hostname to your terminal, you can make requests to the resolvable hostname of the terminal.\nYou 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.\nTo protect local communications, you need to add Adyen's certificate to your POS app, and encrypt your messages.\nCloud communications\nIf 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.\nThe endpoint you need to use depends on two things:\n\nWhether your integration will receive transaction results synchronously or asynchronously.\nWhether you are making test transactions or live transactions.\n\nTest endpoints\nUse these endpoints for all test transactions.\n\n\n\n\nTest endpoints - all locations\n\n\n\n\nSynchronous result:\nhttps:\/\/terminal-api-test.adyen.com\/sync\n\n\nAsynchronous result:\nhttps:\/\/terminal-api-test.adyen.com\/async\n\n\n\nLive endpoints\nWhen 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.\nIf 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.\nWhile 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.\nTo 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 &gt; API URLs &gt; Select a data center, for example AU for Australia.\nSee the available regional live endpoints below or use this overview to identify which region and URL insert applies to your terminal's location.\n\n\n\n\nLive endpoints - Australia\n\n\n\n\nSynchronous result:\nhttps:\/\/terminal-api-live-au.adyen.com\/sync\n\n\nAsynchronous result:\nhttps:\/\/terminal-api-live-au.adyen.com\/async\n\n\n\n\n\n\n\nLive endpoints - East Asia\n\n\n\n\nSynchronous result:\nhttps:\/\/terminal-api-live-apse.adyen.com\/sync\n\n\nAsynchronous result:\nhttps:\/\/terminal-api-live-apse.adyen.com\/async\n\n\n\n\n\n\n\nLive endpoints  - Europe\n\n\n\n\nSynchronous result:\nhttps:\/\/terminal-api-live.adyen.com\/sync\n\n\nAsynchronous result:\nhttps:\/\/terminal-api-live.adyen.com\/async\n\n\n\n\n\n\n\nLive endpoints - US\n\n\n\n\nSynchronous result:\nhttps:\/\/terminal-api-live-us.adyen.com\/sync\n\n\nAsynchronous result:\nhttps:\/\/terminal-api-live-us.adyen.com\/async\n\n\n\nFind regional data centers\nFind the country of your terminal's location in the table below to identify which regional data center endpoint to use.\n\n    \n    \n        \n            \n            \n                                    Regional data center overview\n                            \n        \n        \n            \n\n\n\nCountry of terminal location \nCountry code\nData center region\nData center prefix\n\n\n\n\nEurope\/Middle East (EU)\n\n\n\n\n\nAustria\nAT\nEU\nlive\n\n\nBelgium\nBE\nEU\nlive\n\n\nBulgaria\nBG\nEU\nlive\n\n\nCroatia\nHR\nEU\nlive\n\n\nCyprus\nCY\nEU\nlive\n\n\nCzech Republic\nCZ\nEU\nlive\n\n\nDenmark\nDK\nEU\nlive\n\n\nEstonia\nEE\nEU\nlive\n\n\nFinland\nFI\nEU\nlive\n\n\nFrance\nFR\nEU\nlive\n\n\nGermany\nDE\nEU\nlive\n\n\nGreece\nGR\nEU\nlive\n\n\nHungary\nHU\nEU\nlive\n\n\nIceland\nIS\nEU\nlive\n\n\nIreland\nIE\nEU\nlive\n\n\nItaly\nIT\nEU\nlive\n\n\nLatvia\nLV\nEU\nlive\n\n\nLiechtenstein\nLI\nEU\nlive\n\n\nLithuania\nLT\nEU\nlive\n\n\nLuxembourg\nLU\nEU\nlive\n\n\nMalta\nMT\nEU\nlive\n\n\nNetherlands\nNL\nEU\nlive\n\n\nNorway\nNO\nEU\nlive\n\n\nPoland\nPL\nEU\nlive\n\n\nPortugal\nPT\nEU\nlive\n\n\nRomania\nRO\nEU\nlive\n\n\nSlovakia\nSK\nEU\nlive\n\n\nSlovenia\nSI\nEU\nlive\n\n\nSpain\nES\nEU\nlive\n\n\nSweden\nSE\nEU\nlive\n\n\nSwitzerland\nCH\nEU\nlive\n\n\nUnited Arab Emirates\nAE\nEU\nlive\n\n\nUnited Kingdom\nGB\nEU\nlive\n\n\nGuernsey\nGG\nEU\nlive\n\n\nIsle of Man\nIM\nEU\nlive\n\n\nAmericas (US)\n\n\n\n\n\nUnited States of America\nUS\nUS\nlive-us\n\n\nCanada\nCA\nUS\nlive-us\n\n\nMexico\nMX\nUS\nlive-us\n\n\nBrazil\nBR\nUS\nlive-us\n\n\nPuerto Rico\nPR\nUS\nlive-us\n\n\nAustralia (AU)\n\n\n\n\n\nAustralia\nAU\nAU\nlive-au\n\n\nNew Zealand\nNZ\nAU\nlive-au\n\n\nAsia Pacific (APSE)\n\n\n\n\n\nHong Kong\nHK\nAPSE\nlive-apse\n\n\nJapan\nJP\nAPSE\nlive-apse\n\n\nMalaysia\nMY\nAPSE\nlive-apse\n\n\nSingapore\nSG\nAPSE\nlive-apse\n\n\n\n\n        \n    \n\n\nGet your API key\nYou need to include an Adyen API key in the request header for:\n\nTerminal API requests when using cloud communications.\nRequests to other Adyen APIs. For example, for manual capture, authorization adjustment, and automating terminal management.\n\nTo get an API key for your test environment:\n\n\nLog in to your Customer Area.\n\n\nGo to Developers &gt; API credentials and select the Payments tab.\n\n\nIf you do not have an Adyen API key yet, or if you want to create a new API key without affecting an existing Adyen API key that you already have, first create a \"credential\":\n\nSelect Create new credential.\nIn the dialog, on the Payments tab, select Web service user and enter a description for the API key.\nSave the generated Username, for example ws_123456@Company.[YourCompanyAccount]. You will need this later if you need to manage API keys.\nSelect Create credential.\n\n\nThe Configure API credentials page appears.\n\n\n\nAlternatively, if you want to replace your existing Adyen API key with a new one, select the API credential username for your integration, for example ws_123456@Company.[YourCompanyAccount].\n\nThe Configure API credentials page appears.\n\n\n\nOn the Configure API credentials page, under Server settings &gt; Authentication select the API key tab.\n\n\nSelect Generate API key.\n\n\nSelect the copy icon  and store your API key securely in your system.\n\n\nSelect Save changes.\n\n\nWhen you switch to your live environment, follow the same steps in your live Customer Area.\n\nAdd the value of the API key to the request header using the key: x-API-key\n\nAPI structure\nOur Terminal API communicates with the terminal using JSON messages. All requests and responses have the following message&nbsp;header-body structure:\n\nMessage header: identifies the type of transaction, the terminal being used, and unique transaction identifiers.\nBody: 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 a PaymentResponse object.\n\nThe message header and body of Terminal API requests and responses are described in more detail below.\nRequests\nEach Terminal API request you make is contained in a SaletoPOIRequest object. In this, you need to provide a:\n\nMessageHeader object.\nRequest body object corresponding to the type of transaction. For example,  this is a PaymentRequest object when you are making a payment, or an InputRequest object when you are requesting shopper input.\n\nRequest MessageHeader\nIn each request MessageHeader, specify the following:\n\n\n\nName\nRequired\nType\nDescription\n\n\n\n\nProtocolVersion\n\nString\nVersion of the Nexo protocol that Terminal API is based on. The current protocol version is 3.0\n\n\nMessageClass\n\nEnum\nThis is almost always Service, but it can also be Device or Event. We will specify which MessageClass is required throughout our documentation.\n\n\nMessageCategory\n\nEnum\nThe type of transaction. For example, Payment for a payment request. We will specify which MessageCategory is required throughout our documentation.\n\n\nMessageType\n\nEnum\nThis is always Request.\n\n\nServiceID\n\nString\nYour 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.\n\n\nSaleID\n\nString\nYour unique ID for the system where you send this request from.\n\n\nPOIID\n\nString\nThe unique ID of the terminal that you send this request to. Format: [device model]-[serial number]. For example, P400&#8209;123456789.To find the POIID, see Get the terminal ID.\n\n\n\nThe example below shows the header for making a payment.\n\n    \n\nRequest body\nThe 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.\nResponses\nEach terminal API response you receive is contained in a SaleToPOIResponse object, and includes a:\n\nMessageHeader object: echoes the MessageHeader values you provided in the API request.\nResponse body object: corresponds to the type of transaction request you made.\nFor example, when you make a PaymentRequest you receive a PaymentResponse object.\n\n\nIn 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.\n\nResponse MessageHeader\nThe MessageHeader you receive in the response echoes the values you provided in the request. The only exception is the MessageType, which is Response.\nThe following example shows the header you would receive in response to the example payment request provided above.\n\n    \n\nResponse body\nThe 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.\nThe response body will often include a unique transaction identifier, and data you can use to generate your receipts.\nTransaction identifier\nEvery 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:\n\nThis identifier contains two values, separated by a dot:\n\nTender reference: a unique value generated by the terminal for the transaction.\nPSP reference: a unique alphanumeric value generated by the Adyen payments platform for the transaction.\n\nIf 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.\n\n\nYou should store each transaction identifier you receive, as you will need it to:\n\nMake a refund.\nMake a payment with acquired card details.\nIdentify the transaction in your Customer Area, or in reports generated by Adyen.\n\nTransaction identifiers for offline payments\nIf 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:\n\nWhen 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.\nReceipt data\nWhen 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.\nFor more information, see our receipts documentation.\nGet the terminal ID\nWhen 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&#8209;123456789.\nThere are several ways to get the unique ID (POIID) of a payment terminal:\nGet the serial number from the terminal\nTo construct the POIID of the payment terminal:\n\nFind the serial number of the payment terminal:\n\nOn the back of the payment terminal.\nOn the payment terminal screen under Settings &gt; Device info.\n\nTake the device model, for example, P400, and combine it with the serial number.\nAdd a dash between the device model and the serial number.\nRemove any dashes from the serial number.\n\nGet the serial number from your Customer Area\nIn your Customer Area: \n\nGo to In-person payments &gt; Payment devices, and select the Terminals tab.  \nSelect the payment terminal.\n\nMake an API call\nIf your integration uses cloud communications, you can get the terminal ID with an API call:\n\nMake a POST \n  \/connectedTerminals\n request, specifying your merchant account and optionally a store belonging to that merchant account.\nIn the response, get the POIID from the uniqueTerminalIds array.\nThis array contains a POIID for every terminal that has a live cloud connection and belongs to the specified merchant account or store.\n\nUse a diagnosis request\nIf your integration uses local communications, you can get the terminal ID using a diagnosis request.\n\n\nMake a diagnosis request with a placeholder MessageHeader.POIID, for example xxxx-123456789.\nThe request will fail.\n\n\nIn the DiagnosisResponse, find the correct POIID inside the MessageHeader.\nThis is the POIID of the terminal that you sent the diagnosis request to.\n\n\nUse an Android function\nFor Android payment terminals with your app installed on the terminal:\n\n\nGet the POIID of the terminal by calling the following function:\n\n\n\n\n","type":"page","locale":"en","boost":17,"hierarchy":{"lvl0":"Home","lvl1":"In-person payments","lvl2":"Design your integration","lvl3":"Terminal API"},"hierarchy_url":{"lvl0":"https:\/\/docs.adyen.com\/","lvl1":"https:\/\/docs.adyen.com\/point-of-sale","lvl2":"https:\/\/docs.adyen.com\/point-of-sale\/design-your-integration","lvl3":"\/point-of-sale\/design-your-integration\/terminal-api"},"levels":4,"category":"In-person payments","category_color":"green","tags":["Terminal"]},"articleFiles":{"ReferenceForOnline.svg":"<img alt=\"\" src=\"https:\/\/docs.adyen.com\/user\/pages\/docs\/03.point-of-sale\/04.design-your-integration\/08.terminal-api\/ReferenceForOnline.svg?decoding=auto&amp;fetchpriority=auto\" \/>","ReferenceForOffline.svg":"<img alt=\"\" src=\"https:\/\/docs.adyen.com\/user\/pages\/docs\/03.point-of-sale\/04.design-your-integration\/08.terminal-api\/ReferenceForOffline.svg?decoding=auto&amp;fetchpriority=auto\" \/>"}}
