DEV Community

Cover image for Get Paid IRL (Part 2) Building your app for accepting payments
Charles Watkins for Stripe

Posted on • Edited on

Get Paid IRL (Part 2) Building your app for accepting payments

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.

In our last post, we learned how to register a physical or simulated WisePOS E using the Stripe dashboard, so that we could build a point-of-sale application to take in-person payments.

In this blog post, we’re going to start building our application using a scaffolded Node.js project in Replit, a service you can use to build, compile and host projects–or repls–from the comfort of your browser. That’s right, we’re leaving the Stripe dashboard and breaking out our web-based IDE!

New to this series? Be sure to check out our previous post on how to set up a physical or simulated card reader for testing and development.

Building your point-of-sale app

Setting up the project

We’re going to start building our web app using a scaffolded Node.js project in Replit, a free service you can use to build and host projects (repls) from the comfort of your favorite browser. If you don’t already have a Replit account, you can sign up for a free one here.

To save time, be working off this starter repl. The repl has Node.js backend running the Express.js micro framework. We’ve scaffolded the project ahead of time to include the HTML templates and app server, so that we can focus on building against the Stripe Terminal APIs instead of writing boilerplate.

Fork the starter Repl to create a copy to your account, if you’d like to follow along with the tutorial and remix the application.

Add your Stripe secret key as a project environment variable by navigating to the repl’s Secret store and adding STRIPE_SECRET_KEY as a key and your actual Secret key as its value.

Click the Run button to start your project. This will install the project’s required dependencies and start the app. Your starter point-of-sale app is live 🎉

Click the Run button in your repl to start the project and notice it has no readers in the reader-select

You’ll notice that we have a dropdown field for selecting a reader. You’ll also notice that our dropdown list doesn’t actually list any readers.

To fill out our list, we’ll be creating a backend route for retrieving our Terminal readers from our Stripe account in server/server.js and use it in client/index.js.


Creating a route for listing readers (backend)

To list our readers in our frontend, we’ll need to first retrieve them from Stripe in our backend.

In /server/server.js, add a route for retrieving your Terminal readers from all locations around line 30. Be sure to add your code after instantiating your Express app and stripe but before running app.listen().

Here we’ll create a GET endpoint on our backend at /list-readers. In the app.get() callback, add a try-catch. We’ll call stripe.terminal.readers.list(). In our case, we’ll limit our results to five readers with a status of online. In addition to status, we could also filter the results by location, device_type , and even device serial_number. But for testing, filtering by status will do.

Now if we create a GET request to our /list-readers route, which we can do via cURL, Postman, or by visiting the URL in our browser, we’ll get an array that contains a list of Terminal Reader objects, which represent the current state of our registered card readers.

Retrieving our readers will give us a variety of information about the reader, including its name (label), status, and most recent action. We’ll dive into how to use the action property in our next post on creating and processing payments. For now, let’s focus on rendering our readers to the page and making them selectable.


Retrieving and rendering readers (frontend)

Now that we have a way to retrieve our readers, let’s render them in our web app.

In client/index.js, we have an event listener for when our DOM loads, DOMContentLoaded. In the callback, use fetch to make a GET request to our newly created list-readers endpoint. We’ll destructure the results to get a readers (success) or an error (failure).

If we get an error, we’ll handle the error by adding a message to our #messages div just below our form and logging out to the console using our addMessage helper from utils.js. Otherwise, we’ll loop through our readersList, adding each one to our reader-select dropdown.

Let your repl save and reload. Your Terminal app is now able to list any online readers.

The register Terminal readers in the Stripe dashboard are now listed in our app

If you don’t see any readers or errors, make sure that you’ve set up at least one simulated reader to at least one Stripe Terminal Location. You can learn how in our previous post on registering readers.

Otherwise, your app’s dropdown list should now contain up to five online simulated or real WisePOS E’s.

Just having a list of online readers along with their IDs brings you half-way to processing in-person payments with Stripe’s Terminal server-driven integration.


Next up: Creating and collecting payments with Stripe Terminal

In our next post, we’ll learn how to create and hand-off payments to the Stripe Terminal readers listed in our app using the Payment Intents and Terminal Reader APIs.

Stay connected

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

📣 Follow us on Twitter
💬 Join the official Discord server
📺 Subscribe to our Youtube channel
📧 Sign up for the Dev Digest

About the author

The author, Charles Watkins

Charles Watkins 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.

Top comments (0)