Confused about Square Terminal integration

I’ve been developing a web application which will take payments via Square Terminal. I’ve spent a fair bit of time reading the documentation but I’m still rather confused about some parts of the process of connecting to the terminal and sending checkout requests, and I’m hoping someone can guide me through.

I have set up a Square test account, hoping to be able to test payments via the sandbox. So my first step is, I imagine, to get talking to the new Square Terminal, which I have sitting next to me. According to, my application should ‘Request a new device code by sending a POST request to v2/devices/codes’. So I do that, using the access token from my developer account, and with requisite idempotent_key and other fields. The JSON response contains a 6 character ‘device_code’ object with a ‘code’ property which I assume is what I need to sign in to the Square Terminal with to pair it, and a status of ‘UNPAIRED’. So I attempt to sign in to my Square Terminal (within 5 minutes) with this and get a ‘Login Failed’ error, ‘Incorrect device code. Please check your device code and try again’. So what am I doing wrong? What do I need to do?

I am assuming that this pairing is a one-off process, is it not, I only need to do it once to pair my web application with the Square Terminal and then I can fire off checkout requests using the ID it has given, without having to pair each time?

:wave: Currently you can only pair the device is in production. The Square Sandbox does not support the Devices API. To test a Terminal API application in the Sandbox, use a Sandbox device ID that simulates a Square Terminal from the list of Sandbox test values for the Terminal API instead of production device IDs obtained with the Devices API. :slightly_smiling_face:

1 Like

Thanks. I was thinking that was probably the case, and I’ve been trying to use a Sandbox test device id in the last couple of hours, but it’s not behaving as expected. There is one with the value ‘9fa747a2-25ff-48ee-b078-04381f7c828f’, which is supposed to result in success with amounts less than $25. I’m working in GBP, though (I’m in the UK), and have tried it with test payments with ‘amount’ as 9 and ‘currency’ as ‘GBP’. Every time, I’ve had three webhook calls in succession, first with status PENDING, then PROGRESS and finally CANCELLED, with cancel_reason of ‘TIMED_OUT’. Should this not result in a COMPLETED status? Is there a problem with using a currency other than USD? [LATER: When I change GBP to USD, I get a 400 error. This is reproduceable via - GBP is OK, USD, gives a 400 error]

As regards my other question, is the pairing a one-off event? Do I just need to request a new device code via the Devices API (once in live mode), and use the device code I get back from that to pair with the Square Terminal, and then use the associated device id for subsequent checkouts?

What are the steps to reproduce? I just tested with this and it completed as expected:

    "checkout": {
      "device_options": {
        "device_id": "9fa747a2-25ff-48ee-b078-04381f7c828f"
      "amount_money": {
        "amount": 900,
        "currency": "GBP"
      "payment_type": "CARD_PRESENT"
    "idempotency_key": "05ecddfc-512e-40ac-a519-f3ae61778379"

For the device code yes, it’s a one time thing. Once you request the device code with the API and pair the device you’re all set. :slightly_smiling_face:

When you say it completed as expected, do you mean that it issued a webhook with status = COMPLETED? (As opposed to the CANCELLED I’ve been seeing). I was able to reproduce your example with Postman and found that the payment did in fact complete, so I wonder whether there was something wrong about the JSON I was testing with. Certainly one thing I was doing wrong was that I had 9 instead of 900 (I had forgotten about the smallest unit thing), but I can’t see why that would have resulted in a CANCELLED status. Also I had ‘type’:‘DEVICE’ (picked up from an example), whereas you have ‘payment_type’:‘CARD_PRESENT’. I am now experimenting with these. One thing I’m seeing is that the webhook calls seem to be taking a couple of minutes to show up, don’t know why that would be.

Yes, that’s correct it COMPLETED.

It’s possible there was something wrong with the JSON. Have you checked your API Logs to see the request your application sent to Square to see if its malformed? :slightly_smiling_face: