← All projectsCase study, contactless tipping

Onetip

A tablet app taken over, then a platform built around it so that the tip reaches the team.

Visit the Onetip site →
The Onetip app's App Store visuals
The Onetip app on the App Store.

The starting point

There was already a tablet app, set on the counter to receive tips. I took it over as it was, with its code and its habits.

  • A tablet app for a fleet of dedicated devices, with no remote code updates. Every change goes through a new install.
  • A central server linking payments, teams and venues.
  • No app for the customer or the staff, no tool to follow payouts, no way to pay without the tablet.

What was built

Around the tablet, a set of tools plugged into the same server. Each one serves a specific person.

For the counter

The tablet app

The customer picks an amount and pays on the spot. The app was taken over, made reliable and tested, without changing how the team uses it.

For the teams

The mobile app

Each team member follows the tips received, shares a QR code, enters a bank account and gets paid out. It exists on iOS and Android.

For customers

The NFC payment app

The customer taps their phone on a tag, picks the person to thank and pays, with nothing to install. They can also leave a Google review right after.

For managers

The venue back office

Team, tablet and tag management, tip tracking and venue settings.

For administration

The Onetip team back office

Accounts, venues, subscriptions, commissions and payment tracking, to run the platform day to day.

For every tool

The server

One API for the tablets, the mobile apps, the NFC page and both back offices. It talks to Stripe and splits the payouts.

  • Team payouts go through Stripe Connect, each person having their own account.
  • Subscription and commission are computed server side, with tests that pin down the money rules.
  • The mobile apps exist in three languages.

How it works

The journey of a tip, from the customer to the team.

  1. The customer lands on a thank-you screen, by scanning a QR code, tapping their phone on an NFC tag or using the tablet on the counter.
  2. They pick the person to thank, then an amount.
  3. They pay by card, with Apple Pay or Google Pay when their phone allows it. A 3D Secure check is added if their bank requires it.
  4. The server records the payment once, computes the platform share and assigns the rest to the person.
  5. The person sees the tip in their app and receives it in their bank account, through a Stripe Connect payout.
  6. The manager and the Onetip team follow everything in their back office.

What was hard

A platform that moves money does not forgive calculation errors or duplicates. Here are five real problems, with their cause and what was done.

  1. A subscription charged twice at the start of the month

    During the first days of the month, some accounts were charged more than expected.

    The subscription month calculation picked the wrong period and counted some payments several times. I wrote the tests that pin down the expected behavior, fixed the calculation on Paris time, then checked it on a real production account.

  2. A team member added twice

    When adding someone to the team, a double tap on the button created two records.

    A transaction is not enough here, because the client SDK cannot read a query inside a transaction. Each record now has an identifier built from the person and the venue, and the add is a single grouped write.

  3. A till that stopped asking for its permissions

    After one of my fixes, the tablet started without asking for the access it needs to take payments.

    My rule waited for the app to be in the foreground, but Android does not report that yet at startup. The till stayed silent. I caught it and fixed it the same day, by removing that condition.

  4. An iOS app that froze when choosing a photo

    On iPhone, opening the photo picker locked the screen.

    The app opened the picker while a sheet was still closing, and iOS refuses that overlap. The action now waits until the sheet is closed. Android was not affected.

  5. The 3D Secure check never came back

    After approval at the bank, the page stayed open or showed a routing error.

    The payment library never received the return address on iOS. I hooked that link listener up myself and made the app absorb it without changing screen. The flow is validated on iOS and Android.

The stack

React Native with Expo for the tablet and mobile apps, Next.js for the two back offices and the NFC payment page, Firebase for the database, authentication and server functions in Node and TypeScript, Stripe and Stripe Connect for payments and payouts. The server money rules are covered by automated tests.

Onetip, a contactless tipping platform for service teams | Marcelin Bedy