Get Paid IRL (Part 4) Canceling reader actions and in-flight payments
Tags: tutorial, payments, stripe, webdev
Published: 2022-06-30 20:52:00

_Did you know that you can accept in-person payments with Stripe? In this series, we’re going to dive headfirst into building an in-person payments integration using [Stripe Terminal](https://stripe.com/docs/terminal)_.

_In our [last post](https://dev.to/stripe/get-paid-irl-how-to-accept-money-with-stripe-terminal-part-24-f4a), we gave our web-based point-of-sale application the ability to authorize and capture in-person payments using Stripe’s payments and Terminal APIs._

_In this blog post, we’re going to learn how to cancel payments after they’ve been sent to the reader, so that our application can accommodate any changes to the purchase amount._

_New to this series? Be sure to check out [our first post](https://dev.to/stripe/get-paid-irl-how-to-accept-money-with-stripe-terminal-part-14-1ljd) on how to set up a card reader for testing and development, [our second post](https://dev.to/stripe/get-paid-irl-how-to-accept-money-with-stripe-terminal-part-24-f4a) on connecting them to a web application, and our [third post](https://dev.to/stripe/get-paid-irl-how-to-accept-money-with-stripe-terminal-part-34-13de) on authorizing and capturing in-person payments._

# Building your app: Canceling in-flight payments and reader actions

If you’ve been following along with the series, you‘ve learned how to: 

1. Register [real or simulated card readers](https://dev.to/stripe/get-paid-irl-how-to-accept-money-with-stripe-terminal-part-14-1ljd)
2. [List online readers](https://dev.to/stripe/get-paid-irl-how-to-accept-money-with-stripe-terminal-part-24-f4a)
3. Test [collecting in-person payments on physical and simulated readers](https://dev.to/stripe/get-paid-irl-how-to-accept-money-with-stripe-terminal-part-34-13de). 

In this blog post, we’ll learn how to cancel in-flight payments by resetting the reader to its idle state.

A payment is “in-flight” _after_ the reader has been prompted to collect payment, but _before_ the customer has tapped their card. At this point, you may need to cancel the payment for any number of reasons. Maybe the cashier has scanned the item too many times. Or perhaps the customer has simply decided to change their order at the last minute. Whatever the reason, the final amount has changed and your payment and reader needs to reflect the new amount.

## Canceling a reader action

Let’s build a backend endpoint for canceling a reader action. This route will allow us to reset the reader to its idle state. We can use it to cancel all kinds of reader actions. In this post, we’ll focus on canceling a reader action to process a payment, but just know that you could also use this endpoint to cancel other reader actions, like [displaying the cart details](https://stripe.com/docs/terminal/features/display?terminal-sdk-platform=server-driven) on the reader.

**On the backend** in `server/server.js`, we’ll create a `POST` route for canceling a reader action. This route will expect a request body with a `reader_id`, which represents the specific reader that we want to reset.

{% embed https://gist.github.com/charlesw-stripe/f879de137a221302e100393f8a0a119b %}

Our `/cancel-reader-action` endpoint will return a [`reader`](https://stripe.com/docs/api/terminal/readers/object) object, which includes the state of the reader. We can inspect the reader’s `action` property, which shows the reader’s most recent action.   If we take a look at the action property, we see that it’s `null`. This confirms that the reader has been reset successfully.

{% embed https://gist.github.com/charlesw-stripe/1c10d22bef0258559e7ebe6982bdc989 %}

**On the frontend** in `client/reader.js`, we’ll add an event listener to our Cancel button. If we get an error, we’ll log it to `#messages`. Otherwise, we’ll redirect to the cancel page, where we can restart our payment.

{% embed https://gist.github.com/charlesw-stripe/decf9992bc9665629857ec5f086a5b84 %}

Congratulations! If you’ve been following along, you should now have a complete in-person payments integration that’s able to collect and cancel in-person payments on a physical or simulated WisePOS E reader. 🎉

![Canceling a payment sends us back to the cancel page.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tbzgtz8e2p1r0k2msgef.gif)

![Horizontal rule](https://res.cloudinary.com/practicaldev/image/fetch/s--XRaNCJc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)

💡_You can also see the [completed project on Repl.it](https://replit.com/@charlesw-dev/terminal-complete?v=1)._

![Horizontal rule](https://res.cloudinary.com/practicaldev/image/fetch/s--XRaNCJc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kwi5h27a7elyignm8iie.png)

Your point-of-sales application is complete but, there are still a variety of features that you can add to improve the overall experience. Check out the [Stripe docs](https://stripe.com/docs/terminal) to learn how to [display the cart](https://stripe.com/docs/terminal/features/display) on the reader, [accept tips](https://stripe.com/docs/terminal/features/collecting-tips/overview), and [save cards](https://stripe.com/docs/terminal/features/saving-cards/overview) without charging them. We read these as exercises for the reader (for now 😉).

---

## Stay connected

Want to stay up to date on Stripe’s latest integrations, features, and open-source projects?

📣 Follow us on [Twitter](https://twitter.com/StripeDev)
💬 Join the official [Discord server](https://stripe.com/go/developer-chat)
📺 Subscribe to our [Youtube channel](https://www.youtube.com/StripeDevelopers)
📧 Sign up for the [Dev Digest](https://go.stripe.global/dev-digest)

## About the author

![The author, Charles Watkins](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aqzlent7mkotc9hnl8k7.png)

[Charles Watkins](https://charleswatkins.dev/) is a Developer Advocate at Stripe where he writes, codes, and livestreams about online payments. In his spare time, he enjoys drawing, gaming, and rewatching the first five seasons of Game of Thrones.