Shipped Work · Native iOS & Android

Offline OTP Authenticator

A native app that makes one-time passwords for card payments. More than 2 million people used it.

RoleUI/UX Designer
CompanyCarrene Corp
Timeline2021 – 2024
PlatformsiOS & Android
Scale2M+ users
Three screens of the OTP app: adding a bank, the list of banks with password codes and countdown timers, and activating passwords

Note: I recreated these screens. The banks are fictional and the data is placeholder. The flows and decisions are real.

The short version

I started as the only designer on a team of four. The app had three screens. Then the project grew, and the team grew to 15. Every screen had its own colors, and changes got lost. So I built a design system for all our OTP apps. More than 2 million people used the app.

Overview

People needed a one-time password to approve card payments. The app made these passwords on the phone itself. It didn’t need internet. Each code worked for 60 seconds. Each bank could give two kinds of password:

Password 1

ATMs and card readers

Like taking out cash, or paying in a store.

Password 2

Online shopping and transactions

For paying or moving money online.

My role

I designed the flows and screens for iOS and Android. I followed Apple’s guidelines and Material Design. I did it all, from wireframes to final screens to annotated handoff. I also built the design system.

How it grew

Chapter 1

It started small

At the start we were four people. Me as the only designer, one iOS developer, one Android developer and one backend developer. The app had three screens. We had no design system. Everyone set their own colors on each screen.

Chapter 2

Then the biggest bank wanted its own app

The plan was to add other banks to this app. But the biggest bank wanted the app just for itself. We tried to negotiate. We only wanted to add a section for the other banks. They didn’t accept it, so we had to rethink and build a separate app for the other banks.

The team grew too. By the end we were 2 PMs, 2 designers, 4 iOS and Android developers, 3 backend developers, 2 DevOps and 2 QA. And we had a deadline.

Chapter 3

Then things started to break

More screens, more people, more apps. And the colors were still set screen by screen. So when something changed, we couldn’t track it. We had to search every page, one by one.

Chapter 4

So I built a design system

20 components, used across all our OTP apps. One place for colors and styles, not one per screen. After that, QA found far fewer color and style issues. And handoff to developers got faster.

Color system documentation: primary, neutral, text, and semantic status colors with hex values and usage notes

The core flow

Three steps, from installing the app to paying.

Add New Bank screen with four bank tiles and a Scan Code button
Step 1

Add a bank

The user picks their bank. Then they scan the code they got from their branch or internet banking.

Enter Bank Passwords screen with Password 1 selected, an activation code field and a backup PIN field
Step 2

Activate passwords

They pick Password 1, Password 2, or both. They enter the activation code from the SMS. Then they set a 6-digit backup PIN.

Bank List screen showing three bank cards, each with a password code, a copy button and a countdown ring
Step 3

Use a password

Each bank has one card. It shows the active passwords, the time left and a copy button.

Try it

The password card, live

The ring shows how long the code works. In the last 5 seconds it turns red. When time is up, a new code comes in. Tap copy and you see a check, so you know it worked. These codes are random, not real passwords.

Your bank Password 1
000 000

Expires in 60 seconds

Design decisions

Proposed · Not shipped

Activation without a SIM card

The activation code only came by SMS. So I asked: what if someone has internet but no signal? Or no SIM card, like on an iPad?

Options: SMS only, which was the default. Or SMS plus email. Email was my idea.

Why email: people with no signal or no SIM could still activate their passwords.

Trade-off: reach vs. security. Email reaches more people. But the banks’ security teams didn’t accept email as a safe way to verify someone. So we kept SMS only.

Clarity

One card per bank

Each card only shows the passwords the user turned on. If Password 2 is off, you see a dashed “Add” button, not an empty field. So the screen never shows a code that doesn’t exist.

Time pressure

Expiry you can read at a glance

A ring shows the seconds left, as a number. In the last 5 seconds it turns red. The number is always there, so the warning doesn’t depend on color only.

Speed

Big digits, one-tap copy

People read the code at a card reader, or paste it at checkout. Usually in a hurry. So the digits are big, and the copy button is right next to the code.

Security

Lock the app, not just the phone

The app has its own lock, a pattern or a password. Users can also set when it locks. So even if the phone is unlocked, the card passwords stay safe.

Authentication Method screen with a Password and Pattern toggle and a nine-dot pattern grid

Authentication method

Users pick a password or a pattern to unlock the app.

Bank Support screen listing six banks with a call button for each

Help one tap away

Lost a card? Password not working? Each bank’s support number is there with a call button. Users can also report a problem with the app.

Results

2M+

people used the app

20

components in the design system

I also worked on a login redesign. It reduced fraudulent login attempts.

What I’d improve today

Looking back, I checked our colors against WCAG 2.1 AA. Most pairs pass. White on the primary blue is 6.87:1. But three pairs fail if you use them for text:

PairContrastFixNew contrast
Text Secondary on Light Background4.22:1#6B6B6B4.89:1
White on Success Green2.78:1#2E7D325.13:1
White on Error Red3.68:1#D32F2F4.98:1

AA needs 4.5:1 for body text. The red for the countdown warning, #D32F2F, comes from this fixed set.