DEV Community

Cover image for EMV and Android Terminals: An Introduction to Chip Payment Architecture
Pedro Bustamante
Pedro Bustamante

Posted on

EMV and Android Terminals: An Introduction to Chip Payment Architecture

If you've ever wondered what actually happens between the moment you insert or tap your card on a payment terminal and the "Approved" message on screen, this article is for you. We'll walk through the EMV standard and how it fits into an Android-based payment terminal, without assuming you already know the payments world.

What is EMV and why does it exist?

EMV stands for Europay, Mastercard, and Visa — the three companies that, back in the 1990s, created a common standard so chip cards could be processed securely and interoperably on any terminal worldwide. Today the standard is managed by EMVCo, a consortium that also includes American Express, Discover, JCB, and UnionPay.

Before EMV, cards relied almost exclusively on the magnetic stripe, which is easy to clone because the data is static — it always reads the same way. EMV solved this by introducing a cryptographic microchip into the card that can:

  • Authenticate that the card is genuine (not cloned).
  • Generate a unique cryptogram per transaction.
  • Decide, together with the terminal, whether the transaction should be approved offline, sent online, or declined.

This is what makes cloning a chip card far harder than cloning a magnetic stripe.

The flow of an EMV transaction

At a high level, a chip transaction follows these steps:

  1. Application selection: the terminal and the card agree on which "payment application" to use (Visa, Mastercard, etc.), since a chip can contain several.
  2. Initiate application processing: the terminal reads the card's public data (cardholder name, expiration date, etc.).
  3. Data authentication: the terminal verifies, using public-key cryptography, that the chip's data hasn't been tampered with (SDA, DDA, or CDA, depending on the security level).
  4. Processing restrictions: the terminal checks that the card isn't expired and is compatible with it.
  5. Cardholder verification: PIN, signature, or "no verification," depending on the amount and card type.
  6. Terminal risk management: the terminal decides whether it needs online approval.
  7. Terminal/card action analysis: the chip, using its own internal logic, decides whether to approve offline, request going online, or decline.
  8. Online processing (if applicable): the transaction is sent to the card issuer.
  9. Completion: the final cryptogram is generated and the card is updated.

All of this happens in under a second, and the component that orchestrates this process inside the terminal is what's known as the EMV kernel.

What is the EMV kernel?

The EMV kernel is the software component (certified by EMVCo) that implements the specification's logic: it knows how to talk to the card's chip (contact or contactless/NFC), what data to request, in what order, and how to make risk decisions. There are brand-specific kernels (a Visa kernel, a Mastercard kernel, an Amex kernel, etc.) because each network has its own variations on top of EMVCo's base specification — especially in the contactless world.

This kernel typically lives in a low-level layer, close to the hardware, and not in the Android application layer that the developer sees.

Typical architecture of an Android terminal

This is where Android comes in. More and more payment terminals (known as Smart POS) use Android as their operating system instead of closed proprietary systems. This makes it possible to build point-of-sale apps with the same tools used for any Android app: Kotlin/Java, Android Studio, modern SDKs.

But there's a key difference from a regular smartphone: an Android payment terminal is split into two separate worlds.

1. The "open" world (standard Android)

This is where the Android OS runs as we know it, with its apps, activities, services, etc. This is where the developer builds the point-of-sale interface: product catalog, cart, reports, backend integration, and so on.

2. The "secure" world (PCI PTS / Secure Element)

Terminals certified under PCI PTS (PIN Transaction Security) isolate everything related to handling sensitive data — reading the chip, capturing the PIN, encrypting card data — in a separate, certified environment, often a Secure Element (SE) or a dedicated secure processor. This environment runs the EMV kernel and is not directly accessible from the "application" Android side.

Communication between both worlds happens through a manufacturer SDK (e.g., from PAX, Verifone, Ingenico/Worldline, Newland, etc.), which exposes a high-level API like:

// Conceptual example, not a real SDK
val request = TransactionRequest(
    amount = 15000, // in cents
    currency = "USD",
    transactionType = TransactionType.SALE
)

posSdk.startTransaction(request) { result ->
    when (result) {
        is TransactionResult.Approved -> showApproved(result.receipt)
        is TransactionResult.Declined -> showDeclined(result.reason)
        is TransactionResult.Error -> showError(result.exception)
    }
}
Enter fullscreen mode Exit fullscreen mode

As the developer of the point-of-sale app, you never touch the chip or the PIN directly: the SDK returns a result already processed by the certified EMV kernel. This is intentional and required by PCI rules: no sensitive card data should ever pass through uncertified application code.

Why does this separation matter?

This "two worlds" architecture exists for a very concrete reason: certification and liability. Certifying a full Android app under PCI PTS would be unworkable, since Android changes constantly. Instead, the manufacturer certifies the secure environment and the EMV kernel once, and exposes a stable API so thousands of developers can build on top of it without going through that process themselves.

In short:

Layer Responsibility Certified by
Android app (UI, business logic) User experience, backend integration The developer (no PCI required)
Manufacturer SDK Bridge between app and secure environment The terminal manufacturer
EMV kernel / Secure environment Chip reading, PIN, cryptograms EMVCo + PCI SSC

Contactless: the NFC variant

It's worth mentioning that EMV isn't just "contact chip." The EMV Contactless standard defines how to do the same thing over NFC, enabling both tap cards and phone-based payments (Google Pay, Apple Pay) and, more recently, Tap to Phone, where the Android phone itself acts as the terminal, using its NFC antenna to read the customer's card or wallet. This adds its own set of brand-specific contactless kernels, with risk rules that differ from the contact chip.

If you want to see this flow working in real code, I built tap-to-pay-android, an open-source, educational EMV card reader over NFC written in Kotlin/Jetpack Compose. It implements the full sequence — PPSE selection, AID discovery, the GPO command, record reading, and EMV tag parsing — and displays the details of every tag read, including an AIP bit decoder and Luhn-based PAN validation. I also wrote a dedicated article about this project explaining why reading a card over NFC is more interesting than it sounds: Reading EMV cards over NFC on Android.

Conclusion

At its core, EMV is a trust protocol: it gives the terminal, the card, and the issuer a common language to decide, in milliseconds, whether a transaction is legitimate. When that protocol is implemented on top of Android, the key to understanding the architecture is remembering that the open operating system and the secure payment environment are separate worlds by design, connected through a well-defined SDK.

Top comments (0)