{"title":"Card reader solution for iOS","category":"default","creationDate":1731408720,"content":"<p>With our card reader solution you can accept mobile in-person payments using a card reader as the payment interface, and process these payments on the plataforma de pagamentos da Adyen.<\/p>\n<p>The card reader is connected with an iOS mobile device through Bluetooth, or through USB using a dock. On the iOS mobile device, payment requests are initiated from a POS app. On the card reader, the customer can tap, insert, or swipe their card, or use a digital wallet like Apple Pay.<\/p>\n<h2>Requirements<\/h2>\n<p>Before you begin, take into account the following requirements, limitations, and preparations.<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Requirement<\/th>\n<th style=\"text-align: left;\">Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\"><strong>Integration type<\/strong><\/td>\n<td style=\"text-align: left;\">Your POS app must be integrated with <a href=\"\/pt\/point-of-sale\/design-your-integration\/terminal-api\/\">Terminal API<\/a>.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong><a href=\"\/pt\/development-resources\/api-credentials\/\">API credentials<\/a><\/strong><\/td>\n<td style=\"text-align: left;\">You need the following API credentials: <ul><li markdown=\"1\">To get the SDK, you must have an API credential with a basic authentication password and the <strong>Allow SDK download for POS developers<\/strong> role.<\/li> <li markdown=\"1\">To establish a communication session, you must have an API credential with an API key, a client key, and the <strong>Checkout webservice<\/strong> role.<\/li><\/ul><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong><a href=\"\/pt\/development-resources\/webhooks\">Webhooks<\/a><\/strong><\/td>\n<td style=\"text-align: left;\">To learn the outcome of refunds, set up Standard webhooks (if this hasn't been done already).<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong>Hardware<\/strong><\/td>\n<td style=\"text-align: left;\">You need the following hardware: <ul><li markdown=\"1\">An iOS mobile device. See <a href=\"\/pt\/point-of-sale\/mobile-ios\/requirements\">iOS system requirements<\/a> for the full hardware and software requirements.<\/li><li markdown=\"1\">A test <a href=\"\/pt\/point-of-sale\/user-manuals\/nyc1\/\">NYC1 card reader<\/a> and optionally an <a href=\"\/pt\/point-of-sale\/user-manuals\/nyc1-with-dock\/\">NYC1 dock<\/a>. For PIN transactions your card reader needs to be an <a href=\"\/pt\/point-of-sale\/mobile-ios\/understand#pin-transactions\">NYC1<\/a> model.<\/li><\/ul><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong>Limitations<\/strong><\/td>\n<td style=\"text-align: left;\">Check the countries\/regions, payment methods, and functionality that we <a href=\"\/pt\/point-of-sale\/ipp-mobile\">support<\/a> for card reader on iPhone.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><strong>Setup steps<\/strong><\/td>\n<td style=\"text-align: left;\">Before you begin: <ul><li markdown=\"1\"><a href=\"\/pt\/point-of-sale\/managing-terminals\/order-terminals#sales-order-steps\">Order<\/a> a test NYC1 card reader and a test card, and <a href=\"\/pt\/point-of-sale\/managing-terminals\/assign-terminals\">assign<\/a> the reader to your store.<li markdown=\"1\">If you want to disable PIN support for NYC1 card readers in the US from iOS Mobile SDK version <strong>3.12.0<\/strong> or later, contact our <a href=\"https:\/\/ca-test.adyen.com\/ca\/ca\/contactUs\/support.shtml?form=other\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Support Team<\/a> and ask them to disable PIN support on the company, merchant, or store level.<\/li><\/li><\/ul><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>How it works<\/h2>\n<div class=\"additional-info-block output-inline\">\n<div class=\"additional-info-block__body\"><p><strong>Tutorial and app<\/strong><br \/>\nHit the ground running with our <a href=\"https:\/\/adyen.github.io\/adyen-pos-mobile-ios-artifacts\/2.0.1\/tutorials\/meet-adyenpos\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">integration tutorial<\/a> and <a href=\"https:\/\/github.com\/Adyen\/adyen-pos-mobile-ios\/tree\/main\/POSSampleApp\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">iOS sample app<\/a>.<\/p><\/div><\/div>\n\n<p>To build a card reader solution:<\/p>\n<ol>\n<li>Add the iOS Mobile SDK to your project, using basic authentication.\n<div class=\"notices green\">\n<p>Note that for <a href=\"#objective-c\">compatibility with Objective C<\/a>, you need to prefix the public symbols with <code>ADY<\/code>.<\/p>\n<\/div><\/li>\n<li>Implement a server-to-server API request to establish a secure communication session.<\/li>\n<li>In your POS app, enable the transaction functionality of the SDK.<\/li>\n<li>From your POS app, call the warm-up function to speed up initiating transactions.<\/li>\n<li>In your POS app, add permissions for pairing the mobile device with the card reader.<\/li>\n<li>Get an entitlement from Apple to suppress Apple Pay in your iOS POS app when your app is in the foreground. Configure your Xcode project accordingly.<\/li>\n<li>Optionally, you can configure the Mobile SDK to avoid reconnection delays between the card reader and the mobile device.<\/li>\n<li>You enable the device management screens built into the Mobile SDK or build a custom UI for device management.<\/li>\n<li>\n<p>In your POS app, implement handling payments using the SDK.<br \/>\nThis creates the following flow:<\/p>\n<ol>\n<li>Your iOS POS app creates a Terminal API payment request, or receives a Terminal API payment request from your backend.<\/li>\n<li>The POS app passes the payment request to the iOS Mobile SDK.<\/li>\n<li>The SDK passes the request to the Tap to Pay on iPhone component.<\/li>\n<li>When the customer completes the payment by tapping their card or mobile device on the iPhone, the SDK passes the Terminal API payment response to the POS app.<\/li>\n<\/ol>\n<!-- list separator -->\n<\/li>\n<li>In your POS app, implement handling refunds and diagnosing the state of the SDK.<\/li>\n<li>If the same device will be used at multiple locations, implement clearing the communication session.<\/li>\n<\/ol>\n<h2 id=\"add-sdk\">1. Add the SDK to your project<\/h2>\n<p>You can add the iOS Mobile SDK to your POS app using a Swift Package Manager remote package. To get access you need to have a basic authentication credential. You can share the basic authentication password with anybody in your team who needs to get the SDK or create multiple passwords for internal use.<\/p>\n<div class=\"notices red\">\n<p>Do not share this password in any publicly accessible code or area where unauthorized users can find it.<\/p>\n<\/div>\n<p>To add the iOS Mobile SDK to your project:<\/p>\n<ol>\n<li>\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> create a basic authentication credential with a password:<\/p>\n<ol>\n<li>Go to <strong>Developers<\/strong> &gt; <strong>API credentials<\/strong>, and select <strong>Create new credential<\/strong>.<\/li>\n<li>Under <strong>Payments<\/strong> &gt; <strong>Credential type<\/strong> select <strong>Web service user<\/strong> and then select <strong>Create credential<\/strong>.<\/li>\n<li>Under <strong>Server settings<\/strong> &gt; <strong>Authentication<\/strong> select the <strong>Basic auth<\/strong> tab and then select <strong>Generate password<\/strong>.<\/li>\n<li>Select the copy icon <i class=\"adl-icon-copy\"><\/i> and save your basic authentication password in a secure location.<\/li>\n<li>Go to <strong>Permissions<\/strong> &gt; <strong>Roles<\/strong> &gt; <strong>POS<\/strong>, select <strong>Allow SDK download for POS developers<\/strong>, and deselect any other permissions and roles.\n<div class=\"notices green\">\n<p>Contact <a href=\"https:\/\/ca-test.adyen.com\/ca\/ca\/contactUs\/support.shtml?form=other\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Support Team<\/a> if you don't see the <strong>Allow SDK download for POS developers<\/strong> role.<\/p>\n<\/div><\/li>\n<li>Select <strong>Save changes<\/strong>.<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>Save the basic authentication password in a <a href=\"https:\/\/everything.curl.dev\/usingcurl\/netrc.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">.netrc<\/a> file:<\/p>\n<ol>\n<li>\n<p>Check if you already have a <code>.netrc<\/code> file in your home directory. If you do not have it, create a plain text file with that name in your home directory (<code>~\/.netrc<\/code>).<\/p>\n<\/li>\n<li>\n<p>Add the following content to your <code>.netrc<\/code> file, where <code>login<\/code> is the API credential username, for example ws_12345@Company.[YourCompanyAccount], and <code>password<\/code> is the basic authentication password.<\/p>\n<\/li>\n<\/ol>\n<div data-component-wrapper=\"code-sample\">\n<code-sample :title=\"'.netrc content for TEST integration'\" :id=\"''\" :code-data='[{\"language\":\"raw\",\"tabTitle\":\"\",\"content\":\"machine pos-mobile-test.cdn.adyen.com\\nlogin YOUR_BASIC_AUTH_USERNAME\\npassword YOUR_BASIC_AUTH_PASSWORD\"}]' :enable-copy-link-to-code-block=\"true\" :code-sample-card-size=\"'fullsize'\"><\/code-sample>\n<\/div>\n<ol start=\"3\">\n<li>Make sure that the <code>.netrc<\/code> file has the following file system permission: <strong>0600<\/strong>.<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>Add the POS Mobile SDK as a package dependency to your Xcode project:<\/p>\n<div class=\"notices yellow\">\n<p>It is not possible to use TEST and LIVE environments from a single app target. You need to setup your Xcode project to have separate app targets for Test and for Live. Each target needs to link to the respective AdyenPOS SDK version for its environment: <code>AdyenPOSTest<\/code> and <code>AdyenPOSLive<\/code>.<\/p>\n<\/div>\n<ol>\n<li>\n<p>In your Xcode project or workspace, go to <strong>File<\/strong> &gt; <strong>Add Package Dependencies<\/strong>.<\/p>\n<\/li>\n<li>\n<p>Enter the <strong>URL<\/strong> <code>https:\/\/github.com\/Adyen\/adyen-pos-mobile-ios-test<\/code> and select your preferred <strong>Dependency Rule<\/strong>.<\/p>\n<\/li>\n<li>\n<p>Select <strong>Add Package<\/strong>, and after the SDK is loaded add <code>AdyenPOSTEST<\/code> to your app target that connects to the Adyen test environment.<\/p>\n<\/li>\n<li>\n<p>Select <strong>Add Package<\/strong>.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>In your code, add <code>import AdyenPOS<\/code>, or for Objective-C compatibility add <code>#import \"ADYPOS\/ADYPOS.h\"<\/code>.<\/p>\n<\/li>\n<\/ol>\n<h3 id=\"objective-c\">Compatibility with Objective-C<\/h3>\n<p>If your POS app requires the iOS Mobile SDK to be compatible with Objective-C:<\/p>\n<ul>\n<li>Link the <code>ADYPOSTEST<\/code> package product to your app target instead of <code>AdyenPOSTEST<\/code>.<\/li>\n<li>Link the <code>ADYPOSLIVE<\/code> package product to your app target instead of <code>AdyenPOSLIVE<\/code>.\n<div class=\"notices yellow\">\n<p>It is not possible to use TEST and LIVE environments from a single app target. Each app target must connect to a specific environment.<\/p>\n<\/div><\/li>\n<\/ul>\n<p>The integration process is the same. The only difference is that the public symbols are prefixed with <code>ADY<\/code>. For example, <code>PaymentService<\/code> is called  <code>ADYPaymentService<\/code>.<\/p>\n<h2 id=\"session\">2. Establish a session<\/h2>\n<p>The Mobile SDK has to communicate in a secure way with the plataforma de pagamentos da Adyen. For more information, see <a href=\"\/pt\/point-of-sale\/mobile-ios\/understand#session\">Communication session<\/a>. <\/p>\n<p>To authenticate your server-to-server API request for establishing a communication session, you need to have an Adyen <a href=\"\/pt\/development-resources\/api-credentials\">API credential<\/a> in your <a href=\"https:\/\/ca-test.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">test Customer Area<\/a>. This credential must have a <a href=\"\/pt\/development-resources\/client-side-authentication\">client key<\/a> and an <a href=\"\/pt\/development-resources\/api-credentials#generate-api-key\">API key<\/a> with the following <a href=\"\/pt\/development-resources\/api-credentials#api-permissions\">role<\/a>:<\/p>\n<ul>\n<li><strong>Checkout webservice role<\/strong>. This role is assigned by default when the API key is created.<\/li>\n<\/ul><p>To add a client key to an existing API credential, create a client key as follows:<\/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\">Customer Area<\/a>.<\/li>\n<li>Go to <strong>Developers<\/strong> &gt; <strong>API credentials<\/strong>, and select the credential username for your integration, for example <strong>ws@Company.[YourCompanyAccount]<\/strong>.<\/li>\n<li>Under <strong>Client settings<\/strong> &gt; <strong>Authentication<\/strong> select the <strong>Client key<\/strong> tab.<\/li>\n<li>Select <strong>Generate client key<\/strong>.<\/li>\n<li>\n<p>Select <strong>Save changes<\/strong>.<\/p>\n<div class=\"sc-notice info\"><div>\n<p>The client key is part of the setup but is not used later on. Therefore, you do not need to specify allowed origins, and you do not need to save the client key in your system.<\/p>\n<\/div><\/div>\n<\/li>\n<\/ol>\n<p>To let your backend establish a session, use the regular endpoint, or the dedicated endpoint for <a href=\"\/pt\/get-started-with-adyen\/adyen-glossary#payment-facilitator-payfac\" target=\"_blank\">payment facilitators<\/a>.<\/p>\n<ul>\n<li>Regular endpoint:  <a href=\"https:\/\/docs.adyen.com\/api-explorer\/possdk\/latest\/post\/sessions\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/checkout\/possdk\/v68\/sessions<\/a><\/li>\n<li>Payment facilitator endpoint: <code>\/softposconfig\/v3\/auth\/certificate<\/code><\/li>\n<\/ul>\n\n<div id=\"tabn4jwQ\">\n    <div data-component-wrapper=\"tabs\">\n        <tabs\n                        :items=\"[{&quot;title&quot;:&quot;Regular endpoint&quot;,&quot;content&quot;:&quot;\\n&lt;ol&gt;\\n&lt;li&gt;\\n&lt;p&gt;From your backend, make a POST  &lt;a href=\\&quot;https:\\\/\\\/docs.adyen.com\\\/api-explorer\\\/possdk\\\/latest\\\/post\\\/sessions\\&quot; class=\\&quot;codeLabel  external-link no-image\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot;&gt;\\\/checkout\\\/possdk\\\/v68\\\/sessions&lt;\\\/a&gt; request, specifying:&lt;\\\/p&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Parameter&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Required&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt; &lt;a href=\\&quot;https:\\\/\\\/docs.adyen.com\\\/api-explorer\\\/possdk\\\/latest\\\/post\\\/sessions#request-merchantAccount\\&quot; class=\\&quot;codeLabel  external-link no-image\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot;&gt;merchantAccount&lt;\\\/a&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The unique identifier of your &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/design-your-integration\\\/determine-account-structure#request-merchant-accounts\\&quot;&gt;merchant account&lt;\\\/a&gt;.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt; &lt;a href=\\&quot;https:\\\/\\\/docs.adyen.com\\\/api-explorer\\\/possdk\\\/latest\\\/post\\\/sessions#request-setupToken\\&quot; class=\\&quot;codeLabel  external-link no-image\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot;&gt;setupToken&lt;\\\/a&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The setup token provided by the Mobile SDK through the  &lt;code&gt;PaymentServiceDelegate.register(with:)&lt;\\\/code&gt; callback of &lt;code&gt;PaymentServiceDelegate&lt;\\\/code&gt; .&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt; &lt;a href=\\&quot;https:\\\/\\\/docs.adyen.com\\\/api-explorer\\\/possdk\\\/latest\\\/post\\\/sessions#request-store\\&quot; class=\\&quot;codeLabel  external-link no-image\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot;&gt;store&lt;\\\/a&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The reference of the &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/design-your-integration\\\/determine-account-structure#create-stores\\&quot;&gt;store&lt;\\\/a&gt; that you want to process payments for. Do not include this parameter if your &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/design-your-integration\\\/determine-account-structure#determine-account-structure\\&quot;&gt;account structure&lt;\\\/a&gt; uses merchant accounts as stores.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&lt;div data-component-wrapper=\\&quot;code-sample\\&quot;&gt;\\n&lt;code-sample :title=\\&quot;&#039;\\\/sessions request&#039;\\&quot; :id=\\&quot;&#039;&#039;\\&quot; :code-data=\\&quot;[{&amp;quot;language&amp;quot;:&amp;quot;bash&amp;quot;,&amp;quot;tabTitle&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;curl https:\\\\\\\/\\\\\\\/checkout-test.adyen.com\\\\\\\/checkout\\\\\\\/possdk\\\\\\\/v68\\\\\\\/sessions \\\\\\\\\\\\n-H &#039;content-type: application\\\\\\\/json&#039; \\\\\\\\\\\\n-H &#039;x-API-key: ADYEN_API_KEY&#039; \\\\\\\\\\\\n-X POST \\\\\\\\\\\\n-d &#039;{\\\\n    \\\\&amp;quot;merchantAccount\\\\&amp;quot;: \\\\&amp;quot;YOUR_MERCHANT_ACCOUNT\\\\&amp;quot;,\\\\n    \\\\&amp;quot;setupToken\\\\&amp;quot;: \\\\&amp;quot;SETUP_TOKEN\\\\&amp;quot;,\\\\n    \\\\&amp;quot;store\\\\&amp;quot;: \\\\&amp;quot;YOUR_STORE_REFERENCE\\\\&amp;quot;\\\\n}&#039;&amp;quot;}]\\&quot; :enable-copy-link-to-code-block=\\&quot;true\\&quot; :code-sample-card-size=\\&quot;&#039;fullsize&#039;\\&quot;&gt;&lt;\\\/code-sample&gt;\\n&lt;\\\/div&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;When you receive the response:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;Check that you get a &lt;strong&gt;201 Created&lt;\\\/strong&gt; HTTP status code.&lt;\\\/li&gt;\\n&lt;li&gt;Return the  &lt;a href=\\&quot;https:\\\/\\\/docs.adyen.com\\\/api-explorer\\\/possdk\\\/latest\\\/post\\\/sessions#responses-201-sdkData\\&quot; class=\\&quot;codeLabel  external-link no-image\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot;&gt;sdkData&lt;\\\/a&gt; to your POS app.&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;If you create the Terminal API request on your backend, save the  &lt;a href=\\&quot;https:\\\/\\\/docs.adyen.com\\\/api-explorer\\\/possdk\\\/latest\\\/post\\\/sessions#responses-201-installationId\\&quot; class=\\&quot;codeLabel  external-link no-image\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot;&gt;installationId&lt;\\\/a&gt; and use this as the &lt;code&gt;POIID&lt;\\\/code&gt; in the &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/design-your-integration\\\/terminal-api#request-message-header\\&quot;&gt;\\n  &lt;code&gt;MessageHeader&lt;\\\/code&gt;\\n&lt;\\\/a&gt; of the payment request.&lt;\\\/p&gt;\\n&lt;!-- list-separator --&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;div data-component-wrapper=\\&quot;code-sample\\&quot;&gt;\\n&lt;code-sample :title=\\&quot;&#039;\\\/sessions response&#039;\\&quot; :id=\\&quot;&#039;&#039;\\&quot; :code-data=&#039;[{\\&quot;language\\&quot;:\\&quot;json\\&quot;,\\&quot;tabTitle\\&quot;:\\&quot;\\&quot;,\\&quot;content\\&quot;:\\&quot;{\\\\n    \\\\\\&quot;id\\\\\\&quot;: \\\\\\&quot;APP_SESSION_ID\\\\\\&quot;,\\\\n    \\\\\\&quot;installationId\\\\\\&quot;: \\\\\\&quot;INSTALLATION_ID\\\\\\&quot;,\\\\n    \\\\\\&quot;merchantAccount\\\\\\&quot;: \\\\\\&quot;YOUR_MERCHANT_ACCOUNT\\\\\\&quot;,\\\\n    \\\\\\&quot;store\\\\\\&quot;: \\\\\\&quot;YOUR_STORE_ID\\\\\\&quot;,\\\\n    \\\\\\&quot;sdkData\\\\\\&quot;: \\\\\\&quot;SDK_DATA_BLOB\\\\\\&quot;\\\\n}\\&quot;}]&#039; :enable-copy-link-to-code-block=\\&quot;true\\&quot; :code-sample-card-size=\\&quot;&#039;fullsize&#039;\\&quot;&gt;&lt;\\\/code-sample&gt;\\n&lt;\\\/div&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ol&gt;\\n&quot;,&quot;altTitle&quot;:null,&quot;oldTabId&quot;:&quot;regular_endpoint_0_1&quot;,&quot;relation&quot;:&quot;&quot;},{&quot;title&quot;:&quot;Payment facilitator endpoint&quot;,&quot;content&quot;:&quot;\\n&lt;p&gt;If you are a payment facilitator, card schemes need to receive certain data about your sub-merchant with each transaction. That is because your sub-merchant is considered the Merchant of Record when a transaction is facilitated by you.&lt;\\\/p&gt;\\n&lt;p&gt;Adyen automatically adds certain sub-merchant data to transactions that you facilitate. The remaining data must be supplied by you when you establish a communication session.&lt;\\\/p&gt;\\n&lt;div class=\\&quot;notices red\\&quot;&gt;\\n&lt;p&gt;You must &lt;strong&gt;not&lt;\\\/strong&gt; submit sub-merchant data in your Terminal API requests.&lt;\\\/p&gt;\\n&lt;\\\/div&gt;\\n&lt;h4 id=\\&quot;endpoints-to-use\\&quot;&gt;Endpoints to use&lt;\\\/h4&gt;\\n&lt;ul&gt;\\n&lt;li&gt;Test endpoint: &lt;code&gt;https:\\\/\\\/softposconfig-test.adyen.com\\\/softposconfig\\\/v3\\\/auth\\\/certificate&lt;\\\/code&gt;&lt;\\\/li&gt;\\n&lt;li&gt;Regional live endpoints:\\n&lt;ul&gt;\\n&lt;li&gt;Australia: &lt;code&gt;https:\\\/\\\/softposconfig-live-au.adyen.com\\\/softposconfig\\\/v3\\\/auth\\\/certificate&lt;\\\/code&gt;&lt;\\\/li&gt;\\n&lt;li&gt;Asia Pacific South East: &lt;code&gt;https:\\\/\\\/softposconfig-live-apse.adyen.com\\\/softposconfig\\\/v3\\\/auth\\\/certificate&lt;\\\/code&gt;&lt;\\\/li&gt;\\n&lt;li&gt;Europe: &lt;code&gt;https:\\\/\\\/softposconfig-live.adyen.com\\\/softposconfig\\\/v3\\\/auth\\\/certificate&lt;\\\/code&gt;&lt;\\\/li&gt;\\n&lt;li&gt;North East Asia: &lt;code&gt;https:\\\/\\\/softposconfig-live-nea.adyen.com\\\/softposconfig\\\/v3\\\/auth\\\/certificate&lt;\\\/code&gt;&lt;\\\/li&gt;\\n&lt;li&gt;United States: &lt;code&gt;https:\\\/\\\/softposconfig-live-us.adyen.com\\\/softposconfig\\\/v3\\\/auth\\\/certificate&lt;\\\/code&gt;&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;h4&gt;Request and response&lt;\\\/h4&gt;\\n&lt;ol&gt;\\n&lt;li&gt;\\n&lt;p&gt;From your backend, make a POST request to the applicable &lt;code&gt;\\\/softposconfig\\\/v3\\\/auth\\\/certificate&lt;\\\/code&gt; &lt;a href=\\&quot;#endpoints-to-use\\&quot;&gt;endpoint&lt;\\\/a&gt;, specifying:&lt;\\\/p&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Parameter&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Required&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;merchantAccount&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The unique identifier of your &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/design-your-integration\\\/determine-account-structure#request-merchant-accounts\\&quot;&gt;merchant account&lt;\\\/a&gt;.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;setupToken&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The setup token provided by the Mobile SDK through the  &lt;code&gt;PaymentServiceDelegate.register(with:)&lt;\\\/code&gt; callback of &lt;code&gt;PaymentServiceDelegate&lt;\\\/code&gt; .&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;subMerchantData&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;An object with the details of the sub-merchant. See the next table for details.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&lt;p&gt;The &lt;code&gt;subMerchantData&lt;\\\/code&gt; object includes the following parameters:&lt;\\\/p&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Parameter&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Required&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;id&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;You unique identifier of the sub-merchant.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;name&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The name of the sub-merchant.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;mcc&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The sub-merchant&#039;s four-digit Merchant Category Code (MCC). This parameter is used to correctly route the transaction.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;street&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The street name and house number of the sub-merchant&#039;s address.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;city&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The city of the sub-merchant&#039;s address.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;postalCode&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The postal code of the sub-merchant&#039;s address, without dashes.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;country&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;img title=\\&quot;-white_check_mark-\\&quot; alt=\\&quot;-white_check_mark-\\&quot; class=\\&quot;smileys\\&quot; src=\\&quot;\\\/user\\\/data\\\/smileys\\\/emoji\\\/white_check_mark.png\\&quot; \\\/&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The country\\\/region of the sub-merchant&#039;s address, specified as the three-letter country code in &lt;a href=\\&quot;https:\\\/\\\/en.wikipedia.org\\\/wiki\\\/ISO_3166-1_alpha-3\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot; class=\\&quot;external-link no-image\\&quot;&gt;ISO 3166-1 alpha-3&lt;\\\/a&gt; format.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;state&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The state code of the sub-merchant&#039;s address, if applicable for the country or region.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;taxId&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The tax ID of the sub-merchant. Required only in Brazil and for Cartes Bancaires in France. &lt;br&gt; For Brazil, this is the 11-digit CPF or 14-digit CNPJ. &lt;br&gt; For France, this is the SIRET, with a maximum of 14 digits.&lt;\\\/td&gt;\\n&lt;td&gt;&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;displayName&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The name of the sub-merchant as it should appear on the display of the mobile device during transactions. Only for Tap to Pay on iPhone.&lt;\\\/td&gt;\\n&lt;td&gt;&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;email&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The email address of the sub-merchant. Required for American Express.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;phoneNumber&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The phone number of the sub-merchant. Required for American Express.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&lt;div data-component-wrapper=\\&quot;code-sample\\&quot;&gt;\\n&lt;code-sample :title=\\&quot;&#039;\\\/certificate request&#039;\\&quot; :id=\\&quot;&#039;&#039;\\&quot; :code-data=\\&quot;[{&amp;quot;language&amp;quot;:&amp;quot;bash&amp;quot;,&amp;quot;tabTitle&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;curl https:\\\\\\\/\\\\\\\/softposconfig-test.adyen.com\\\\\\\/softposconfig\\\\\\\/v3\\\\\\\/auth\\\\\\\/certificate \\\\\\\\\\\\n-H &#039;content-type: application\\\\\\\/json&#039; \\\\\\\\\\\\n-H &#039;x-API-key: ADYEN_API_KEY&#039; \\\\\\\\\\\\n-X POST \\\\\\\\\\\\n-d &#039;{\\\\n    \\\\&amp;quot;merchantAccount\\\\&amp;quot;: \\\\&amp;quot;YOUR_MERCHANT_ACCOUNT\\\\&amp;quot;,\\\\n    \\\\&amp;quot;setupToken\\\\&amp;quot;: \\\\&amp;quot;SETUP_TOKEN\\\\&amp;quot;,\\\\n    \\\\&amp;quot;subMerchantData\\\\&amp;quot;: {\\\\n        \\\\&amp;quot;id\\\\&amp;quot;: \\\\&amp;quot;123456\\\\&amp;quot;,\\\\n        \\\\&amp;quot;name\\\\&amp;quot;: \\\\&amp;quot;Test Merchant\\\\&amp;quot;,\\\\n        \\\\&amp;quot;mcc\\\\&amp;quot;: \\\\&amp;quot;5734\\\\&amp;quot;,\\\\n        \\\\&amp;quot;street\\\\&amp;quot;: \\\\&amp;quot;123 Sample Street\\\\&amp;quot;,\\\\n        \\\\&amp;quot;city\\\\&amp;quot;: \\\\&amp;quot;San Francisco\\\\&amp;quot;,\\\\n        \\\\&amp;quot;state\\\\&amp;quot;: \\\\&amp;quot;CA\\\\&amp;quot;,\\\\n        \\\\&amp;quot;postalCode\\\\&amp;quot;: \\\\&amp;quot;94107\\\\&amp;quot;,\\\\n        \\\\&amp;quot;country\\\\&amp;quot;: \\\\&amp;quot;USA\\\\&amp;quot;,\\\\n        \\\\&amp;quot;taxId\\\\&amp;quot;: \\\\&amp;quot;TAX123456\\\\&amp;quot;,\\\\n        \\\\&amp;quot;displayName\\\\&amp;quot;: \\\\&amp;quot;SF Computer Software\\\\&amp;quot;,\\\\n        \\\\&amp;quot;email\\\\&amp;quot;: \\\\&amp;quot;test-merchant@example.com\\\\&amp;quot;,\\\\n        \\\\&amp;quot;phoneNumber\\\\&amp;quot;: \\\\&amp;quot;+14151234567\\\\&amp;quot;\\\\n    }\\\\n}&#039;&amp;quot;}]\\&quot; :enable-copy-link-to-code-block=\\&quot;true\\&quot; :code-sample-card-size=\\&quot;&#039;fullsize&#039;\\&quot;&gt;&lt;\\\/code-sample&gt;\\n&lt;\\\/div&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;When you receive the response:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;Check that you get a &lt;strong&gt;201 Created&lt;\\\/strong&gt; HTTP status code.&lt;\\\/li&gt;\\n&lt;li&gt;Return the &lt;code&gt;sdkData&lt;\\\/code&gt; to your POS app.&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;If you create the Terminal API request on your backend, save the &lt;code&gt;installationId&lt;\\\/code&gt; and use this as the &lt;code&gt;POIID&lt;\\\/code&gt; in the &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/design-your-integration\\\/terminal-api#request-message-header\\&quot;&gt;\\n  &lt;code&gt;MessageHeader&lt;\\\/code&gt;\\n&lt;\\\/a&gt; of the payment request.&lt;\\\/p&gt;\\n&lt;!-- list-separator --&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;div data-component-wrapper=\\&quot;code-sample\\&quot;&gt;\\n&lt;code-sample :title=\\&quot;&#039;Successful \\\/certificate response&#039;\\&quot; :id=\\&quot;&#039;&#039;\\&quot; :code-data=&#039;[{\\&quot;language\\&quot;:\\&quot;json\\&quot;,\\&quot;tabTitle\\&quot;:\\&quot;\\&quot;,\\&quot;content\\&quot;:\\&quot;{\\\\n    \\\\\\&quot;id\\\\\\&quot;: \\\\\\&quot;APP_SESSION_ID\\\\\\&quot;,\\\\n    \\\\\\&quot;installationId\\\\\\&quot;: \\\\\\&quot;INSTALLATION_ID\\\\\\&quot;,\\\\n    \\\\\\&quot;merchantAccount\\\\\\&quot;: \\\\\\&quot;YOUR_MERCHANT_ACCOUNT\\\\\\&quot;,\\\\n    \\\\\\&quot;store\\\\\\&quot;: \\\\\\&quot;YOUR_STORE_ID\\\\\\&quot;,\\\\n    \\\\\\&quot;sdkData\\\\\\&quot;: \\\\\\&quot;SDK_DATA_BLOB\\\\\\&quot;\\\\n}\\&quot;}]&#039; :enable-copy-link-to-code-block=\\&quot;true\\&quot; :code-sample-card-size=\\&quot;&#039;fullsize&#039;\\&quot;&gt;&lt;\\\/code-sample&gt;\\n&lt;\\\/div&gt;\\n&lt;p&gt;If you receive a response with an error message similar to the following, ask our &lt;a href=\\&quot;https:\\\/\\\/ca-test.adyen.com\\\/ca\\\/ca\\\/contactUs\\\/support.shtml?form=other\\&quot; target=\\&quot;_blank\\&quot; rel=\\&quot;nofollow noopener noreferrer\\&quot; class=\\&quot;external-link no-image\\&quot;&gt;Support Team&lt;\\\/a&gt; to configure the MCC that you specified in the request.&lt;\\\/p&gt;\\n&lt;div data-component-wrapper=\\&quot;code-sample\\&quot;&gt;\\n&lt;code-sample :title=\\&quot;&#039;\\\/certificate error message&#039;\\&quot; :id=\\&quot;&#039;&#039;\\&quot; :code-data=&#039;[{\\&quot;language\\&quot;:\\&quot;raw\\&quot;,\\&quot;tabTitle\\&quot;:\\&quot;\\&quot;,\\&quot;content\\&quot;:\\&quot;Refused (905_3 Could not find an acquirer account for the provided currency (USD).)\\&quot;}]&#039; :enable-copy-link-to-code-block=\\&quot;true\\&quot; :code-sample-card-size=\\&quot;&#039;fullsize&#039;\\&quot;&gt;&lt;\\\/code-sample&gt;\\n&lt;\\\/div&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ol&gt;\\n&quot;,&quot;altTitle&quot;:null,&quot;oldTabId&quot;:&quot;payment_facilitator_endpoint_1_2&quot;,&quot;relation&quot;:&quot;&quot;}]\"\n            :should-update-when-url-changes='false'>\n        <\/tabs>\n    <\/div>\n<\/div>\n\n<h2 id=\"enable-transactions\">3. Enable transactions<\/h2>\n<p>To enable the payments functionality of the Mobile SDK:<\/p>\n<ol>\n<li>\n<p>In your POS app, implement the <code>PaymentServiceDelegate<\/code> protocol. Below is an example of how you could do that.<\/p>\n<pre><code class=\"language-swift\">struct SessionsResponse: Decodable {\n    let sdkData: String\n}\n\nclass MyPaymentServiceDelegate: PaymentServiceDelegate {\n    internal func register(\n        with setupToken: String\n    ) async throws -&gt; String {\n        \/\/\/ Make a call to your backend to trigger a `\/checkout\/possdk\/v68\/sessions` request, specifying the `setupToken` provided by the SDK.\n        let request = URLRequest(url: URL(string: \"{ADDRESS_OF_YOUR_BACKEND_API}\")!)\n        let (data, _) = try await URLSession.shared.data(for: request)\n        let response = try JSONDecoder().decode(SessionsResponse.self, from: data)\n        return response.sdkData\n    }\n}<\/code><\/pre>\n<p>The actual structure of the <code>SessionsResponse<\/code> depends on your backend implementation.<\/p>\n<\/li>\n<li>\n<p>Create an instance of <code>PaymentService<\/code> with the <code>PaymentService(delegate:)<\/code> initializer and pass the delegate object. Make sure that you keep a strong reference to the payment service instance so that it is retained for the duration of the transaction. Also make sure your <code>delegate<\/code> is strongly referenced, because the <code>PaymentService<\/code> keeps a weak reference to the <code>delegate<\/code>.<\/p>\n<pre><code class=\"language-swift\">let paymentService = PaymentService(delegate: myPaymentServiceDelegate)<\/code><\/pre>\n<\/li>\n<li>\n<p>Make sure that the <code>PaymentServiceDelegate<\/code> can provide new <code>sdkData<\/code> at any time.<br \/>\nIf there is no session or the session has expired, the delegate is called using the <code>PaymentServiceDelegate.register(with:)<\/code> callback. Using the provided <code>setupToken<\/code> you need to get the <code>sdkData<\/code> through your backend and return it. For instructions, see <a href=\"#session\">Establish a session<\/a>.<\/p>\n<\/li>\n<li>\n<p>Optional. Verify that the callback works, by calling the warm-up function.<\/p>\n<div class=\"notices blue\">\n<p>The warm-up function checks for a session and any configuration changes, and prepares the proximity reader on the iPhone. <\/p>\n<\/div>\n<pre><code class=\"language-swift\">try await paymentService.warmUp()<\/code><\/pre>\n<\/li>\n<\/ol>\n<h2 id=\"use-warm-up\">4. Use the warm-up function<\/h2>\n<p>To speed up initiating transactions, you can use the warm-up function. This function checks for a session and any configuration changes<\/p>\n<p>As a best practice, call the warm-up function:<\/p>\n<ul>\n<li>When the POS app starts. In other words, as soon as the app has the <a href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uiapplication\/state\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">active state<\/a>.<\/li>\n<li>When the POS app returns to the active state after running in the background.<\/li>\n<\/ul>\n<p>To call the warm-up function:<\/p>\n<pre><code class=\"language-swift\">try await paymentService.warmUp()<\/code><\/pre>\n<div class=\"notices green\">\n<p>Similar to the warm-up function, you can optionally <a href=\"\/pt\/point-of-sale\/mobile-ios\/build\/card-reader#prepare-the-card-reader-for-transaction\">prepare the card reader<\/a> to perform hardware configuration updates and security checks outside the transaction flow. <\/p>\n<\/div>\n<h2 id=\"configure-pos-app\">5. Configure your POS app<\/h2>\n<p>For your card reader solution you need to configure your POS app to:<\/p>\n<ul>\n<li><a href=\"#pairing-permissions\">Manage pairing permissions<\/a>.<\/li>\n<li><a href=\"#usb-permissions\">Manage USB permissions<\/a>.<\/li>\n<li><a href=\"#suppress-apple-pay\">Suppress Apple Pay in your POS app<\/a>.<\/li>\n<\/ul>\n<h3 id=\"pairing-permissions\">Manage pairing permissions<\/h3>\n<p>Your iOS POS app needs to have certain permissions for pairing the mobile device with the card reader.<\/p>\n<ul>\n<li>In the <code>Info.plist<\/code> of your POS app, add the following keys with an appropriate explanation:\n<ul>\n<li><a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/nsbluetoothalwaysusagedescription\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">\n  <code>NSBluetoothAlwaysUsageDescription<\/code>\n<\/a>: this enables setting up a Bluetooth pairing between the mobile device and the card reader.<\/li>\n<li><a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/nscamerausagedescription\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">\n  <code>NSCameraUsageDescription<\/code>\n<\/a>: this enables using the camera of the mobile device to scan the barcode of the card reader. Barcode scanning is one of the ways to select a card reader for pairing.<\/li>\n<\/ul><\/li>\n<\/ul>\n<h3 id=\"usb-permissions\">Manage USB permissions<\/h3>\n<p>If you are using the NYC1 dock:<\/p>\n<ul>\n<li>\n<p>Add the following key to the <code>Info.plist<\/code> of your POS app:<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information-property-list\/uisupportedexternalaccessoryprotocols\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">\n  <code>UISupportedExternalAccessoryProtocols<\/code>\n<\/a>: set this to <code>com.adyen.dock<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>If you are going to submit your application to the App Store, your <em>Review Notes<\/em> need to provide a Made for iPhone\/iPad Product Plan ID (MFi PPID). To get this MFi PPID, provide your Adyen contact with the following information:<\/p>\n<ul>\n<li>The exact app name as it appears in the App Store.<\/li>\n<li>The app version number.<\/li>\n<li>Whether it is an update to an existing app, or a new app.<\/li>\n<li>The app bundle ID.<\/li>\n<li>External Accessory protocol(s) supported by this app.<\/li>\n<li>A description of app including a general functions overview of the software and its key features.<\/li>\n<\/ul>\n<p>We will then allowlist your application in the Adyen MFi portal and share the required MFi PPID.<\/p>\n<\/li>\n<\/ul>\n<h3 id=\"suppress-apple-pay\">Suppress Apple Pay<\/h3>\n<div class=\"notices red\">\n<p>To accept payments from customers, you may need to suppress Apple Pay on the device that runs your mobile POS app.<\/p>\n<\/div>\n<p>It is possible that Apple Pay is enabled on the Apple device that runs your iOS POS app. For example, if staff use their personal iPhone. When a card reader is near, the device running the POS app tries to make the payment using the Apple Pay passes that are on the device.<\/p>\n<p>To prevent this from happening, you must suppress Apple Pay in your iOS POS app when your app is in the foreground.<\/p>\n<ol>\n<li>Contact Apple Pay at <a href=\"mailto:apple-pay-inquiries@apple.com\" class=\"mailto\">apple-pay-inquiries@apple.com<\/a> and ask for an entitlement to suppress Apple Pay.<\/li>\n<li>When you receive confirmation that the entitlement was granted, add the entitlement to your provisioning profile on the Apple developer website.<\/li>\n<li>In Xcode, in the <span translate=\"no\"><strong>Signing &amp; Capabilities<\/strong><\/span> settings, add the <a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/Miscellaneous\/Reference\/EntitlementKeyReference\/ApplePayandPassKitEntitlements\/ApplePayandPassKitEntitlements.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\"><code>com.apple.developer.passkit.pass-presentation-suppression<\/code> <\/a> key to the <em>.entitlements<\/em> file for your POS app.<\/li>\n<li>\n<p>In your POS app, call <a href=\"https:\/\/developer.apple.com\/documentation\/passkit\/pkpasslibrary\/1617078-requestautomaticpasspresentation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">requestAutomaticPassPresentationSuppression<\/a>.<\/p>\n<p>This method automatically switches between disabling Apple Pay when the POS app is in the foreground, and enabling Apple Pay when the POS app is in the background.<\/p>\n<\/li>\n<\/ol>\n<h2 id=\"avoid\">6. (Optional) Avoid delays<\/h2>\n<p>You can avoid delays and speed up the transaction by:<\/p>\n<ul>\n<li>Waking up the card reader after it has gone to sleep.<\/li>\n<li>Preparing the card reader outside a transaction flow with configuration and security checks.<\/li>\n<\/ul>\n<h3>Wake up the card reader<\/h3>\n<p>The card reader goes to sleep after about five minutes. When you start a transaction after the reader has gone to sleep, there is a slight delay while the mobile device reconnects to the last connected reader. To avoid this delay, you can take either of the following measures:<\/p>\n<ul>\n<li>Before starting the transaction, wake up the card reader by calling the <span translate=\"no\"><strong>DeviceManager<\/strong><\/span> <code>connect<\/code> function.<\/li>\n<li>Regularly refresh the connection between the mobile device and the card reader by implementing a timer that calls the <code>connect<\/code> function every couple of minutes.\n<div class=\"notices yellow\">\n<p>Be aware that implementing a timer can significantly decrease the battery life of the card reader.<\/p>\n<\/div><\/li>\n<\/ul>\n<p>Call the <code>connect<\/code> method as follows, where <code>viewModel<\/code> is a class that contains an instance of the SDK's <code>PaymentService<\/code> (for an example, see our <a href=\"https:\/\/github.com\/Adyen\/adyen-pos-mobile-ios\/blob\/main\/POSSampleApp\/SampleAppSwiftUI\/MainViewModel.swift#L17\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">sample app<\/a>):<\/p>\n<pre><code class=\"language-swift\">Button(\"Connect to last known reader\") {\n    if let device = viewModel.paymentService.deviceManager.knownDevices.first {\n        viewModel.paymentService.deviceManager.connect(to: device)\n    }\n}<\/code><\/pre>\n<h3>Prepare the card reader for transaction<\/h3>\n<p>When you start a transaction, the Mobile SDK connects with the card reader through Bluetooth to check the reader's configuration. If the configuration is not up to date, the Mobile SDK sends the latest configuration files to the reader. This can take up to to 30 seconds. Additionally, the Mobile SDK performs a security check every 24 hours. To avoid a delay during the transaction flow, you can prepare the card reader by running these checks outside the transaction flow.<\/p>\n<p>It is possible to start a transaction while the card reader preparation is running. There can be a short delay during the transaction while any remaining checks and configuration updates are completed.<\/p>\n<p>We recommend preparing the device for transaction every 24 hours or when the configuration has changed.<\/p>\n<p>To prepare the device outside a transaction flow:<\/p>\n<ol>\n<li>\n<p>Call the <span translate=\"no\"><strong>DeviceManager<\/strong><\/span> <code>prepareDeviceForTransaction<\/code> function  as follows, where the <code>connectedDevice<\/code> is the card reader to prepare.<\/p>\n<pre><code class=\"language-swift\">\/\/ Register delegate\npaymentService.deviceManager.delegate = self\n\n\/\/ Start device preparation\nif let connectedDevice = paymentService.deviceManager.connectedDevice {\n  paymentService.deviceManager.prepareDeviceForTransaction(connectedDevice)\n}<\/code><\/pre>\n<\/li>\n<li>When the preparation of the card reader is finished, the <code>deviceManager<\/code> delegate is called with <code>onDevicePreparationFinished<\/code> or an <a href=\"\/pt\/point-of-sale\/mobile-ios\/troubleshooting\/#error-messages\">\n  <code>error<\/code>\n<\/a> message.\n<pre><code class=\"language-Swift\">\/\/ Called when preparation finished\nfunc onDevicePreparationFinished(with error: Error?, by manager: DeviceManager) {\n\/\/ Handle result of preparation\n}<\/code><\/pre><\/li>\n<\/ol>\n<h2 id=\"manage-ui\">7. Manage the Device Manager UI<\/h2>\n<p>To use the card reader, operators need to:<\/p>\n<ul>\n<li>Connect the mobile device with the card reader through Bluetooth pairing, or through USB using a dock.<\/li>\n<li>View an overview of card readers. For example, to switch to a different card reader.<\/li>\n<li>View details of the card reader they are using. For example, to check the battery charge level.<\/li>\n<li>Update the firmware of the card reader or the dock they are using.<\/li>\n<\/ul>\n<p>To handle these tasks, the SDK provides device management functions that enable you to either:<\/p>\n<ul>\n<li>Use the built-in UI.<\/li>\n<li>Build a custom UI.<\/li>\n<\/ul>\n\n<div id=\"tabmiyfa\">\n    <div data-component-wrapper=\"tabs\">\n        <tabs\n                        :items=\"[{&quot;title&quot;:&quot;Use the built-in UI&quot;,&quot;content&quot;:&quot;\\n&lt;p&gt;To use the built-in UI, you only need to:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;\\n&lt;p&gt;&lt;strong&gt;Present the Device Management View&lt;\\\/strong&gt;.&lt;br \\\/&gt;\\nThis automatically takes care of all screens and flows that end users need. For a preview, see:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;&lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#ui-for-card-reader-operations\\&quot;&gt;UI for card reader operations&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;li&gt;&lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#bt-pairing\\&quot;&gt;Bluetooth pairing&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;li&gt;&lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#updating-card-reader\\&quot;&gt;Updating the card reader firmware&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;li&gt;&lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#connecting-usb-dock\\&quot;&gt;Connecting through USB using a dock&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;li&gt;&lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#updating-usb-dock\\&quot;&gt;Updating the dock firmware&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;&lt;strong&gt;Alert users to available firmware updates&lt;\\\/strong&gt;.&lt;br \\\/&gt;\\nThe built-in UI automatically signals that a firmware update is available. In practice however, end users often need an extra reminder. For a secure transaction flow, it is very important that end users update the devices. We therefore strongly recommend that you implement a command to check for firmware updates and create a UI to alert end users and direct them to the built-in screen for performing the update.&lt;\\\/p&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;p&gt;Proceed as follows:&lt;\\\/p&gt;\\n&lt;ol&gt;\\n&lt;li&gt;\\n&lt;p&gt;Use the built-in device management screens from within either SwiftUI or UIKit.&lt;\\\/p&gt;\\n\\n&lt;div id=\\&quot;tabIJqi4\\&quot;&gt;\\n    &lt;div data-component-wrapper=\\&quot;tabs\\&quot;&gt;\\n        &lt;tabs\\n                        :items=\\&quot;[{&amp;quot;title&amp;quot;:&amp;quot;Use the built-in UI through SwiftUI&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;\\\\n&amp;lt;p&amp;gt;To use the device management screens built into the Mobile SDK from within SwiftUI:&amp;lt;\\\\\\\/p&amp;gt;\\\\n&amp;lt;ul&amp;gt;\\\\n&amp;lt;li&amp;gt;\\\\n&amp;lt;p&amp;gt;Add &amp;lt;code&amp;gt;DeviceManagementView&amp;lt;\\\\\\\/code&amp;gt; to the &amp;lt;code&amp;gt;body&amp;lt;\\\\\\\/code&amp;gt; property of your&amp;lt;br \\\\\\\/&amp;gt;\\\\n&amp;lt;a href=\\\\&amp;quot;https:\\\\\\\/\\\\\\\/developer.apple.com\\\\\\\/documentation\\\\\\\/swiftui\\\\\\\/view\\\\&amp;quot; target=\\\\&amp;quot;_blank\\\\&amp;quot; rel=\\\\&amp;quot;nofollow noopener noreferrer\\\\&amp;quot; class=\\\\&amp;quot;external-link no-image\\\\&amp;quot;&amp;gt;View&amp;lt;\\\\\\\/a&amp;gt;. One of the ways to do that, is using a &amp;lt;a href=\\\\&amp;quot;https:\\\\\\\/\\\\\\\/developer.apple.com\\\\\\\/documentation\\\\\\\/swiftui\\\\\\\/view\\\\\\\/sheet(item:ondismiss:content:)\\\\&amp;quot; target=\\\\&amp;quot;_blank\\\\&amp;quot; rel=\\\\&amp;quot;nofollow noopener noreferrer\\\\&amp;quot; class=\\\\&amp;quot;external-link no-image\\\\&amp;quot;&amp;gt;.sheet&amp;lt;\\\\\\\/a&amp;gt;:&amp;lt;\\\\\\\/p&amp;gt;\\\\n&amp;lt;pre&amp;gt;&amp;lt;code class=\\\\&amp;quot;language-swift\\\\&amp;quot;&amp;gt;struct MyView: View {\\\\n  @State private var showingDeviceManagement = false\\\\n  private let paymentService: PaymentService = ...\\\\n\\\\n  var body: some View {\\\\n      { ... }\\\\n      .sheet(isPresented: $showingDeviceManagement) {\\\\n          NavigationView { DeviceManagementView(paymentService: paymentService) }\\\\n      }\\\\n  }\\\\n}&amp;lt;\\\\\\\/code&amp;gt;&amp;lt;\\\\\\\/pre&amp;gt;\\\\n&amp;lt;\\\\\\\/li&amp;gt;\\\\n&amp;lt;\\\\\\\/ul&amp;gt;\\\\n&amp;quot;,&amp;quot;altTitle&amp;quot;:null,&amp;quot;oldTabId&amp;quot;:&amp;quot;use_the_built-in_ui_through_swiftui_0_1&amp;quot;,&amp;quot;relation&amp;quot;:&amp;quot;&amp;quot;},{&amp;quot;title&amp;quot;:&amp;quot;Use the built-in UI through UIKit&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;\\\\n&amp;lt;p&amp;gt;To use the device management screens built into the Mobile SDK from within UIKit:&amp;lt;\\\\\\\/p&amp;gt;\\\\n&amp;lt;ol&amp;gt;\\\\n&amp;lt;li&amp;gt;Create an instance of &amp;lt;code&amp;gt;DeviceManagementViewController&amp;lt;\\\\\\\/code&amp;gt; using &amp;lt;code&amp;gt;DeviceManagementViewController(paymentService:)&amp;lt;\\\\\\\/code&amp;gt;, passing your instance of &amp;lt;code&amp;gt;PaymentService&amp;lt;\\\\\\\/code&amp;gt;.&amp;lt;\\\\\\\/li&amp;gt;\\\\n&amp;lt;li&amp;gt;\\\\n&amp;lt;p&amp;gt;Present it in your preferred way. For example, with &amp;lt;a href=\\\\&amp;quot;https:\\\\\\\/\\\\\\\/developer.apple.com\\\\\\\/documentation\\\\\\\/uikit\\\\\\\/uiviewcontroller\\\\\\\/1621380-presentviewcontroller\\\\&amp;quot; target=\\\\&amp;quot;_blank\\\\&amp;quot; rel=\\\\&amp;quot;nofollow noopener noreferrer\\\\&amp;quot; class=\\\\&amp;quot;external-link no-image\\\\&amp;quot;&amp;gt;presentViewController:animated:completion:&amp;lt;\\\\\\\/a&amp;gt;:&amp;lt;\\\\\\\/p&amp;gt;\\\\n&amp;lt;pre&amp;gt;&amp;lt;code class=\\\\&amp;quot;language-swift\\\\&amp;quot;&amp;gt;class MyViewController: UIViewController {\\\\n  let paymentService = PaymentService { ... }\\\\n\\\\n  func presentDeviceManagement() {\\\\n      let deviceManagementViewController = DeviceManagementViewController(paymentService: paymentService)\\\\n      present(deviceManagementViewController, animated: true)\\\\n  }\\\\n}&amp;lt;\\\\\\\/code&amp;gt;&amp;lt;\\\\\\\/pre&amp;gt;\\\\n&amp;lt;\\\\\\\/li&amp;gt;\\\\n&amp;lt;\\\\\\\/ol&amp;gt;\\\\n&amp;quot;,&amp;quot;altTitle&amp;quot;:null,&amp;quot;oldTabId&amp;quot;:&amp;quot;use_the_built-in_ui_through_uikit_1_2&amp;quot;,&amp;quot;relation&amp;quot;:&amp;quot;&amp;quot;}]\\&quot;\\n            :should-update-when-url-changes=&#039;false&#039;&gt;\\n        &lt;\\\/tabs&gt;\\n    &lt;\\\/div&gt;\\n&lt;\\\/div&gt;\\n\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Regularly check for firmware updates for the card reader and, if used, the dock:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;\\n&lt;p&gt;For card reader updates, check the &lt;code&gt;firmwareUpdateSummary&lt;\\\/code&gt; property on &lt;code&gt;deviceManager&lt;\\\/code&gt;.&lt;br \\\/&gt;\\nIf no update is available, a &lt;code&gt;nil&lt;\\\/code&gt; value is returned.&lt;br \\\/&gt;\\nWhen an update is found, an &lt;code&gt;AvailableFirmwareUpdate&lt;\\\/code&gt; object is returned that can include the following details:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;&lt;code&gt;requiresBluetoothConnection&lt;\\\/code&gt;: If &lt;span translate=\\&quot;no\\&quot;&gt;&lt;strong&gt;true&lt;\\\/strong&gt;&lt;\\\/span&gt;, the update includes the Bluetooth layer of the firmware and a Bluetooth connection is necessary to complete the update.&lt;\\\/li&gt;\\n&lt;li&gt;&lt;code&gt;requiredDate&lt;\\\/code&gt;: The date by which transactions will be refused if the card reader is not updated to this firmware version.&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;p&gt;When connected through USB (using the dock), Bluetooth updates cannot be completed and the SDK does not return information about available Bluetooth updates.&lt;\\\/p&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;For dock updates, check the &lt;code&gt;dockFirmwareUpdateSummary&lt;\\\/code&gt; property on &lt;code&gt;deviceManager&lt;\\\/code&gt;.&lt;br \\\/&gt;\\nIf no update is available, a &lt;code&gt;nil&lt;\\\/code&gt; value is returned.&lt;br \\\/&gt;\\nWhen an update is found, an &lt;code&gt;AvailableDockFirmwareUpdate&lt;\\\/code&gt; object is returned that includes:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;&lt;code&gt;requiredDate&lt;\\\/code&gt;: The date by which transactions will be refused if the dock is not updated to this firmware version.&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;!-- list-separator --&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Create a UI to prompt end users to update their devices, redirecting them to the built-in UI for performing the update. This is in addition to the built-in screens that alert to available updates.&lt;\\\/p&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ol&gt;\\n&quot;,&quot;altTitle&quot;:null,&quot;oldTabId&quot;:&quot;use_the_built-in_ui_0_1&quot;,&quot;relation&quot;:&quot;&quot;},{&quot;title&quot;:&quot;Build a custom UI&quot;,&quot;content&quot;:&quot;\\n&lt;p&gt;If you intend to build your own UI for device management, use the &lt;code&gt;DeviceManagerDelegate&lt;\\\/code&gt; protocol to obtain all the necessary information. For details, refer to &lt;code&gt;DeviceManagerDelegate&lt;\\\/code&gt; in the Mobile SDK.&lt;\\\/p&gt;\\n&lt;p&gt;For an overview, see the &lt;a href=\\&quot;#devicemanager-functions\\&quot;&gt;List of device management functions&lt;\\\/a&gt;. The next sections provide information about the device management functions you can use when building a UI for:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;&lt;a href=\\&quot;#bt-pairing\\&quot;&gt;Bluetooth pairing&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;li&gt;&lt;a href=\\&quot;#updating-card-reader\\&quot;&gt;Updating the card reader firmware&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;li&gt;&lt;a href=\\&quot;#connecting-usb-dock\\&quot;&gt;Connecting through USB using a dock&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;li&gt;&lt;a href=\\&quot;#updating-usb-dock\\&quot;&gt;Updating the dock firmware&lt;\\\/a&gt;&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;h3 id=\\&quot;bt-pairing\\&quot;&gt;Bluetooth pairing&lt;\\\/h3&gt;\\n&lt;p&gt;To build a UI for the Bluetooth pairing flow:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;Get a list of card readers in the vicinity by calling the &lt;code&gt;DeviceManager.startDiscovery()&lt;\\\/code&gt; function.&lt;\\\/li&gt;\\n&lt;li&gt;Connect to a card reader by calling the &lt;code&gt;DeviceManager.connect(to device: Device)&lt;\\\/code&gt; function.&lt;\\\/li&gt;\\n&lt;li&gt;Check if the Bluetooth pairing succeeded by implementing the &lt;code&gt;DeviceManagerDelegate.onDeviceConnected(with:to:)&lt;\\\/code&gt; method. The card reader was paired and connected successfully if this method is called and the &lt;code&gt;error&lt;\\\/code&gt; parameter is &lt;code&gt;nil&lt;\\\/code&gt;.&lt;\\\/li&gt;\\n&lt;li&gt;To disconnect from a card reader, call the &lt;code&gt;DeviceManager.disconnect()&lt;\\\/code&gt; function.&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;p&gt;As an example, &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#bt-pairing\\&quot;&gt;see the built-in UI screens&lt;\\\/a&gt;.&lt;\\\/p&gt;\\n&lt;h3 id=\\&quot;updating-card-reader\\&quot;&gt;Updating the card reader firmware&lt;\\\/h3&gt;\\n&lt;div class=\\&quot;notices yellow\\&quot;&gt;\\n&lt;p&gt;You must check for new firmware updates regularly, and provide a way to update the card reader to the latest version.&lt;\\\/p&gt;\\n&lt;\\\/div&gt;\\n&lt;p&gt;It is required that you build logic into your POS app to:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;Check for new card reader firmware updates often. For example, when the app is launched.&lt;\\\/li&gt;\\n&lt;li&gt;Handle the firmware update flow correctly within your POS app.&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;p&gt;Your UI must prompt end users to update the card reader firmware, and inform them about the progress and result of the update process.&lt;\\\/p&gt;\\n&lt;p&gt;To build a UI for card reader firmware updates:&lt;\\\/p&gt;\\n&lt;ol&gt;\\n&lt;li&gt;\\n&lt;p&gt;Make sure that you set the &lt;code&gt;firmwareDelegate&lt;\\\/code&gt; to your own instance correctly to receive firmware management events.&lt;\\\/p&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Regularly check if updates are available, by checking the &lt;code&gt;firmwareUpdateSummary&lt;\\\/code&gt; property on &lt;code&gt;deviceManager&lt;\\\/code&gt;.&lt;br \\\/&gt;\\nIf no update is available, a &lt;code&gt;nil&lt;\\\/code&gt; value is returned.&lt;br \\\/&gt;\\nWhen an update is found, an &lt;code&gt;AvailableFirmwareUpdate&lt;\\\/code&gt; object is returned that can include the following details:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;&lt;code&gt;requiresBluetoothConnection&lt;\\\/code&gt;: If &lt;span translate=\\&quot;no\\&quot;&gt;&lt;strong&gt;true&lt;\\\/strong&gt;&lt;\\\/span&gt;, the update includes the Bluetooth layer and a Bluetooth connection is necessary to complete the update.&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;&lt;code&gt;requiredDate&lt;\\\/code&gt;: The date by which transactions will be refused if the card reader is not updated to this firmware version.&lt;\\\/p&gt;\\n&lt;!-- list-separator --&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Start the update using the &lt;code&gt;DeviceManager.startFirmwareUpdate()&lt;\\\/code&gt; function.&lt;\\\/p&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Implement the &lt;code&gt;FirmwareManagerDelegate&lt;\\\/code&gt; delegate to build UI screens showing the progress and result of the update.&lt;\\\/p&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Delegate Method&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareDownloadProgress(percent: Double)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The SDK is in the process of downloading the firmware.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateProgress(percent: Double)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The SDK is installing the update on the card reader.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;applyingFirmwareUpdate()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The SDK is applying the update. The card reader will reboot and reconnect.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateComplete()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Indicates the process has completed.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateFailure(error: AdyenPOSError)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Invoked when the firmware update fails with an associated error.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;In case a firmware update failed because it required a Bluetooth connection and the error &lt;code&gt;AdyenPOSError.firmwareError(.bluetoothFirmwareUpdateError)&lt;\\\/code&gt; is thrown, ensure you provide instructions on how to reset the card reader before retrying the update. The instructions you need to provide, are as follows:&lt;\\\/p&gt;\\n&lt;ol&gt;\\n&lt;li&gt;Power off the reader.&lt;\\\/li&gt;\\n&lt;li&gt;Press and hold the power button until a single loud beep sounds.&lt;\\\/li&gt;\\n&lt;li&gt;Wait for the reader to reset and reboot.&lt;\\\/li&gt;\\n&lt;li&gt;In the Bluetooth settings of the mobile device, select \\&quot;Forget This Device\\&quot;.&lt;\\\/li&gt;\\n&lt;li&gt;Re-pair the reader and retry installing the update.&lt;\\\/li&gt;\\n&lt;\\\/ol&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ol&gt;\\n&lt;p&gt;As an example, &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#updating-card-reader\\&quot;&gt;see the built-in UI screens&lt;\\\/a&gt;.&lt;\\\/p&gt;\\n&lt;h3 id=\\&quot;connecting-usb-dock\\&quot;&gt;Connecting through USB using a dock&lt;\\\/h3&gt;\\n&lt;p&gt;A USB connection is automatically established when the user connects the dock to power, connects the mobile device to the dock using the USB-C cable provided with the card reader, and places the reader in the dock.&lt;\\\/p&gt;\\n&lt;p&gt;When connected through the dock, the card reader is always ready for use without delay. There is no need to reconnect to the card reader before initiating a transaction.&lt;\\\/p&gt;\\n&lt;p&gt;To build a UI for dock connections:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;Listen to &lt;code&gt;DeviceManagerDelegate.onDockConnected&lt;\\\/code&gt; and &lt;code&gt;DeviceManagerDelegate.onDockDisconnected&lt;\\\/code&gt; to follow what the end user did: connect the card reader to the dock, or disconnect the dock.&lt;\\\/li&gt;\\n&lt;li&gt;Make sure the UI clearly shows the difference between these situations:\\n&lt;ul&gt;\\n&lt;li&gt;The mobile device is connected to the dock through USB, but no card reader is placed in the dock.&lt;\\\/li&gt;\\n&lt;li&gt;The card reader is placed in the dock, but the mobile device is connected to the card reader through Bluetooth.&lt;\\\/li&gt;\\n&lt;li&gt;The card reader is placed in the dock and the mobile device is connected to the dock and the reader through USB.&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;p&gt;As an example, &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#connecting-usb-doc\\&quot;&gt;see the built-in UI screens&lt;\\\/a&gt;.&lt;\\\/p&gt;\\n&lt;h3 id=\\&quot;updating-usb-dock\\&quot;&gt;Updating the dock firmware&lt;\\\/h3&gt;\\n&lt;div class=\\&quot;notices yellow\\&quot;&gt;\\n&lt;p&gt;You must check for new firmware updates regularly, and provide a way to update the dock to the latest version.&lt;\\\/p&gt;\\n&lt;\\\/div&gt;\\n&lt;p&gt;It is required that you build logic into your POS app to:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;Check for new dock firmware updates often. For example, when the app is launched.&lt;\\\/li&gt;\\n&lt;li&gt;Handle the firmware update flow correctly within your POS app.&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;p&gt;Your UI must prompt end users to update the dock firmware, and inform them about the progress and result of the update process.&lt;\\\/p&gt;\\n&lt;p&gt;To build a UI for dock firmware updates:&lt;\\\/p&gt;\\n&lt;ol&gt;\\n&lt;li&gt;\\n&lt;p&gt;Make sure that you set the &lt;code&gt;firmwareDelegate&lt;\\\/code&gt; to your own instance correctly to receive firmware management events.&lt;\\\/p&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Regularly check if updates are available, by checking the &lt;code&gt;dockFirmwareUpdateSummary&lt;\\\/code&gt; property on &lt;code&gt;deviceManager&lt;\\\/code&gt;.&lt;br \\\/&gt;\\nIf no update is available, a &lt;code&gt;nil&lt;\\\/code&gt; value is returned.&lt;br \\\/&gt;\\nWhen an update is found, an &lt;code&gt;AvailableDockFirmwareUpdate&lt;\\\/code&gt; object is returned that includes:&lt;\\\/p&gt;\\n&lt;ul&gt;\\n&lt;li&gt;\\n&lt;p&gt;&lt;code&gt;requiredDate&lt;\\\/code&gt;: The date by which transactions will be refused if the dock is not updated to this firmware version.&lt;\\\/p&gt;\\n&lt;!-- list-separator --&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ul&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Start the update using the &lt;code&gt;DeviceManager.startDockFirmwareUpdate()&lt;\\\/code&gt; function.&lt;\\\/p&gt;\\n&lt;\\\/li&gt;\\n&lt;li&gt;\\n&lt;p&gt;Implement the &lt;code&gt;FirmwareManagerDelegate&lt;\\\/code&gt; delegate to build UI screens showing the progress and result of the update.&lt;\\\/p&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Delegate Method&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareDownloadProgress(percent: Double)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The SDK is in the process of downloading the firmware.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateProgress(percent: Double)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The SDK is installing the update on the dock.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;applyingFirmwareUpdate()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The SDK is applying the update. The dock will reboot and reconnect.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateComplete()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Indicates the process has completed.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateFailure(error: AdyenPOSError)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Invoked when the firmware update fails with an associated error.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&lt;\\\/li&gt;\\n&lt;\\\/ol&gt;\\n&lt;p&gt;As an example, &lt;a href=\\&quot;\\\/pt\\\/point-of-sale\\\/mobile-ios\\\/understand#updating-usb-dock\\&quot;&gt;see the built-in UI screens&lt;\\\/a&gt;.&lt;\\\/p&gt;\\n&lt;h3 id=\\&quot;devicemanager-functions\\&quot;&gt;List of DeviceManager tools&lt;\\\/h3&gt;\\n&lt;p&gt;&lt;code&gt;DeviceManager&lt;\\\/code&gt; let you scan for card readers through Bluetooth device discovery, connect and disconnect a card reader, connect and disconnect a USB dock, get information about the currently connected card reader, get information about the currently connected USB dock, and manage firmware updates.&lt;\\\/p&gt;\\n&lt;p&gt;The following tables show the available DeviceManager functions, firmware update properties, and FirmwareManagerDelegate methods.&lt;\\\/p&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;DeviceManager function&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;connectedDevice: ConnectedDevice?&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The device that the manager is currently connected to.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;discoveredDevices: [Device]&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Devices discovered during the last (ongoing) discovery. Sorted by proximity (RSSI).&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;delegate: DeviceManagerDelegate?&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The delegate to handle card reader events.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;startDiscovery()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Starts scanning for nearby card readers.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;stopDiscovery()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Stops scanning for nearby card readers.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;knownDevices: [Device]&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Returns a list of previously connected devices.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;connect(to device: Device)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Connects to a card reader.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;disconnect()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Disconnects from the currently connected card reader.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;prepareDeviceForTransaction(device: ConnectedDevice)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Prepares the device for transaction. The configuration is updated and security checks are done if needed. When preparation is complete, &lt;code&gt;onDevicePreparationFinished&lt;\\\/code&gt; is called on the delegate. If an error has occurred, the delegate call contains the error.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareDelegate: FirmwareManagerDelegate?&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The delegate to handle firmware-related events. See the &lt;a href=\\&quot;#fmd-methods\\&quot;&gt;table with &lt;code&gt;FirmwareManagerDelegate&lt;\\\/code&gt; methods&lt;\\\/a&gt;.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateSummary: AvailableFirmwareUpdate?&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Checks if a firmware update is available for the card reader that is currently connected to the mobile device. Returns an &lt;code&gt;AvailableFirmwareUpdate&lt;\\\/code&gt; instance if an update is available, otherwise &lt;code&gt;nil&lt;\\\/code&gt;. Can throw errors if there is a problem with retrieving the firmware, no card reader is connected, or a general error occurs. See the &lt;a href=\\&quot;#afu-properties\\&quot;&gt;table with firmware update properties&lt;\\\/a&gt;.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;startFirmwareUpdate()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Starts the firmware update on the card reader that is currently connected to the mobile device. To receive &lt;a href=\\&quot;#fmd-methods\\&quot;&gt;progress updates&lt;\\\/a&gt;, the &lt;code&gt;firmwareManagerDelegate&lt;\\\/code&gt; must be set correctly. Throws an error if the delegate is not set, no updates are available, no card reader is connected, or if other errors occur during the process.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;connectedDock&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Returns the details of the connected dock.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;dockFirmwareUpdateSummary: AvailableDockFirmwareUpdate?&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Checks if a firmware update is available for the dock that is currently connected to the mobile device. Returns an &lt;code&gt;AvailableDockFirmwareUpdate&lt;\\\/code&gt; instance if an update is available, otherwise &lt;code&gt;nil&lt;\\\/code&gt;. Can throw errors if there is a problem with retrieving the firmware, no dock is connected, or a general error occurs. See the &lt;a href=\\&quot;#afu-properties\\&quot;&gt;table with firmware update properties&lt;\\\/a&gt;.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;startDockFirmwareUpdate()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Starts the firmware update on the dock that is currently connected to the mobile device. To receive &lt;a href=\\&quot;#fmd-methods\\&quot;&gt;progress updates&lt;\\\/a&gt;, the &lt;code&gt;FirmwareManagerDelegate&lt;\\\/code&gt; must be set correctly, otherwise an error is thrown when calling this function.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;AvailableFirmwareUpdate&lt;\\\/code&gt; or &lt;code&gt;AvailableDockFirmwareUpdate&lt;\\\/code&gt; property&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description &lt;a id=\\&quot;afu-properties\\&quot;&gt;&lt;\\\/a&gt;&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;requiredDate: Date?&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;The date when the firmware updates are required.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;requiresBluetoothConnection: Bool&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Indicates whether this update requires a Bluetooth connection to the mobile device in order to proceed. &lt;br&gt; Not included in &lt;code&gt;AvailableDockFirmwareProperties&lt;\\\/code&gt; for dock firmware updates.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&lt;table&gt;\\n&lt;thead&gt;\\n&lt;tr&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;FirmwareManagerDelegate&lt;\\\/code&gt; method&lt;\\\/th&gt;\\n&lt;th style=\\&quot;text-align: left;\\&quot;&gt;Description &lt;a id=\\&quot;fmd-methods\\&quot;&gt;&lt;\\\/a&gt;&lt;\\\/th&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/thead&gt;\\n&lt;tbody&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateProgress(percent: Double)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Invoked when the firmware update percentage increases.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareDownloadProgress(percent: Double)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Invoked when the firmware download percentage increases.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;applyingFirmwareUpdate()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Invoked when the firmware update is being applied to the connected device (card reader or dock).&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateComplete()&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Invoked when the firmware update has been completed.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;tr&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;&lt;code&gt;firmwareUpdateFailure(error: AdyenPOSError)&lt;\\\/code&gt;&lt;\\\/td&gt;\\n&lt;td style=\\&quot;text-align: left;\\&quot;&gt;Invoked when the firmware update fails with an associated error. &lt;code&gt;AdyenPOSError&lt;\\\/code&gt; describes the cause of the failure.&lt;\\\/td&gt;\\n&lt;\\\/tr&gt;\\n&lt;\\\/tbody&gt;\\n&lt;\\\/table&gt;\\n&quot;,&quot;altTitle&quot;:null,&quot;oldTabId&quot;:&quot;build_a_custom_ui_1_2&quot;,&quot;relation&quot;:&quot;&quot;}]\"\n            :should-update-when-url-changes='false'>\n        <\/tabs>\n    <\/div>\n<\/div>\n\n<h2 id=\"payment\">8. Handle a payment<\/h2>\n<p>In this step you add code to start a transaction with:<\/p>\n<ul>\n<li>\n<p>A <a href=\"\/pt\/point-of-sale\/design-your-integration\/terminal-api\">Terminal API<\/a> payment request.<\/p>\n<div class=\"sc-notice info\"><div>\n<p><strong>Tip<\/strong><br \/>\nTo help you create Terminal API requests, we provide a <strong>TerminalAPIKit for iOS<\/strong> on <a href=\"https:\/\/github.com\/Adyen\/adyen-terminal-api-ios\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">GitHub<\/a>. Installation and usage instructions are in the repository's README.<\/p>\n<\/div><\/div>\n<\/li>\n<li>\nThe card reader as the payment interface to use. <\/li>\n<li>\n<p>The presentation mode you want to use.<\/p>\n<\/li>\n<\/ul>\n<p>To enable the iOS Mobile SDK to handle transactions:<\/p>\n<ol>\n<li>\n<p>In your POS app, create a Terminal API payment request with:<\/p>\n<ul>\n<li>\n<p><code>MessageHeader.POIID<\/code>: the installation ID of the SDK.<\/p>\n<ul>\n<li>If you create the Terminal API diagnosis request in your POS app, use <code>PaymentService.installationId<\/code> as the <code>POIID<\/code> in the <a href=\"\/pt\/point-of-sale\/design-your-integration\/terminal-api#request-message-header\">MessageHeader<\/a> of the request.<\/li>\n<li>If you create the Terminal API diagnosis request in the backend, this uses the  <a href=\"https:\/\/docs.adyen.com\/api-explorer\/possdk\/latest\/post\/sessions#responses-201-installationId\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">installationId<\/a> from the <a href=\"#session\"><code>\/checkout\/possdk\/v68\/sessions<\/code> response<\/a>.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>The remaining <code>MessageHeader<\/code> parameters and the request body.<\/p>\n<div class=\"sc-notice info\"><div>\n<p>For details, see <a href=\"\/pt\/point-of-sale\/basic-tapi-integration\/make-a-payment\">Make a payment<\/a> and <a href=\"https:\/\/docs.adyen.com\/api-explorer\/terminal-api\/latest\/post\/payment\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PaymentRequest<\/a>.<\/p>\n<\/div><\/div>\n<\/li>\n<li>\n<p>If you want to be able to <a href=\"\/pt\/point-of-sale\/basic-tapi-integration\/refund-payment\/referenced#refund-offline-payment\">make a referenced refund of an offline payment when back online<\/a>, add the Card Reader ID as <a href=\"\/pt\/point-of-sale\/basic-tapi-integration\/refund-payment\/referenced#refund-offline-payment\">metadata in <code>SaleData.SaleToAcquirerData<\/code><\/a>.<\/p>\n<\/li>\n<\/ul>\n    <div class=\"faqs\">\n        <div class=\"adl-accordion adl-accordion--max-height-transition\" style=\"margin-bottom:24px\">\n                                                            <div class=\"adl-accordion__item\">\n                    <div tabindex=\"1\" role=\"question\" aria-expanded=\"true\" class=\"adl-accordion__header\" data-accordion=\"#add-the-card-reader-id-to-the-payment-request\">\n                        <i class=\"adl-accordion__toggle adl-icon-chevron-down\"><\/i>\n                        <div class=\"adl-accordion__title-wrapper\">\n                            <h3 class=\"adl-accordion__title no-anchor\">\n                                Add the card reader ID to the payment request <div class=\"faq-link-icon adl-icon adl-icon-chain\"><\/div>\n                            <\/h3>\n                                                    <\/div>\n                    <\/div>\n                    <div role=\"answer\" class=\"adl-accordion__content\">\n                        <p>To add the card reader ID to the payment request:<\/p>\n<ol>\n<li>\n<p>Look up the card reader ID of the connected card reader, using:<\/p>\n<pre><code class=\"language-swift\">if let connectedDevice = paymentService.deviceManager.connectedDevice,\nlet name = connectedDevice.name {\nlet fullName = \"\\(name)-\\(connectedDevice.serialNumber)\"\nprint(fullName) \/\/ e.g. \"NYC1-123456\"\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>In <code>SaleData.SaleToAcquirerData<\/code> include:<br>\n<code>metadata<\/code>: Must include a key, for example <code>cardReaderID<\/code>, with the card reader's unique identifier for example NYC1-123456, as its value.<br>\nPass the <code>SaleToAcquirerData<\/code> value in one of the following formats:<\/p>\n<ul>\n<li>\n<p>Option 1: a JSON object converted to a Base64 encoded string. <\/p>\n<div data-component-wrapper=\"code-sample\">\n<code-sample :title=\"'Example data element in JSON format'\" :id=\"''\" :code-data='[{\"language\":\"json\",\"tabTitle\":\"\",\"content\":\"{\\n    \\\"metadata\\\": {\\n        \\\"cardReaderID\\\": \\\"NYC1-123456\\\"\\n    }\\n}\"}]' :enable-copy-link-to-code-block=\"true\" :code-sample-card-size=\"'fullsize'\"><\/code-sample>\n<\/div>\n<p>Example JSON object converted to a Base64 encoded string:<\/p>\n<pre><code class=\"language-raw\">ewogICAgIm1ldGFkYXRhIjogewogICAgICAgICJjYXJkUmVhZGVySUQiOiAiTllDMS0xMjM0NTYiCiAgICB9Cn0= <\/code><\/pre>\n<\/li>\n<li>\n<p>Option 2: form-encoded key-value pairs (using <strong>&amp;<\/strong> as a separator). For example:<br>\n<code>metadata.cardReaderID=NYC1-123456<\/code><br>\nThe format that you use here, will also be the format of the <code>AdditionalResponse<\/code> that you receive.<\/p>\n<\/li>\n<\/ul>\n<p>Refer to <a href=\"\/pt\/point-of-sale\/add-data#base64-json\">Add information to a payment<\/a> to learn how to extract the cardReaderID from the <code>AdditionalResponse<\/code> in the payment response. <\/p><\/li><\/ol>\n                    <\/div>\n                <\/div>\n                    <\/div>\n    <\/div>\n\n<\/li>\n<li>\n<p>Create an instance of <code>Payment.Request<\/code> using <code>Payment.Request(data:)<\/code>, and pass the Terminal API payment request from your POS app or backend.<\/p>\n<pre><code class=\"language-swift\">let transaction = try Payment.Request(data: requestData)<\/code><\/pre>\n<\/li>\n<li>\n<p>Get a <code>PaymentInterface<\/code> from an instance of <code>PaymentService<\/code>, using  <code>PaymentService.getPaymentInterface(with: .cardReader)<\/code>. <\/p>\n<pre><code class=\"language-swift\">let paymentService = PaymentService(...)\nlet paymentInterface = try paymentService\n                        .getPaymentInterface(with: .cardReader)<\/code><\/pre>\n<\/li>\n<li>\n<p>Specify a <code>TransactionPresentationMode<\/code> value that matches the UI framework, SwiftUI or UIKit, of the POS app.<\/p>\n<table>\n<thead>\n<tr>\n<th>Value<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>viewModifier<\/code><\/td>\n<td>For use with a SwiftUI application. The UI is embedded in a <code>View<\/code> as a <code>ViewModifier<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>presentingViewController<\/code><\/td>\n<td>For use with a UIKit application. The UI is presented on top of the provided <code>UIViewController<\/code>.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a id=\"ui-parameters\"><\/a>Optionally use parameters to customize the user interface.<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Parameter<\/th>\n<th style=\"text-align: left;\">Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\"><code>logo<\/code><\/td>\n<td style=\"text-align: left;\">A bitmap image to show on your mobile device during the transaction flow. To ensure visibility in both dark mode and light mode, the bitmap image must have a transparent background. The logo is placed in a frame with a vertical height of 40 points and scaled to aspect ratio to fit in that frame.<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><code>successScreenTimeout<\/code><\/td>\n<td style=\"text-align: left;\">Indicates how long the SDK shows the screen that indicates the transaction succeeded. If not specified, this success screen is dismissed after four seconds. You can set a time in seconds as a Double with a minimum of 0.5&nbsp;seconds and a maximum of 4&nbsp;seconds.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Using <code>viewModifier<\/code> (SwiftUI)<\/h4>\n<p>If you use <code>TransactionPresentationMode<\/code> with <code>viewModifier<\/code>:<\/p>\n<ol>\n<li>\n<p>Set <code>presentationMode<\/code> as follows.<\/p>\n<pre><code class=\"language-swift\">let presentationMode: TransactionPresentationMode = .viewModifier<\/code><\/pre>\n<\/li>\n<li>\n<p>Apply the presentation mode on your SwiftUI view.<\/p>\n<pre><code class=\"language-swift\">Button(...) {\n   \/\/ code to start the transaction\n})\n.transactionModal(\n   with: {YOUR_INSTANCE_OF_PAYMENT_SERVICE}\n   logo: logo,\n   parameters: .init(successScreenTimeout: 2)\n)<\/code><\/pre>\n<\/li>\n<\/ol>\n<h4>Using <code>presentingViewController<\/code> (UIKit)<\/h4>\n<p>If you use <code>TransactionPresentationMode<\/code> with <code>presentingViewController(_:logo:parameters:)<\/code>, set <code>presentationMode<\/code> as follows.<\/p>\n<pre><code class=\"language-swift\">let presentationMode: TransactionPresentationMode = .presentingViewController(\n   rootViewController,\n   logo: logo,\n   parameters: .init(successScreenTimeout: 2)\n)<\/code><\/pre>\n<\/li>\n<li>\n<p>Invoke <code>PaymentService.performTransaction(with:paymentInterface:presentationMode:)<\/code> on your instance of <code>PaymentService<\/code>.<\/p>\n<pre><code class=\"language-swift\">let transactionResponse = await paymentService.performTransaction(\n   with: transaction,\n   paymentInterface: paymentInterface,\n   presentationMode: presentationMode\n)<\/code><\/pre>\n<p>The Mobile SDK checks for a session, starts the transaction, and shows screens on your mobile device to help the customer.<\/p>\n<\/li>\n<li>\n<p>Check the <code>paymentResponse<\/code>. This is the Terminal API response with the transaction result and the data you can use to generate a receipt, or with any <a href=\"\/pt\/point-of-sale\/error-scenarios\">errors<\/a>.<\/p>\n<\/li>\n<li>\n<p>Pass the <code>paymentResponse<\/code> to your POS app.<\/p>\n<\/li>\n<\/ol>\n<h2 id=\"refund\">9. Handle a refund<\/h2>\n<p>There are two types of refund: <a href=\"#referenced-refund\">referenced<\/a> and <a href=\"#unreferenced-refund\">unreferenced<\/a>. The main difference is that a referenced refund is connected to the original payment, and an unreferenced refund isn't. That makes unreferenced refunds a bit riskier. For an overview of the differences, see <a href=\"\/pt\/point-of-sale\/basic-tapi-integration\/refund-payment\">Refund a payment<\/a>.<\/p>\n<p>Refunds are usually <em>not<\/em> processed synchronously. When you send a request for a referenced or unreferenced refund, the Terminal API response only confirms we received the request. <\/p>\n<p>We inform you about the outcome of the refund asynchronously, through a webhook.<\/p>\n<ul>\n<li>For a referenced refund, we return a <strong>CANCEL_OR_REFUND<\/strong> webhook.<\/li>\n<li>For an unreferenced refund, we return a <strong>REFUND_WITH_DATA<\/strong> webhook.<\/li>\n<\/ul>\n<p>Depending on the card scheme and country\/region where the card is used, unreferenced refunds are sometimes processed synchronously. In that case the Terminal API response includes an <code>acquirerResponseCode<\/code> to indicate the outcome.<\/p>\n<p><\/p>\n<p>To learn the <a href=\"\/pt\/point-of-sale\/basic-tapi-integration\/refund-payment\/refund-webhooks\">outcome of a refund<\/a>, you need to set up webhooks.<\/p>\n<h3 id=\"referenced-refund\">Handle a referenced refund<\/h3>\n<p>The Terminal API request for a referenced refund is a reversal request. The SDK contains a dedicated function for this.<\/p>\n<p>In your iOS POS app, add code for the following steps:<\/p>\n<ol>\n<li>\n<p>Create a Terminal API reversal request with:<\/p>\n<ul>\n<li>\n<p><code>MessageHeader.POIID<\/code>: the installation ID of the SDK.<\/p>\n<ul>\n<li>If you create the Terminal API diagnosis request in your POS app, use <code>PaymentService.installationId<\/code> as the <code>POIID<\/code> in the <a href=\"\/pt\/point-of-sale\/design-your-integration\/terminal-api#request-message-header\">MessageHeader<\/a> of the request.<\/li>\n<li>If you create the Terminal API diagnosis request in the backend, this uses the  <a href=\"https:\/\/docs.adyen.com\/api-explorer\/possdk\/latest\/post\/sessions#responses-201-installationId\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">installationId<\/a> from the <a href=\"#session\"><code>\/checkout\/possdk\/v68\/sessions<\/code> response<\/a>.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>The remaining <code>MessageHeader<\/code> parameters and the request body.<\/p>\n<div class=\"sc-notice info\"><div>\n<p>For details, see <a href=\"\/pt\/point-of-sale\/basic-tapi-integration\/refund-payment\/referenced\">Referenced refund<\/a> and  <a href=\"https:\/\/docs.adyen.com\/api-explorer\/terminal-api\/latest\/post\/reversal\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ReversalRequest<\/a>.<\/p>\n<\/div><\/div>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Create an instance of <code>Reversal.Request<\/code> using <code>Reversal.Request(data:)<\/code>, and pass the Terminal API reversal request from your POS app or backend.<\/p>\n<pre><code class=\"language-swift\">let request = try Reversal.Request(data: requestData)<\/code><\/pre>\n<\/li>\n<li>\n<p>Invoke <code>PaymentService.performReversal(with:)<\/code> on your instance of <code>PaymentService<\/code>.<\/p>\n<pre><code class=\"language-swift\">let reversalResponse = await paymentService.performReversal(with: request)<\/code><\/pre>\n<p>The Mobile SDK now checks for a session, and starts the transaction.<\/p>\n<\/li>\n<li>\n<p>Check the <code>reversalResponse<\/code>. This is the Terminal API response with the transaction result and the data you can use to generate a receipt, or with any <a href=\"\/pt\/point-of-sale\/error-scenarios\">errors<\/a>.<\/p>\n<\/li>\n<li>\n<p>Pass the <code>reversalResponse<\/code> to your POS app.<\/p>\n<\/li>\n<\/ol>\n<h3 id=\"unreferenced-refund\">Handle an unreferenced refund<\/h3>\n<p>The Terminal API request for an unreferenced refund is a payment request with an additional parameter:<\/p>\n<ul>\n<li><code>PaymentData.PaymentType<\/code>: <strong>Refund<\/strong><\/li>\n<\/ul>\n<p>This means you can use the same code as for <a href=\"#payment\">handling a payment<\/a>. The only difference is the structure of the Terminal API payment request that you pass as the <code>requestData<\/code> to the <code>Payment.Request<\/code>.<\/p>\n<div class=\"sc-notice info\"><div>\n<p>For the structure of the Terminal API request, see <a href=\"\/pt\/point-of-sale\/basic-tapi-integration\/refund-payment\/unreferenced\">Unreferenced refund<\/a>.<\/p>\n<\/div><\/div>\n<h2 id=\"diagnosis\">10. Diagnose the device<\/h2>\n<p>We recommend implementing the Terminal API diagnosis request. This enables you to do the following:<\/p>\n<ul>\n<li>\n<p>Check if there are <strong>stored offline payments<\/strong> that have not been forwarded to Adyen yet. The SDK will try to go online and forward these transactions. Note that you do not need to send a diagnosis request to forward offline transactions, because forwarding happens automatically whenever the internet connection is restored after it had dropped.<\/p>\n<\/li>\n<li>\n<p>Check for <strong>security threats<\/strong> that would block transactions. If threats are detected that an operator can solve, the response includes information about the cause and solution of the problem.<\/p>\n<\/li>\n<li>\n<p>Check the <strong>expiry date of the SDK<\/strong> that is used on the mobile device. <a href=\"\/pt\/point-of-sale\/mobile-ios\/manage\/#keep-the-mobile-sdk-up-to-date\">Transactions will be blocked<\/a> if mandatory updates are not carried out.<\/p>\n<\/li>\n<\/ul>\n<p>Be aware that the diagnosis can take a while if the SDK succeeds in going online and there is a large number of stored offline payments that are forwarded.<\/p>\n<p>In your iOS POS app, add code for the following steps:<\/p>\n<ol>\n<li>\n<p>Create a Terminal API diagnosis request with:<\/p>\n<ul>\n<li>\n<p><code>MessageHeader.POIID<\/code>: the installation ID of the SDK.<\/p>\n<ul>\n<li>If you create the Terminal API diagnosis request in your POS app, use <code>PaymentService.installationId<\/code> as the <code>POIID<\/code> in the <a href=\"\/pt\/point-of-sale\/design-your-integration\/terminal-api#request-message-header\">MessageHeader<\/a> of the request.<\/li>\n<li>If you create the Terminal API diagnosis request in the backend, this uses the  <a href=\"https:\/\/docs.adyen.com\/api-explorer\/possdk\/latest\/post\/sessions#responses-201-installationId\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">installationId<\/a> from the <a href=\"#session\"><code>\/checkout\/possdk\/v68\/sessions<\/code> response<\/a>.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>The remaining <code>MessageHeader<\/code> parameters.<\/p>\n<\/li>\n<li>\n<p>The request body consisting of <code>DiagnosisRequest.HostDiagnosisFlag<\/code>: set to <strong>true<\/strong>, so that the SDK will try to forward any stored offline transactions and perform a security scan.<\/p>\n<\/li>\n<\/ul>\n<div class=\"sc-notice info\"><div>\n<p>For details, see <a href=\"\/pt\/point-of-sale\/diagnostics\/request-diagnosis#diagnosis-request-mobile\">Diagnose a Mobile SDK solution<\/a> and  <a href=\"https:\/\/docs.adyen.com\/api-explorer\/terminal-api\/latest\/post\/diagnosis\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">DiagnosisRequest<\/a>.<\/p>\n<\/div><\/div>\n<\/li>\n<li>\n<p>Call the <code>performDiagnosis<\/code> function, using the <code>request<\/code> parameter to pass the Terminal API diagnosis request.<\/p>\n<pre><code class=\"language-swift\">public func performDiagnosis(\n    with request: Diagnosis.Request\n) async -&gt; Diagnosis.Response {\n    await diagnosisPerformer.performDiagnosis(with: request)\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>When you get the Terminal API <code>DiagnosisResponse<\/code>, check the <code>Response.AdditionalResponse<\/code>:<\/p>\n<ul>\n<li>\n<p>See the <code>unconfirmedBatchCount<\/code> for the number of stored offline transactions that have not been forwarded to theplataforma de pagamentos da Adyen yet.<\/p>\n<\/li>\n<li>\n<p>Base64-decode the <code>storeAndForwardStatus<\/code> value for more information about offline transactions.<\/p>\n<\/li>\n<li>\n<p>Base64-decode the <code>attestationStatus<\/code> value for information about any security issues. If issues are detected that can be resolved by the end user, the resulting JSON object includes messages with the details. These are the same <a href=\"\/pt\/point-of-sale\/mobile-ios\/troubleshooting\/#error-messages\">error messages<\/a> that we show automatically on the end user's mobile device when these issues are detected during a transaction.<\/p>\n<\/li>\n<li>\n<p>See the <code>sdkExpiry<\/code> for the date when the installed SDK version expires.<\/p>\n<\/li>\n<\/ul>\n<div class=\"sc-notice info\"><div>\n<p>For a detailed explanation of the response, see <a href=\"\/pt\/point-of-sale\/diagnostics\/request-diagnosis#diagnosis-request-mobile\">Diagnose a Mobile SDK solution<\/a>.<\/p>\n<\/div><\/div>\n<\/li>\n<\/ol>\n<h2 id=\"clear-session-token\">11. (Optional) Clear the session token<\/h2>\n<p>There are several situations when you need to clear the existing session to remove all session information from your mobile device. When you have cleared the session, configuration updates are fetched and a new session is established when you start a new transaction or call the warm-up function.<\/p>\n<p>As a best practice, clear the session to:<\/p>\n<ul>\n<li><strong>Re-establish a session after switching between merchant accounts or stores in your POS app and your Customer Area<\/strong>. If the device is reassigned from store A to store B and a transaction is started there, on the Adyen side the transaction will continue to appear to belong to store A instead of store B. Clearing the session prevents this issue.<\/li>\n<li><strong>Force a refresh of the configuration<\/strong>. After clearing the session, the latest configuration is fetched and stored on your mobile device the next time the iOS Mobile SDK connects to the Adyen backend.<\/li>\n<li><strong>Test the session establishment flow in your POS app<\/strong>, specifically how it interacts with your and Adyen's backend to securely establish a session with the iOS Mobile SDK.<\/li>\n<\/ul>\n<p>To clear the session:<\/p>\n<ol>\n<li>Explicitly clear the communication session using  <code>PaymentService.resetSession()<\/code> .<\/li>\n<li><a href=\"#session\">Establish a new communication session<\/a>.<\/li>\n<\/ol>\n<h2>Other supported features<\/h2>\n<p>In addition to <a href=\"#payment\">payments<\/a>, <a href=\"#referenced-refund\">refunds<\/a>, and <a href=\"#diagnosis\">diagnosis<\/a>, the Mobile solutions support other (payment) features. These are the same features that are supported in Terminal API integrations using Adyen-provided payment terminals.<\/p>\n<p>For some features you need to add parameters to your Terminal API payment request, similar to <a href=\"#unreferenced-refund\">unreferenced refunds<\/a> described above. Other features only require enabling the feature for your Adyen account. You can find the details on the pages dedicated to those features. Where the details differ between an integration using payment terminals and a mobile solution, this is clearly indicated.<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Feature<\/th>\n<th style=\"text-align: center;\">Supported with Card reader iOS<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">Diagnosis<\/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<\/tr>\n<tr>\n<td style=\"text-align: left;\"><a href=\"\/pt\/point-of-sale\/partial-payments\/\">Partial authorization<\/a><\/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<\/tr>\n<tr>\n<td style=\"text-align: left;\">Payment<\/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<\/tr>\n<tr>\n<td style=\"text-align: left;\"><a href=\"\/pt\/point-of-sale\/pre-authorisation\/\">Pre-authorization<\/a><\/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<\/tr>\n<tr>\n<td style=\"text-align: left;\">Refund, referenced<\/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<\/tr>\n<tr>\n<td style=\"text-align: left;\">Refund, unreferenced<\/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<\/tr>\n<tr>\n<td style=\"text-align: left;\"><a href=\"\/pt\/point-of-sale\/offline-payment\/\">Store and forward<\/a> offline payments<\/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<\/tr>\n<tr>\n<td style=\"text-align: left;\"><a href=\"\/pt\/point-of-sale\/surcharge\/\">Surcharge<\/a><\/td>\n<td style=\"text-align: center;\"><img title=\"-x-\" alt=\"-x-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/x.png\" \/><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\"><a href=\"\/pt\/point-of-sale\/shopper-recognition\/tax-free-shopping\/\">Tax-free shopping<\/a><\/td>\n<td style=\"text-align: center;\"><img title=\"-x-\" alt=\"-x-\" class=\"smileys\" src=\"\/user\/data\/smileys\/emoji\/x.png\" \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Test your solution<\/h2>\n<p>To make test transactions:<\/p>\n<ol>\n<li>\n<p>Make sure you are using the test version of the Mobile SDK. <\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/developer.apple.com\/help\/app-store-connect\/test-in-app-purchases\/create-sandbox-apple-ids\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Create a Sandbox Apple ID<\/a>. This is needed to test Tap to Pay on iPhone in our test environment. <\/p>\n<\/li>\n<li>\n<p>Initiate a test transaction using the following Adyen point-of-sale test cards to complete the payment:<\/p>\n<ul>\n<li><a href=\"\/pt\/point-of-sale\/testing-pos-payments\/test-card-v3\/\">White-green test card<\/a><\/li>\n<li><a href=\"\/pt\/point-of-sale\/testing-pos-payments\/test-card-v2\/\">Blue-green test card<\/a> version <strong>2.4<\/strong> or later<\/li>\n<\/ul>\n<p>The instructions are the same for both cards; see either of the pages mentioned above.<\/p>\n<\/li>\n<\/ol>\n<h2>Go live<\/h2>\n<p>When you have finished testing your integration and are ready to go live:<\/p>\n<ol>\n<li>\n<p>If new to Adyen, get a <a href=\"\/pt\/get-started-with-adyen\/#apply-for-your-live-account\">live account<\/a>. You need to have access to your organization's live Customer Area to generate API credentials for the live environment.<\/p>\n<\/p>\n<\/li>\n<li>\n<p><a href=\"#get-live-sdk\">Get the live SDK<\/a>. You need to generate a new, live basic authentication credential exclusively for downloading the SDK.<\/p>\n<\/li>\n<li>\n<p><a href=\"#establish-a-live-session\">Use the live endpoint for establishing a session<\/a>. To access the live endpoint, you need to generate a new, live API key that is different from the API key used for downloading the SDK. <\/p>\n<\/li>\n<\/ol>\n<h3 id=\"get-live-sdk\">Get the live SDK<\/h3>\n<p>To pull in the live version of the SDK:<\/p>\n<ol>\n<li>Generate a new basic authentication credential in your <a href=\"https:\/\/ca-live.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">live Customer Area<\/a> and add it to your <code>.netrc<\/code> file.<\/li>\n<li>In your <code>.netrc<\/code> file, change the value for <code>machine<\/code> to <code>pos-mobile.cdn.adyen.com<\/code>.<\/li>\n<li>In your Xcode project or workspace, remove the TEST dependency and add the LIVE dependency using the <strong>URL<\/strong> <code>https:\/\/github.com\/Adyen\/adyen-pos-mobile-ios<\/code>.<\/li>\n<li>Add <code>AdyenPOSLIVE<\/code> to your app target that connects to the Adyen Live environment.<\/li>\n<\/ol>\n<div class=\"notices green\">\n<p>If your POS app requires the iOS Mobile SDK to be compatible with Objective-C:<\/p>\n<\/div>\n<ul>\n<li>Link the <code>ADYPOSLIVE<\/code> package product to your app target instead of <code>AdyenPOSLIVE<\/code>.<\/li>\n<\/ul>\n<h3>Establish a live session<\/h3>\n<p>When going live, you must change the <code>\/sessions<\/code> endpoint as well as the API key that you use to authenticate <code>\/sessions<\/code> requests.<\/p>\n<ul>\n<li>To access the live endpoint, generate a new API key from your <a href=\"https:\/\/ca-live.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">live Customer Area<\/a>.<\/li>\n<li>\n<p>The live endpoint URL contains a prefix which is unique to your company account, for example:<\/p>\n<p><code>https:\/\/{PREFIX}-checkout-live.adyenpayments.com\/checkout\/possdk\/v68\/sessions<\/code><\/p>\n<p>Get your <code>{PREFIX}<\/code> from your <a href=\"https:\/\/ca-live.adyen.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">live Customer Area<\/a> under <strong>Developers<\/strong> &gt; <strong>API URLs<\/strong> &gt; <strong>Prefix<\/strong>.<\/p>\n<\/li>\n<\/ul>\n<h2>Next steps<\/h2>\n<div class=\"next-steps\" id=\"next-steps\" >\n<a href=\"\/point-of-sale\/mobile-ios\/manage\" class=\"next-steps__step\" style=\"width:45%;\" target=\"_self\"><div class=\"next-steps__label\">required<\/div><p class=\"next-steps__body\"><div style=\"text-align: center;\"><img src=\"\/user\/themes\/adyen\/images\/illustrations\/settings.svg\"><h6 class=\"next-steps__title\">Manage your solution<\/h6><p>Make your solution available and keep the software up-to-date.<\/p><\/div><\/p><\/a><a href=\"\/point-of-sale\/mobile-ios\/checklists\" class=\"next-steps__step\" style=\"width:45%;\" target=\"_self\"><p class=\"next-steps__body\"><div style=\"text-align: center;\"><img src=\"\/user\/themes\/adyen\/images\/illustrations\/checkmark.svg\"><h6 class=\"next-steps__title\">Checklists<\/h6><p>Get a list of what needs to be done to get started and go live with a Mobile solution.<\/p><\/div><\/p><\/a><a href=\"\/point-of-sale\/mobile-ios\/troubleshooting\" class=\"next-steps__step\" style=\"width:45%;\" target=\"_self\"><p class=\"next-steps__body\"><div style=\"text-align: center;\"><img src=\"\/user\/themes\/adyen\/images\/illustrations\/close.svg\"><h6 class=\"next-steps__title\">Error handling<\/h6><p>Resolve errors that appear on the mobile iOS device.<\/p><\/div><\/p><\/a><a href=\"\/point-of-sale\/user-manuals\/nyc1\" class=\"next-steps__step\" style=\"width:45%;\" target=\"_self\"><p class=\"next-steps__body\"><div style=\"text-align: center;\"><p><img style=\"width: 45px;\" alt=\"RFID card icon\" src=\"\/user\/pages\/reuse\/image-library\/01.icons\/rfid-card\/rfid-card.svg?decoding=auto&amp;fetchpriority=auto\"><\/p><h6 class=\"next-steps__title\">Use the card reader<\/h6><p>Learn how to connect and operate the NYC1 card reader.<\/p><\/div><\/p><\/a><a href=\"\/point-of-sale\/user-manuals\/nyc1-with-dock\" class=\"next-steps__step\" style=\"width:45%;\" target=\"_self\"><p class=\"next-steps__body\"><div style=\"text-align: center;\"><p><img style=\"width: 45px;\" alt=\"RFID card icon\" src=\"\/user\/pages\/reuse\/image-library\/01.icons\/rfid-card\/rfid-card.svg?decoding=auto&amp;fetchpriority=auto\"><\/p><h6 class=\"next-steps__title\">Use the card reader with a dock<\/h6><p>Learn how to connect and operate the NYC1 card reader and NYC1 dock.<\/p><\/div><\/p><\/a><\/div>\n","url":"https:\/\/docs.adyen.com\/pt\/point-of-sale\/mobile-ios\/build\/card-reader","articleFields":{"description":"Integrate your POS app with the Adyen POS Mobile SDK for iOS to make mobile payments using a card reader.","search_tags":["Tap to Pay card reader"],"parameters":{"generic_sdk_name":"Mobile SDK","sdk_name":"iOS Mobile SDK","solution":"readeriOS","solution_name":"card reader on iPhone","platform":"iOS"},"type":"page","feedback_component":true,"filters_component":false,"decision_tree":"[]","page_id":"f0a135a3-b464-4c02-b267-cab8b480a8ce","last_edit_on":"22-12-2025 09:25"},"algolia":{"url":"https:\/\/docs.adyen.com\/pt\/point-of-sale\/mobile-ios\/build\/card-reader","title":"Card reader solution for iOS","content":"With our card reader solution you can accept mobile in-person payments using a card reader as the payment interface, and process these payments on the plataforma de pagamentos da Adyen.\nThe card reader is connected with an iOS mobile device through Bluetooth, or through USB using a dock. On the iOS mobile device, payment requests are initiated from a POS app. On the card reader, the customer can tap, insert, or swipe their card, or use a digital wallet like Apple Pay.\nRequirements\nBefore you begin, take into account the following requirements, limitations, and preparations.\n\n\n\nRequirement\nDescription\n\n\n\n\nIntegration type\nYour POS app must be integrated with Terminal API.\n\n\nAPI credentials\nYou need the following API credentials: To get the SDK, you must have an API credential with a basic authentication password and the Allow SDK download for POS developers role. To establish a communication session, you must have an API credential with an API key, a client key, and the Checkout webservice role.\n\n\nWebhooks\nTo learn the outcome of refunds, set up Standard webhooks (if this hasn't been done already).\n\n\nHardware\nYou need the following hardware: An iOS mobile device. See iOS system requirements for the full hardware and software requirements.A test NYC1 card reader and optionally an NYC1 dock. For PIN transactions your card reader needs to be an NYC1 model.\n\n\nLimitations\nCheck the countries\/regions, payment methods, and functionality that we support for card reader on iPhone.\n\n\nSetup steps\nBefore you begin: Order a test NYC1 card reader and a test card, and assign the reader to your store.If you want to disable PIN support for NYC1 card readers in the US from iOS Mobile SDK version 3.12.0 or later, contact our Support Team and ask them to disable PIN support on the company, merchant, or store level.\n\n\n\nHow it works\n\nTutorial and app\nHit the ground running with our integration tutorial and iOS sample app.\n\nTo build a card reader solution:\n\nAdd the iOS Mobile SDK to your project, using basic authentication.\n\nNote that for compatibility with Objective C, you need to prefix the public symbols with ADY.\n\nImplement a server-to-server API request to establish a secure communication session.\nIn your POS app, enable the transaction functionality of the SDK.\nFrom your POS app, call the warm-up function to speed up initiating transactions.\nIn your POS app, add permissions for pairing the mobile device with the card reader.\nGet an entitlement from Apple to suppress Apple Pay in your iOS POS app when your app is in the foreground. Configure your Xcode project accordingly.\nOptionally, you can configure the Mobile SDK to avoid reconnection delays between the card reader and the mobile device.\nYou enable the device management screens built into the Mobile SDK or build a custom UI for device management.\n\nIn your POS app, implement handling payments using the SDK.\nThis creates the following flow:\n\nYour iOS POS app creates a Terminal API payment request, or receives a Terminal API payment request from your backend.\nThe POS app passes the payment request to the iOS Mobile SDK.\nThe SDK passes the request to the Tap to Pay on iPhone component.\nWhen the customer completes the payment by tapping their card or mobile device on the iPhone, the SDK passes the Terminal API payment response to the POS app.\n\n\n\nIn your POS app, implement handling refunds and diagnosing the state of the SDK.\nIf the same device will be used at multiple locations, implement clearing the communication session.\n\n1. Add the SDK to your project\nYou can add the iOS Mobile SDK to your POS app using a Swift Package Manager remote package. To get access you need to have a basic authentication credential. You can share the basic authentication password with anybody in your team who needs to get the SDK or create multiple passwords for internal use.\n\nDo not share this password in any publicly accessible code or area where unauthorized users can find it.\n\nTo add the iOS Mobile SDK to your project:\n\n\nIn your Customer Area create a basic authentication credential with a password:\n\nGo to Developers &gt; API credentials, and select Create new credential.\nUnder Payments &gt; Credential type select Web service user and then select Create credential.\nUnder Server settings &gt; Authentication select the Basic auth tab and then select Generate password.\nSelect the copy icon  and save your basic authentication password in a secure location.\nGo to Permissions &gt; Roles &gt; POS, select Allow SDK download for POS developers, and deselect any other permissions and roles.\n\nContact Support Team if you don't see the Allow SDK download for POS developers role.\n\nSelect Save changes.\n\n\n\nSave the basic authentication password in a .netrc file:\n\n\nCheck if you already have a .netrc file in your home directory. If you do not have it, create a plain text file with that name in your home directory (~\/.netrc).\n\n\nAdd the following content to your .netrc file, where login is the API credential username, for example ws_12345@Company.[YourCompanyAccount], and password is the basic authentication password.\n\n\n\n\n\n\nMake sure that the .netrc file has the following file system permission: 0600.\n\n\n\nAdd the POS Mobile SDK as a package dependency to your Xcode project:\n\nIt is not possible to use TEST and LIVE environments from a single app target. You need to setup your Xcode project to have separate app targets for Test and for Live. Each target needs to link to the respective AdyenPOS SDK version for its environment: AdyenPOSTest and AdyenPOSLive.\n\n\n\nIn your Xcode project or workspace, go to File &gt; Add Package Dependencies.\n\n\nEnter the URL https:\/\/github.com\/Adyen\/adyen-pos-mobile-ios-test and select your preferred Dependency Rule.\n\n\nSelect Add Package, and after the SDK is loaded add AdyenPOSTEST to your app target that connects to the Adyen test environment.\n\n\nSelect Add Package.\n\n\n\n\nIn your code, add import AdyenPOS, or for Objective-C compatibility add #import \"ADYPOS\/ADYPOS.h\".\n\n\nCompatibility with Objective-C\nIf your POS app requires the iOS Mobile SDK to be compatible with Objective-C:\n\nLink the ADYPOSTEST package product to your app target instead of AdyenPOSTEST.\nLink the ADYPOSLIVE package product to your app target instead of AdyenPOSLIVE.\n\nIt is not possible to use TEST and LIVE environments from a single app target. Each app target must connect to a specific environment.\n\n\nThe integration process is the same. The only difference is that the public symbols are prefixed with ADY. For example, PaymentService is called  ADYPaymentService.\n2. Establish a session\nThe Mobile SDK has to communicate in a secure way with the plataforma de pagamentos da Adyen. For more information, see Communication session. \nTo authenticate your server-to-server API request for establishing a communication session, you need to have an Adyen API credential in your test Customer Area. This credential must have a client key and an API key with the following role:\n\nCheckout webservice role. This role is assigned by default when the API key is created.\nTo add a client key to an existing API credential, create a client key as follows:\n\nLog in to your Customer Area.\nGo to Developers &gt; API credentials, and select the credential username for your integration, for example ws@Company.[YourCompanyAccount].\nUnder Client settings &gt; Authentication select the Client key tab.\nSelect Generate client key.\n\nSelect Save changes.\n\nThe client key is part of the setup but is not used later on. Therefore, you do not need to specify allowed origins, and you do not need to save the client key in your system.\n\n\n\nTo let your backend establish a session, use the regular endpoint, or the dedicated endpoint for payment facilitators.\n\nRegular endpoint:  \/checkout\/possdk\/v68\/sessions\nPayment facilitator endpoint: \/softposconfig\/v3\/auth\/certificate\n\n\n\n    \n        \n        \n    \n\n\n3. Enable transactions\nTo enable the payments functionality of the Mobile SDK:\n\n\nIn your POS app, implement the PaymentServiceDelegate protocol. Below is an example of how you could do that.\nstruct SessionsResponse: Decodable {\n    let sdkData: String\n}\n\nclass MyPaymentServiceDelegate: PaymentServiceDelegate {\n    internal func register(\n        with setupToken: String\n    ) async throws -&gt; String {\n        \/\/\/ Make a call to your backend to trigger a `\/checkout\/possdk\/v68\/sessions` request, specifying the `setupToken` provided by the SDK.\n        let request = URLRequest(url: URL(string: \"{ADDRESS_OF_YOUR_BACKEND_API}\")!)\n        let (data, _) = try await URLSession.shared.data(for: request)\n        let response = try JSONDecoder().decode(SessionsResponse.self, from: data)\n        return response.sdkData\n    }\n}\nThe actual structure of the SessionsResponse depends on your backend implementation.\n\n\nCreate an instance of PaymentService with the PaymentService(delegate:) initializer and pass the delegate object. Make sure that you keep a strong reference to the payment service instance so that it is retained for the duration of the transaction. Also make sure your delegate is strongly referenced, because the PaymentService keeps a weak reference to the delegate.\nlet paymentService = PaymentService(delegate: myPaymentServiceDelegate)\n\n\nMake sure that the PaymentServiceDelegate can provide new sdkData at any time.\nIf there is no session or the session has expired, the delegate is called using the PaymentServiceDelegate.register(with:) callback. Using the provided setupToken you need to get the sdkData through your backend and return it. For instructions, see Establish a session.\n\n\nOptional. Verify that the callback works, by calling the warm-up function.\n\nThe warm-up function checks for a session and any configuration changes, and prepares the proximity reader on the iPhone. \n\ntry await paymentService.warmUp()\n\n\n4. Use the warm-up function\nTo speed up initiating transactions, you can use the warm-up function. This function checks for a session and any configuration changes\nAs a best practice, call the warm-up function:\n\nWhen the POS app starts. In other words, as soon as the app has the active state.\nWhen the POS app returns to the active state after running in the background.\n\nTo call the warm-up function:\ntry await paymentService.warmUp()\n\nSimilar to the warm-up function, you can optionally prepare the card reader to perform hardware configuration updates and security checks outside the transaction flow. \n\n5. Configure your POS app\nFor your card reader solution you need to configure your POS app to:\n\nManage pairing permissions.\nManage USB permissions.\nSuppress Apple Pay in your POS app.\n\nManage pairing permissions\nYour iOS POS app needs to have certain permissions for pairing the mobile device with the card reader.\n\nIn the Info.plist of your POS app, add the following keys with an appropriate explanation:\n\n\n  NSBluetoothAlwaysUsageDescription\n: this enables setting up a Bluetooth pairing between the mobile device and the card reader.\n\n  NSCameraUsageDescription\n: this enables using the camera of the mobile device to scan the barcode of the card reader. Barcode scanning is one of the ways to select a card reader for pairing.\n\n\nManage USB permissions\nIf you are using the NYC1 dock:\n\n\nAdd the following key to the Info.plist of your POS app:\n\n\n  UISupportedExternalAccessoryProtocols\n: set this to com.adyen.dock.\n\n\n\nIf you are going to submit your application to the App Store, your Review Notes need to provide a Made for iPhone\/iPad Product Plan ID (MFi PPID). To get this MFi PPID, provide your Adyen contact with the following information:\n\nThe exact app name as it appears in the App Store.\nThe app version number.\nWhether it is an update to an existing app, or a new app.\nThe app bundle ID.\nExternal Accessory protocol(s) supported by this app.\nA description of app including a general functions overview of the software and its key features.\n\nWe will then allowlist your application in the Adyen MFi portal and share the required MFi PPID.\n\n\nSuppress Apple Pay\n\nTo accept payments from customers, you may need to suppress Apple Pay on the device that runs your mobile POS app.\n\nIt is possible that Apple Pay is enabled on the Apple device that runs your iOS POS app. For example, if staff use their personal iPhone. When a card reader is near, the device running the POS app tries to make the payment using the Apple Pay passes that are on the device.\nTo prevent this from happening, you must suppress Apple Pay in your iOS POS app when your app is in the foreground.\n\nContact Apple Pay at apple-pay-inquiries@apple.com and ask for an entitlement to suppress Apple Pay.\nWhen you receive confirmation that the entitlement was granted, add the entitlement to your provisioning profile on the Apple developer website.\nIn Xcode, in the Signing &amp; Capabilities settings, add the com.apple.developer.passkit.pass-presentation-suppression  key to the .entitlements file for your POS app.\n\nIn your POS app, call requestAutomaticPassPresentationSuppression.\nThis method automatically switches between disabling Apple Pay when the POS app is in the foreground, and enabling Apple Pay when the POS app is in the background.\n\n\n6. (Optional) Avoid delays\nYou can avoid delays and speed up the transaction by:\n\nWaking up the card reader after it has gone to sleep.\nPreparing the card reader outside a transaction flow with configuration and security checks.\n\nWake up the card reader\nThe card reader goes to sleep after about five minutes. When you start a transaction after the reader has gone to sleep, there is a slight delay while the mobile device reconnects to the last connected reader. To avoid this delay, you can take either of the following measures:\n\nBefore starting the transaction, wake up the card reader by calling the DeviceManager connect function.\nRegularly refresh the connection between the mobile device and the card reader by implementing a timer that calls the connect function every couple of minutes.\n\nBe aware that implementing a timer can significantly decrease the battery life of the card reader.\n\n\nCall the connect method as follows, where viewModel is a class that contains an instance of the SDK's PaymentService (for an example, see our sample app):\nButton(\"Connect to last known reader\") {\n    if let device = viewModel.paymentService.deviceManager.knownDevices.first {\n        viewModel.paymentService.deviceManager.connect(to: device)\n    }\n}\nPrepare the card reader for transaction\nWhen you start a transaction, the Mobile SDK connects with the card reader through Bluetooth to check the reader's configuration. If the configuration is not up to date, the Mobile SDK sends the latest configuration files to the reader. This can take up to to 30 seconds. Additionally, the Mobile SDK performs a security check every 24 hours. To avoid a delay during the transaction flow, you can prepare the card reader by running these checks outside the transaction flow.\nIt is possible to start a transaction while the card reader preparation is running. There can be a short delay during the transaction while any remaining checks and configuration updates are completed.\nWe recommend preparing the device for transaction every 24 hours or when the configuration has changed.\nTo prepare the device outside a transaction flow:\n\n\nCall the DeviceManager prepareDeviceForTransaction function  as follows, where the connectedDevice is the card reader to prepare.\n\/\/ Register delegate\npaymentService.deviceManager.delegate = self\n\n\/\/ Start device preparation\nif let connectedDevice = paymentService.deviceManager.connectedDevice {\n  paymentService.deviceManager.prepareDeviceForTransaction(connectedDevice)\n}\n\nWhen the preparation of the card reader is finished, the deviceManager delegate is called with onDevicePreparationFinished or an \n  error\n message.\n\/\/ Called when preparation finished\nfunc onDevicePreparationFinished(with error: Error?, by manager: DeviceManager) {\n\/\/ Handle result of preparation\n}\n\n7. Manage the Device Manager UI\nTo use the card reader, operators need to:\n\nConnect the mobile device with the card reader through Bluetooth pairing, or through USB using a dock.\nView an overview of card readers. For example, to switch to a different card reader.\nView details of the card reader they are using. For example, to check the battery charge level.\nUpdate the firmware of the card reader or the dock they are using.\n\nTo handle these tasks, the SDK provides device management functions that enable you to either:\n\nUse the built-in UI.\nBuild a custom UI.\n\n\n\n    \n        \n        \n    \n\n\n8. Handle a payment\nIn this step you add code to start a transaction with:\n\n\nA Terminal API payment request.\n\nTip\nTo help you create Terminal API requests, we provide a TerminalAPIKit for iOS on GitHub. Installation and usage instructions are in the repository's README.\n\n\n\nThe card reader as the payment interface to use. \n\nThe presentation mode you want to use.\n\n\nTo enable the iOS Mobile SDK to handle transactions:\n\n\nIn your POS app, create a Terminal API payment request with:\n\n\nMessageHeader.POIID: the installation ID of the SDK.\n\nIf you create the Terminal API diagnosis request in your POS app, use PaymentService.installationId as the POIID in the MessageHeader of the request.\nIf you create the Terminal API diagnosis request in the backend, this uses the  installationId from the \/checkout\/possdk\/v68\/sessions response.\n\n\n\nThe remaining MessageHeader parameters and the request body.\n\nFor details, see Make a payment and PaymentRequest.\n\n\n\nIf you want to be able to make a referenced refund of an offline payment when back online, add the Card Reader ID as metadata in SaleData.SaleToAcquirerData.\n\n\n    \n        \n                                                            \n                    \n                        \n                        \n                            \n                                Add the card reader ID to the payment request \n                            \n                                                    \n                    \n                    \n                        To add the card reader ID to the payment request:\n\n\nLook up the card reader ID of the connected card reader, using:\nif let connectedDevice = paymentService.deviceManager.connectedDevice,\nlet name = connectedDevice.name {\nlet fullName = \"\\(name)-\\(connectedDevice.serialNumber)\"\nprint(fullName) \/\/ e.g. \"NYC1-123456\"\n}\n\n\nIn SaleData.SaleToAcquirerData include:\nmetadata: Must include a key, for example cardReaderID, with the card reader's unique identifier for example NYC1-123456, as its value.\nPass the SaleToAcquirerData value in one of the following formats:\n\n\nOption 1: a JSON object converted to a Base64 encoded string. \n\n\n\nExample JSON object converted to a Base64 encoded string:\newogICAgIm1ldGFkYXRhIjogewogICAgICAgICJjYXJkUmVhZGVySUQiOiAiTllDMS0xMjM0NTYiCiAgICB9Cn0= \n\n\nOption 2: form-encoded key-value pairs (using &amp; as a separator). For example:\nmetadata.cardReaderID=NYC1-123456\nThe format that you use here, will also be the format of the AdditionalResponse that you receive.\n\n\nRefer to Add information to a payment to learn how to extract the cardReaderID from the AdditionalResponse in the payment response. \n                    \n                \n                    \n    \n\n\n\nCreate an instance of Payment.Request using Payment.Request(data:), and pass the Terminal API payment request from your POS app or backend.\nlet transaction = try Payment.Request(data: requestData)\n\n\nGet a PaymentInterface from an instance of PaymentService, using  PaymentService.getPaymentInterface(with: .cardReader). \nlet paymentService = PaymentService(...)\nlet paymentInterface = try paymentService\n                        .getPaymentInterface(with: .cardReader)\n\n\nSpecify a TransactionPresentationMode value that matches the UI framework, SwiftUI or UIKit, of the POS app.\n\n\n\nValue\nDescription\n\n\n\n\nviewModifier\nFor use with a SwiftUI application. The UI is embedded in a View as a ViewModifier.\n\n\npresentingViewController\nFor use with a UIKit application. The UI is presented on top of the provided UIViewController.\n\n\n\nOptionally use parameters to customize the user interface.\n\n\n\nParameter\nDescription\n\n\n\n\nlogo\nA bitmap image to show on your mobile device during the transaction flow. To ensure visibility in both dark mode and light mode, the bitmap image must have a transparent background. The logo is placed in a frame with a vertical height of 40 points and scaled to aspect ratio to fit in that frame.\n\n\nsuccessScreenTimeout\nIndicates how long the SDK shows the screen that indicates the transaction succeeded. If not specified, this success screen is dismissed after four seconds. You can set a time in seconds as a Double with a minimum of 0.5&nbsp;seconds and a maximum of 4&nbsp;seconds.\n\n\n\nUsing viewModifier (SwiftUI)\nIf you use TransactionPresentationMode with viewModifier:\n\n\nSet presentationMode as follows.\nlet presentationMode: TransactionPresentationMode = .viewModifier\n\n\nApply the presentation mode on your SwiftUI view.\nButton(...) {\n   \/\/ code to start the transaction\n})\n.transactionModal(\n   with: {YOUR_INSTANCE_OF_PAYMENT_SERVICE}\n   logo: logo,\n   parameters: .init(successScreenTimeout: 2)\n)\n\n\nUsing presentingViewController (UIKit)\nIf you use TransactionPresentationMode with presentingViewController(_:logo:parameters:), set presentationMode as follows.\nlet presentationMode: TransactionPresentationMode = .presentingViewController(\n   rootViewController,\n   logo: logo,\n   parameters: .init(successScreenTimeout: 2)\n)\n\n\nInvoke PaymentService.performTransaction(with:paymentInterface:presentationMode:) on your instance of PaymentService.\nlet transactionResponse = await paymentService.performTransaction(\n   with: transaction,\n   paymentInterface: paymentInterface,\n   presentationMode: presentationMode\n)\nThe Mobile SDK checks for a session, starts the transaction, and shows screens on your mobile device to help the customer.\n\n\nCheck the paymentResponse. This is the Terminal API response with the transaction result and the data you can use to generate a receipt, or with any errors.\n\n\nPass the paymentResponse to your POS app.\n\n\n9. Handle a refund\nThere are two types of refund: referenced and unreferenced. The main difference is that a referenced refund is connected to the original payment, and an unreferenced refund isn't. That makes unreferenced refunds a bit riskier. For an overview of the differences, see Refund a payment.\nRefunds are usually not processed synchronously. When you send a request for a referenced or unreferenced refund, the Terminal API response only confirms we received the request. \nWe inform you about the outcome of the refund asynchronously, through a webhook.\n\nFor a referenced refund, we return a CANCEL_OR_REFUND webhook.\nFor an unreferenced refund, we return a REFUND_WITH_DATA webhook.\n\nDepending on the card scheme and country\/region where the card is used, unreferenced refunds are sometimes processed synchronously. In that case the Terminal API response includes an acquirerResponseCode to indicate the outcome.\n\nTo learn the outcome of a refund, you need to set up webhooks.\nHandle a referenced refund\nThe Terminal API request for a referenced refund is a reversal request. The SDK contains a dedicated function for this.\nIn your iOS POS app, add code for the following steps:\n\n\nCreate a Terminal API reversal request with:\n\n\nMessageHeader.POIID: the installation ID of the SDK.\n\nIf you create the Terminal API diagnosis request in your POS app, use PaymentService.installationId as the POIID in the MessageHeader of the request.\nIf you create the Terminal API diagnosis request in the backend, this uses the  installationId from the \/checkout\/possdk\/v68\/sessions response.\n\n\n\nThe remaining MessageHeader parameters and the request body.\n\nFor details, see Referenced refund and  ReversalRequest.\n\n\n\n\n\nCreate an instance of Reversal.Request using Reversal.Request(data:), and pass the Terminal API reversal request from your POS app or backend.\nlet request = try Reversal.Request(data: requestData)\n\n\nInvoke PaymentService.performReversal(with:) on your instance of PaymentService.\nlet reversalResponse = await paymentService.performReversal(with: request)\nThe Mobile SDK now checks for a session, and starts the transaction.\n\n\nCheck the reversalResponse. This is the Terminal API response with the transaction result and the data you can use to generate a receipt, or with any errors.\n\n\nPass the reversalResponse to your POS app.\n\n\nHandle an unreferenced refund\nThe Terminal API request for an unreferenced refund is a payment request with an additional parameter:\n\nPaymentData.PaymentType: Refund\n\nThis means you can use the same code as for handling a payment. The only difference is the structure of the Terminal API payment request that you pass as the requestData to the Payment.Request.\n\nFor the structure of the Terminal API request, see Unreferenced refund.\n\n10. Diagnose the device\nWe recommend implementing the Terminal API diagnosis request. This enables you to do the following:\n\n\nCheck if there are stored offline payments that have not been forwarded to Adyen yet. The SDK will try to go online and forward these transactions. Note that you do not need to send a diagnosis request to forward offline transactions, because forwarding happens automatically whenever the internet connection is restored after it had dropped.\n\n\nCheck for security threats that would block transactions. If threats are detected that an operator can solve, the response includes information about the cause and solution of the problem.\n\n\nCheck the expiry date of the SDK that is used on the mobile device. Transactions will be blocked if mandatory updates are not carried out.\n\n\nBe aware that the diagnosis can take a while if the SDK succeeds in going online and there is a large number of stored offline payments that are forwarded.\nIn your iOS POS app, add code for the following steps:\n\n\nCreate a Terminal API diagnosis request with:\n\n\nMessageHeader.POIID: the installation ID of the SDK.\n\nIf you create the Terminal API diagnosis request in your POS app, use PaymentService.installationId as the POIID in the MessageHeader of the request.\nIf you create the Terminal API diagnosis request in the backend, this uses the  installationId from the \/checkout\/possdk\/v68\/sessions response.\n\n\n\nThe remaining MessageHeader parameters.\n\n\nThe request body consisting of DiagnosisRequest.HostDiagnosisFlag: set to true, so that the SDK will try to forward any stored offline transactions and perform a security scan.\n\n\n\nFor details, see Diagnose a Mobile SDK solution and  DiagnosisRequest.\n\n\n\nCall the performDiagnosis function, using the request parameter to pass the Terminal API diagnosis request.\npublic func performDiagnosis(\n    with request: Diagnosis.Request\n) async -&gt; Diagnosis.Response {\n    await diagnosisPerformer.performDiagnosis(with: request)\n}\n\n\nWhen you get the Terminal API DiagnosisResponse, check the Response.AdditionalResponse:\n\n\nSee the unconfirmedBatchCount for the number of stored offline transactions that have not been forwarded to theplataforma de pagamentos da Adyen yet.\n\n\nBase64-decode the storeAndForwardStatus value for more information about offline transactions.\n\n\nBase64-decode the attestationStatus value for information about any security issues. If issues are detected that can be resolved by the end user, the resulting JSON object includes messages with the details. These are the same error messages that we show automatically on the end user's mobile device when these issues are detected during a transaction.\n\n\nSee the sdkExpiry for the date when the installed SDK version expires.\n\n\n\nFor a detailed explanation of the response, see Diagnose a Mobile SDK solution.\n\n\n\n11. (Optional) Clear the session token\nThere are several situations when you need to clear the existing session to remove all session information from your mobile device. When you have cleared the session, configuration updates are fetched and a new session is established when you start a new transaction or call the warm-up function.\nAs a best practice, clear the session to:\n\nRe-establish a session after switching between merchant accounts or stores in your POS app and your Customer Area. If the device is reassigned from store A to store B and a transaction is started there, on the Adyen side the transaction will continue to appear to belong to store A instead of store B. Clearing the session prevents this issue.\nForce a refresh of the configuration. After clearing the session, the latest configuration is fetched and stored on your mobile device the next time the iOS Mobile SDK connects to the Adyen backend.\nTest the session establishment flow in your POS app, specifically how it interacts with your and Adyen's backend to securely establish a session with the iOS Mobile SDK.\n\nTo clear the session:\n\nExplicitly clear the communication session using  PaymentService.resetSession() .\nEstablish a new communication session.\n\nOther supported features\nIn addition to payments, refunds, and diagnosis, the Mobile solutions support other (payment) features. These are the same features that are supported in Terminal API integrations using Adyen-provided payment terminals.\nFor some features you need to add parameters to your Terminal API payment request, similar to unreferenced refunds described above. Other features only require enabling the feature for your Adyen account. You can find the details on the pages dedicated to those features. Where the details differ between an integration using payment terminals and a mobile solution, this is clearly indicated.\n\n\n\nFeature\nSupported with Card reader iOS\n\n\n\n\nDiagnosis\n\n\n\nPartial authorization\n\n\n\nPayment\n\n\n\nPre-authorization\n\n\n\nRefund, referenced\n\n\n\nRefund, unreferenced\n\n\n\nStore and forward offline payments\n\n\n\nSurcharge\n\n\n\nTax-free shopping\n\n\n\n\nTest your solution\nTo make test transactions:\n\n\nMake sure you are using the test version of the Mobile SDK. \n\n\nCreate a Sandbox Apple ID. This is needed to test Tap to Pay on iPhone in our test environment. \n\n\nInitiate a test transaction using the following Adyen point-of-sale test cards to complete the payment:\n\nWhite-green test card\nBlue-green test card version 2.4 or later\n\nThe instructions are the same for both cards; see either of the pages mentioned above.\n\n\nGo live\nWhen you have finished testing your integration and are ready to go live:\n\n\nIf new to Adyen, get a live account. You need to have access to your organization's live Customer Area to generate API credentials for the live environment.\n\n\n\nGet the live SDK. You need to generate a new, live basic authentication credential exclusively for downloading the SDK.\n\n\nUse the live endpoint for establishing a session. To access the live endpoint, you need to generate a new, live API key that is different from the API key used for downloading the SDK. \n\n\nGet the live SDK\nTo pull in the live version of the SDK:\n\nGenerate a new basic authentication credential in your live Customer Area and add it to your .netrc file.\nIn your .netrc file, change the value for machine to pos-mobile.cdn.adyen.com.\nIn your Xcode project or workspace, remove the TEST dependency and add the LIVE dependency using the URL https:\/\/github.com\/Adyen\/adyen-pos-mobile-ios.\nAdd AdyenPOSLIVE to your app target that connects to the Adyen Live environment.\n\n\nIf your POS app requires the iOS Mobile SDK to be compatible with Objective-C:\n\n\nLink the ADYPOSLIVE package product to your app target instead of AdyenPOSLIVE.\n\nEstablish a live session\nWhen going live, you must change the \/sessions endpoint as well as the API key that you use to authenticate \/sessions requests.\n\nTo access the live endpoint, generate a new API key from your live Customer Area.\n\nThe live endpoint URL contains a prefix which is unique to your company account, for example:\nhttps:\/\/{PREFIX}-checkout-live.adyenpayments.com\/checkout\/possdk\/v68\/sessions\nGet your {PREFIX} from your live Customer Area under Developers &gt; API URLs &gt; Prefix.\n\n\nNext steps\n\nrequiredManage your solutionMake your solution available and keep the software up-to-date.ChecklistsGet a list of what needs to be done to get started and go live with a Mobile solution.Error handlingResolve errors that appear on the mobile iOS device.Use the card readerLearn how to connect and operate the NYC1 card reader.Use the card reader with a dockLearn how to connect and operate the NYC1 card reader and NYC1 dock.\n","type":"page","locale":"pt","boost":16,"hierarchy":{"lvl0":"Home","lvl1":"Terminais","lvl2":"iOS Mobile solutions","lvl3":"Build your iOS Mobile solution","lvl4":"Card reader solution for iOS"},"hierarchy_url":{"lvl0":"https:\/\/docs.adyen.com\/pt","lvl1":"https:\/\/docs.adyen.com\/pt\/point-of-sale","lvl2":"https:\/\/docs.adyen.com\/pt\/point-of-sale\/mobile-ios","lvl3":"https:\/\/docs.adyen.com\/pt\/point-of-sale\/mobile-ios\/build","lvl4":"\/pt\/point-of-sale\/mobile-ios\/build\/card-reader"},"levels":5,"category":"In-person payments","category_color":"green","tags":["Tap to Pay card reader"]}}
