Keep Checkout IN_PROGRESS (instead of CANCEL) after a Swipe failure for customer to retry

We currently have the Square Terminal implemented in several self-checkout kiosks for campuses and cafeterias. For a kiosk solution like this we believe it would be ideal to not cancel a Checkout after a dip or swipe failure, but to keep the Checkout active for the user to try again.

Please find more information here:

I was told this falls into a new Feature Request. I’m posting here to give it more visibility.

Thanks for the great work you guys are doing in this product!

1 Like

Surprisingly I think you should be able to implement this fairly well, and very flexibly, using what is there now.

My suggestion would be to use the terminal updated webhook to trigger creation of another terminal request, if it had failed for a “soft” reason (whatever your app considers “soft”). You should detect the user attempting to cancel from the terminal and offer a cancel or retry button on the kiosk screen. While you’re at it, some sort of integration with the screen is a nice-to-have as it makes the experience seem more responsive (for instance, “Processing card”, “Approved” appearing on screen rather than just on the terminal (which may be hard to see).

1 Like

Thanks for the input Brian.
We don’t have a way to differentiate between a checkout canceled due to an invalid card swipe and an explicit cancel made by the user (using the back button).
Both checkouts are identical, example:

This is a Checkout canceled by swiping instead of using chip:

{
      "id": "UKYYW10JBvcqO",
      "amount_money": {
        "amount": 100,
        "currency": "USD"
      },
      "device_options": {
        "device_id": "xxxxx",
        "tip_settings": {
          "allow_tipping": false
        },
        "skip_receipt_screen": false
      },
      "status": "CANCELED",
      "created_at": "2020-08-01T19:57:24.292Z",
      "updated_at": "2020-08-01T19:57:41.008Z",
      "app_id": "xxxxxxxxx",
      "deadline_duration": "PT1M",
      "cancel_reason": "BUYER_CANCELED"
    }

This is a Checkout canceled by tapping on the back button (buyer intentionally canceled)

{
      "id": "fSSaVl7ndXqqO",
      "amount_money": {
        "amount": 100,
        "currency": "USD"
      },
      "device_options": {
        "device_id": "xxxxx",
        "tip_settings": {
          "allow_tipping": false
        },
        "skip_receipt_screen": false
      },
      "status": "CANCELED",
      "created_at": "2020-08-01T19:59:04.483Z",
      "updated_at": "2020-08-01T19:59:14.843Z",
      "app_id": "sq0idp-xxxxx",
      "deadline_duration": "PT1M",
      "cancel_reason": "BUYER_CANCELED"
    }

As you can see they are both identical, there is no way for us to detect the “soft” cancelation. We cannot simply trigger another checkout, because it could have been a legit cancelation.

We do provide feedback to the user in the kiosk screen, that’s really helpful for the customer, however in this case we cannot know for sure what the reason for the cancellation was.