A while back I got curious about a question that seemed simple on the surface: what actually happens between the moment you tap a contactless card and the moment a terminal accepts it? That question led me to build Tap to Pay Android, an app that uses the phone's NFC to read and parse EMV cards, showing in real time the APDU commands and tags being exchanged.
⚠️ Before going further: this is an educational project. It doesn't store or transmit any card data, all processing happens locally, and it's not meant for commercial use nor does it guarantee PCI-DSS compliance. The goal is to understand the protocol, not to process real payments.
Note: All card data shown in screenshots are test/sample cards, not real payment cards.
What does the app do?
In plain terms: you tap a contactless card against the phone, and the app walks you through exactly how the communication gets established:
- PPSE selection — requests the card's Proximity Payment System Environment.
- AID discovery — extracts the Application Identifier from the response.
- Application selection — selects the payment app using that AID.
- GPO (Get Processing Options) — sends the PDOL data.
- Record reading — reads records from the Application File Locator.
- EMV parsing — organizes all tags by category (app info, transaction data, cardholder data, etc.).
All of this is visible in the UI in real time, with a dedicated view for APDU commands (request/response with status codes) and an EMV tag viewer with search.
Tech stack
- Kotlin 2.0.21 + Jetpack Compose for the entire UI
- Material 3, with light/dark/system theme support
- MVVM with layer separation following Clean Architecture principles
- Coroutines + StateFlow for reactive state management
- Android's NFC API + the ISO-DEP (ISO 14443-4) protocol for card communication
- A custom EMV parser, written from scratch
No third-party libraries for the parsing — all tag and APDU command handling is a custom implementation, which was honestly the most fun (and most "read the EMVCo spec") part of the project.
The most interesting part, technically
What I got the most out of wasn't Compose or MVVM (I already knew those), but diving headfirst into a real binary protocol: understanding EMV's TLV (Tag-Length-Value) format, building a parser to recognize it, and mapping all that into a UI that makes sense to someone with zero protocol knowledge. Watching the command exchange between phone and card happen live on screen — something that normally takes milliseconds and stays completely invisible — was the whole point of the project.
Try it out
git clone https://github.com/Pedro-kt/tap-to-pay-android.git
Requires an Android device with NFC and API 35 (Android 15) or higher. The repo has full build and install instructions.
Repo: https://github.com/Pedro-kt/tap-to-pay-android
If you're into the EMV protocol, NFC on Android, or just want to see another example of Clean Architecture + MVVM with Compose, go take a look at the code. Feedback, issues, and PRs are all welcome — and if you find it useful, a star ⭐ on the repo goes a long way in helping it reach more people.
Have you worked with NFC or EMV protocols on any project? I'd love to compare approaches — comments are open.




Top comments (0)