Beta Release
This is pre-release documentation for an API in public beta and is subject to change.
Terminal API

Integrate with Square Terminal

Use the Square Terminal and Devices APIs to integrate Square Terminal with a point-of-sale (POS) app.

This guide walks you through the development steps necessary to integrate a third-party POS app with a Square Terminal. At a high level, you will learn about:

  • OAuth permissions needed to call Square Terminals and Devices APIs.

  • Pairing and unpairing a Square Terminal.

  • Requesting a Square Terminal checkout for payment.

  • Monitoring the status of a checkout request.

The Terminals API cannot be used to refund payments collected with Square Terminal. Instead, refund payments using the Square Refunds API. To learn about managing payments made with Square Terminal, see Payments and Refunds Overview.

Register your POS app and set up webhooks
Permalink Get a link to this section

Before you can integrate the Square Terminals and Devices APIs, you need to complete the following tasks:

The app registration allows you to get the access tokens you need to call Square APIs. If you use OAuth tokens, use the Developer Dashboard to test your OAuth flow in the Square Sandbox.

Square sends webhook notifications with each status update for a Square Terminal pairing request and for Square Terminal checkout request status update. If you add listening endpoints for these webhook notifications, you will avoid polling a Square server to get the current status of either request. The app webhook endpoint should listen for the following notifications:

  • device.code.paired - Notifies of a pairing completion.

  • terminal.checkout.created - Acknowledges a new terminal checkout.

  • terminal.checkout.updated - Notifies of a checkout status change.

The webhook payload for device.code.paired is an instance of DeviceCode with the current state of the object.

The webhook payload for the terminal.checkout notifications is an instance of the TerminalCheckout whose properties have changed as Square Terminal processes the checkout.

Learn about OAuth permissions for Square Terminal
Permalink Get a link to this section

When setting up your OAuth flow, request the minimum permissions necessary to pair a Square Terminal and request a checkout. Doing so might increase adoption of your app and reduce your liability.

The following are the minimum permissions you need to request:

  • DEVICE_CREDENTIAL_MANAGEMENT

  • MERCHANT_PROFILE_READ

  • PAYMENTS_READ

  • PAYMENTS_WRITE

When sellers sign in to an integrated POS app, they should be redirected to a URL as shown in the following example:

https://connect.squareup.com/oauth2/authorize?client_id=YOUR_APP_ID&scope=DEVICE_CREDENTIAL_MANAGEMENT,MERCHANT_PROFILE_READ,PAYMENTS_READ,PAYMENTS_WRITE

The Square authorization page asks sellers to accept the POS app request for access to their Square Terminal credential cache, access to their merchant profile, and read/write access to payments in their Square account.

Important

If you are building an app for accounts other than your own, use the OAuth API to generate tokens for each of your customers. They will each create and use their own device codes to put the Terminal into Connected Mode.

Pair a POS client with a Square Terminal
Permalink Get a link to this section

If you have not set up your Square Terminal for testing code in development, you should complete the setup before proceeding with this guide.

Did you know?

While your app is in development, you can use the Sandbox test values for Terminal API to get a sandbox device ID that simulates a Square Terminal.

A seller might have more than one location where Square Terminals are used. When pairing a Square Terminal, the seller must pick the location of the Square Terminal to be paired. Before a POS app can use a Square Terminal to check out a buyer, the POS must be paired to a Square Terminal at the chosen location.

The pairing process follows these steps:

  1. The POS client uses the Locations API to present a location picker for the seller.

  2. The POS client gets a device code by providing a location ID and a friendly name.

  3. The seller enters the device code into the Square Terminal to sign in.

  4. Square Terminal notifies Square that it is signed in using the device code.

  5. The POS and Square Terminal are paired when the device code has been used to sign in to the terminal.

  6. The POS client receives a webhook that shows pairing is enabled and provides a device ID to be used in checkout requests for the paired terminal.

Request a device code
Permalink Get a link to this section

curl https://connect.squareup.com/v2/devices/codes \
  -X POST \
  -H 'Square-Version: 2020-04-22' \
  -H 'Authorization: {{ACCESS_TOKEN}}' \
  -H 'Content-Type: application/json' \
  -d '{
    "idempotency_key": "123-456-789",
    "device_code": {
      "name": "Counter 1",
      "product_type": "TERMINAL_API",
      "location_id": "NHT...CGJ"
    }
  }'

The response returns several fields, including:

  • The friendly name you used in the request.

  • The device pairing status, which is currently UNPAIRED.

  • The device code to enter into the Square Terminal.

  • The date and time on which the device code will expire if not used.

HTTP 200 
{
    id: "1234567890",
    name: "Counter 1",
    code: "AFZEFB",
    status: "UNPAIRED",
    location_id: "NHT...CGJ",
    product_type: "TERMINAL_API",
    pair_by: "1970-01-01 11:10",
    created_at: "1970-01-01 11:10",
    updated_at: "1970-01-01 11:10"
}

After a device code is created, it must be used to sign in to a Square Terminal within 5 minutes. If the device code is not used within 5 minutes, it expires and a new device code must be requested. After the initial sign in, the device code can be used to sign in on the same Square Terminal in the future.

After a seller signs in to a Square Terminal with the code, the status changes to PAIRED and the device_id value of the Terminal device is available. The device ID is the serial number on the underside of the Square Terminal.

A seller can now sign in to Square Terminal using the device code. When signed in, the POS client is notified as described in the following sections.

Listen for device pairing webhook (optional)
Permalink Get a link to this section

Validate the webhook notification for device.code.paired.

The following example shows the payload of the webhook:

{
  "merchant_id": "6SSW...ST5",
  "location_id": "S8GW...3HF3",
  "type": "device.code.paired",
  "event_id": "d214f854-adb1-4f56-b078-4b8697a3187a",
  "created_at": "2020-02-15T04:38:13Z",
  "data": {
    "type": "device_code",
    "id": "bact:cgvL1yv43VFjexample",
    "object": {
      "device_code": {
         "id": "TQYQBS0P8B7AJ",
         "name": "Counter 1",
         "code": "TRXKEB",
         "device_id": "R5WNWB5BKNG9R",
         "product_type": "TERMINAL_API",
         "location_id": "S8GW...3HF3",
         "pair_by": "2020-03-20T19:49:19.000Z",
         "created_at": "2020-03-20T19:44:19.000Z",
         "status": "PAIRED",
         "status_changed_at": "2020-03-20T19:44:19.000Z"
      }
    }
  }
}

Request pairing status (optional)
Permalink Get a link to this section

The devices API returns the current status of a device pairing with a GET command, as shown in the following example:

curl -X GET \
  https://connect.squareup.com/v2/devices/codes/{DEVICE_CODE_ID} \
 -H 'Square-Version: 2020-04-22' \
 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
 -H 'Content-Type: application/json' \
 -H 'cache-control: no-cache'

If the device code has not expired, a response like the following example is returned:

{
  "device_code": {
    "id": "3YVR0WQ0VY6WG",
    "name": "Counter 2",
    "code": "QYXRJQ",
    "product_type": "TERMINAL_API",
    "location_id": "NHT82D0ENBCGJ",
    "pair_by": "2020-03-20T20:23:31.000Z",
    "created_at": "2020-03-20T20:18:31.000Z",
    "status": "UNPAIRED",
    "status_changed_at": "2020-03-20T20:18:31.000Z"
  }
}

Check the status of the device code. If it is not PAIRED, you need to request the device pairing again. Keep checking until the device is PAIRED. When paired, the POS client can send terminal checkout requests.

Note

Expired device codes are not returned in the ListDeviceCodes and GetDeviceCode operations.

Request a Square Terminal checkout
Permalink Get a link to this section

The POS app must specify the total amount to be paid by the buyer (including any sales tax or other fees) when requesting a checkout. Optionally, the POS app can require the Square Terminal to add a tip amount or show a receipt screen.

Note

Square Terminal accepts Apple Pay, Google Pay, Square Gift Cards and prepaid debit cards. However, if the balance of a Gift or prepaid card is not sufficient to pay for a transaction, the card will be declined.

Payment flow
Permalink Get a link to this section

To take a payment from a buyer, the Square Terminal needs to have the total purchase amount and currency. For example, a Square Terminal can be told to accept $100 (USD). To process this request, the POS app makes a request to Square using the Terminal API to send the payment request to a paired Square Terminal, identified by the device ID. This process flows is as follows:

  1. The POS client sends the Terminal API a request to check out a buyer and accept a payment.

  2. Square sends the checkout details to Square Terminal, which shows the payment details to the buyer.

  3. The buyer dips, taps, or swipes a payment card in the Square Terminal.

  4. The Square Terminal notifies Square of the payment.

  5. The Terminal API notifies the POS backend that the terminal checkout was COMPLETED.

Take a payment with a tip
Permalink Get a link to this section

The following command configures the Terminal checkout to:

  • Print a receipt.

  • Show the receipt screen.

The device_options object sets these behaviors:

 "device_options": {
        "print_receipt": true,
        "skip_receipt_screen": false,
        "tip_settings": {
          "allow_tipping": true,
          "separate_tip_screen": true,
          "custom_tip_field": false
        }
curl https://connect.squareup.com/v2/terminals/checkouts \
  -X POST \
  -H 'Square-Version: 2020-04-22' \
  -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
  -H 'Content-Type: application/json' \
  -d '{
    "idempotency_key": "blart34343432",
    "checkout": {
      "amount_money": {
        "amount": 100,
        "currency": "USD"
      },
      "reference_id": "232323",
      "note": "hamburger",
      "device_options": {
        "print_receipt": true,
        "skip_receipt_screen": false,
        "tip_settings": {
          "allow_tipping": true,
          "separate_tip_screen": true,
          "custom_tip_field": false
        },
        "device_id": "R5WNWB5BKNG9R"
      }
    }
  }'

The response is returned when the paired Square Terminal acknowledges the checkout request. Note that the PENDING status changes to IN_PROGRESS when the Terminal is showing the checkout to the buyer and awaiting input. When the checkout is complete and Square has accepted the payment card, the status is COMPLETED.

While the status of the checkout is PENDING, the POS client or the buyer can cancel the checkout. When the status is IN_PROGRESS, the process continues until COMPLETED. At that time, the POS client can query for the final state of the checkout.

{
  "checkout": {
    "id": "Dobuud5jsMbqO",
    "amount_money": {
      "amount": 100,
      "currency": "USD"
    },
    "reference_id": "232323",
    "note": "hamburger",
    "device_options": {
      "device_id": "R5WNWB5BKNG9R",
      "print_receipt": true,
      "tip_settings": {
        "separate_tip_screen": true,
        "custom_tip_field": false,
        "allow_tipping": true
      },
      "skip_receipt_screen": false
    },
    "device_id": "R5WNWB5BKNG9R",
    "status": "PENDING",
    "created_at": "2020-03-20T21:23:05.051Z",
    "updated_at": "2020-03-20T21:23:05.051Z",
    "app_id": "sq0ids-o38CJ3JfIrKJ_xn10mRhFg",
    "deadline_duration": "PT10M"
  }
}

Cancel a terminal checkout
Permalink Get a link to this section

A terminal checkout request can be canceled from the POS app while the status of the checkout is PENDING. To cancel a terminal checkout, POST a request to the cancel endpoint for the terminal checkout to be canceled.

In this example, the seller cancels cancels a pending terminal request from the POS.

curl https://connect.squareup.com/v2/terminals/checkouts/{checkout_id}/cancel \
  -X POST \
  -H 'Square-Version: 2020-04-22' \
  -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
  -H 'Content-Type: application/json' \
  -d '{
      "checkout_id": "{checkout_id}",
      "cancel_reason": SELLER_CANCELED
      }
    }
  }'

If the request is successful, the response provides the terminal checkout object in it's new state:

{
  "checkout": {
    "id": "{checkout_id}",
    "amount_money": {
      "amount": 100,
      "currency": "USD"
    },
    "device_options": {
      "device_id": "432532423`",
      "tip_settings": {
        "allow_tipping": false
      },
      "skip_receipt_screen": true
    },
    "status": "CANCELED",
    "created_at": "2020-04-06T21:37:08.516Z",
    "updated_at": "2020-04-06T21:37:08.516Z",
    "app_id": "sq0ids-o38CJ3JfIrKJ_xn10mRhFg",
    "deadline_duration": "PT5M"
  }
}

Verify a payment
Permalink Get a link to this section

When the status of a Terminal checkout object is updated, webhook notifications are sent to the endpoint that is registered for a POS app. To get the notifications, be sure that your app is updated in the Application Dashboard with the following webhook notifications:

  • terminal.checkout.created

  • terminal.checkout.updated

When a Terminal checkout object is created, canceled, or completed, a full copy of the object is sent to your app at your webhook URL. The object provides status and payment_ids fields.

On checkout completion, a Payment is created to record the details of the charge. The payment status can be COMPLETED, CANCELED, or FAILED. A completed payment is normally for the full amount of the purchase but must be verified against the amount expected by your POS app.

Completed payment for full purchase amount means that the checkout is complete and the POS payment window can be closed. A receipt for the amount charged on the payment card is printed by the Square Terminal.

Completed payment for a partial purchase amount means that the buyer used a Square Gift Card or a prepaid debit card when the full balance of the card was insufficient to complete a purchase. The payment is COMPLETED but the buyer is charged only the balance of the card. The POS payment window should remain open to initiate a check out for the remaining balance.

When a checkout is completed, it has one (or more) payment_ids listed on it. These are confirmations about how much money was actually collected, if any at all.

Important

A COMPLETED checkout might not have collected the exact total you requested. For example, when a tip is added to the payment. You should always check the Payment object to determine the actual amount collected.

Get a completed checkout to find its payment_ids, as shown in the following example:

curl -X GET \
  https://connect.squareup.com/v2/terminals/checkouts/CHECKOUT_ID \
 -H 'Square-Version: 2020-04-22' \
 -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \
 -H 'Content-Type: application/json' \
 -H 'cache-control: no-cache'

{
    "checkout": {
        "id": "xv4gh2KBCmlqO",
        "amount_money": {
            "amount": 100,
            "currency": "USD"
        },
        ...snip...
        "status": "COMPLETED",
        "payment_ids": [
            "PAYMENT_ID"
        ],
    }
}

Search for Terminal checkout requests
Permalink Get a link to this section

Search for existing Terminal checkout requests filtered by:

  • Device ID.

  • Time and date range that the Terminal checkout was requested

  • Terminal checkout status

Search results are sorted, paginated, and allow for a custom page size.

This example requests an additional page of completed terminal checkout requests sent to the Square Terminal with ID R5WNWB5BKNG9R, and created on or after noon UTC/GMT, starting on 03-20-2020. Results are limited to 10 terminal checkouts per result page.

Read pagination in Square APIs to learn more about how to work with cursors.

curl https://connect.squareup.com/v2/terminals/checkouts/search \
  -X POST \
  -H 'Square-Version: 2020-04-22' \
  -H 'Authorization: {{ACCESS_TOKEN}}' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "filter": {
        "device_id" : "R5WNWB5BKNG9R",
        "created_at" : {
          "start_at": "2020-03-20T12:00:00.000Z",
          "end_at": "2020-03-20T24:00:00.000Z"
        }
        "status" : "COMPLETED"
      },
      "sort": {
        "sort_order": "ASC"
      }
    },
    "cursor": "YTt3Nej0VB04dG4jS06HqO4Hm4Q9cEaCrCL84f5KzLg_p",
    "limit": 10
  }'

Set up a Square Terminal Device
Permalink Get a link to this section

A new Square Terminal must be set up before use. If a previously set up device is powered off, after turning it on, check for any software updates that might have been missed while the Terminal was powered off.

  1. Power on the Square Terminal and connect to your Wi-Fi network.

  2. On the Terminal Sign in Page, choose Change Settings, choose General, and then choose About Terminal. If there are any pending software updates, update the Square Terminal to the latest version.

Sign in to Square Terminal
Permalink Get a link to this section

When a device code is available for the requested Square Terminal, a merchant signs in to the Square Terminal using the following steps:

  1. On the Sign in Page, touch the Device Code button.

  2. Request a new device code by sending a POST request to v2/devices/codes.

  3. Display this code to the person performing the setup.

  4. Use the device code your application gathered.

The Terminal screen should look like this:

Square Terminal Ready screen

Sign a Square Terminal out of paired mode
Permalink Get a link to this section

If your Square Terminal is paired with a POS client, you might want to sign out of the Terminal. This lets you pair the Square Terminal with a different POS client or use Square’s Point of Sale app.

  1. Swipe from the left side of the screen to open the navigation drawer.

  2. Choose Settings.

  3. Click Sign Out at the bottom of the menu.

Requirements and limitations
Permalink Get a link to this section

  • Applications must have the following OAuth permissions: DEVICE_CREDENTIAL_MANAGEMENT to get a device code, PAYMENTS_WRITE to process payments and PAYMENTS_READ to retrieve payments.

  • You cannot take cash payments with the Terminal API.