> For the complete documentation index, see [llms.txt](https://docs.verifone.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.verifone.com/psdk-latest/reference-material/how-tos/reading-nfc-tag-uids-and-msr-t2.md).

# Reading NFC Tag UIDs & MSR T2

## Reading NFC Tag UIDs and MSR Track 2 Data from a POS Application

{% hint style="info" %}
This page explains how a third-party POS application running on a Verifone Android terminal can read NFC/RFID tag UIDs and Magnetic Stripe Reader (MSR) Track 2 data via AGPA's **PSDK** interface.

This is a common requirement for loyalty, fidelity, and stored-value use cases where the POS app needs to identify a card or tag but is **not** processing an EMV payment.
{% endhint %}

## NFC / RFID Tag UID Reading

### How it works

On Verifone Android terminals, the NFC hardware is connected to the secure processor. **Standard Android NFC APIs (`android.nfc.*`) do not work** the NFC reader is not accessible to third-party apps directly.

The correct approach is to use PSDK `CardAcquisitionRequest` (also referred to as `requestCardData`). This starts a card read session via AGPA, and the tag UID is returned in the `PaymentAccountRef` field of the `CardInformation` response.

This has been validated on the following tag types:

<table><thead><tr><th width="602.888916015625">Tag Type</th><th>Readable</th></tr></thead><tbody><tr><td>NXP NTAG213 (NfcA / MifareUltralight / Ndef)</td><td>✅ Yes</td></tr><tr><td>NXP MIFARE Classic 1K (NfcA / MifareClassic)</td><td>✅ Yes</td></tr><tr><td>NXP MIFARE Ultralight C (NfcA / MifareUltralight)</td><td>✅ Yes</td></tr><tr><td>MIFARE DESFire EV1 2K / 4K / 8K</td><td>✅ Yes</td></tr><tr><td>NTAG213 sticker</td><td>✅ Yes</td></tr><tr><td>MIFARE Classic 1K wristband</td><td>✅ Yes</td></tr></tbody></table>

{% hint style="info" %}
Only the UID/serial number is returned. Sector data and NDEF payload are not accessible via this interface.
{% endhint %}

### Prerequisites

#### 1. Enable NFC Detection in the Merchant container

In VHQ, set the following parameter on the terminal's Merchant container:

```none
com.verifone → Merchant → NfcDetectionEnabled = 1
```

Without this, the NFC reader will not respond to tag taps during a card acquisition session.

#### 2. AGPA version requirement (for RFID-only acquisition)

If you intend to request **only** the RFID presentation method (rather than allowing all methods), your terminal must be running **AGPA 5.350.0.13**.

{% hint style="danger" %}
Earlier builds have a defect where starting a `CardAcquisition` with only `PresentationMethod.RFID` selected causes the card reader service to enter an undefined state and fail to read the tag.
{% endhint %}

{% hint style="warning" %}
**Workaround for older builds:** pass an empty presentation methods list (equivalent to all methods accepted) the RFID tap will still be detected. See code example below.
{% endhint %}

### PSDK Integration

#### Step 1: Start a CardAcquisition with no presentation methods (simplest / most compatible)

Passing an empty `presentationMethods` list defaults to all methods being accepted. This is the recommended starting point and works on all AGPA versions.

```java
import com.verifone.payment_sdk.CardAcquisitionRequest;
import com.verifone.payment_sdk.PresentationMethod;

// Start card acquisition — empty list = all presentation methods accepted
ArrayList<PresentationMethod> presentationMethods = new ArrayList<>();

mTransactionManager.requestCardData("Tap your loyalty card", presentationMethods);
```

#### Step 2: Receive the UID in the CardInformationReceivedEvent callback

Implement `handleCardInformationReceivedEvent` in your `CommerceListener`:

```java
@Override
public void handleCardInformationReceivedEvent(CardInformationReceivedEvent event) {
    if (CardInformationReceivedEvent.TYPE_CARD_DATA.equals(event.getType())) {
        CardInformation cardInfo = event.getCardInformation();
        if (cardInfo != null) {
            String uid = cardInfo.getPaymentAccountRef();
            // uid contains the NFC tag UID, e.g. "10FA43F5"
            Log.d(TAG, "NFC UID: " + uid);
        }
    }
}
```

#### Step 3 (optional): Narrow to RFID-only (requires AGPA 5.350.0.13)

Once you have confirmed the basic read works, you can restrict to RFID only to avoid unintended EMV card taps triggering the session:

```java
ArrayList<PresentationMethod> presentationMethods = new ArrayList<>();
presentationMethods.add(PresentationMethod.RFID);

mTransactionManager.requestCardData("Tap your loyalty card", presentationMethods);
```

#### Using CardAcquisitionRequest.create() directly

If you prefer the full `CardAcquisitionRequest` builder (equivalent to `requestCardData2` in PaymentFlowDemo):

```java
ArrayList<PresentationMethod> presentationMethods = new ArrayList<>();
// Add PresentationMethod.RFID here, or leave empty for all methods

CardAcquisitionRequest request = CardAcquisitionRequest.create(
    false,                   // backgroundRead
    "Tap your loyalty card", // display message
    presentationMethods,     // presentation methods (empty = all)
    null,                    // loyalty data
    null,                    // allowed brands (null = all)
    null,                    // additional data
    false                    // silent
);

mTransactionManager.requestCardData2(request);
```

***

## MSR Track 2 Reading

MSR Track 2 data is also accessible via the `CardAcquisitionRequest` interface. To enable MSR reading, include `PresentationMethod.MAG_STRIPE` in the presentation methods list (or pass an empty list to accept all methods including MSR):

```java
ArrayList<PresentationMethod> presentationMethods = new ArrayList<>();
presentationMethods.add(PresentationMethod.MAG_STRIPE);

mTransactionManager.requestCardData("Swipe your card", presentationMethods);
```

The Track 2 data is returned in the `CardInformation` object within the `CardInformationReceivedEvent` callback. The presentation method on the returned `CardInformation` will be `PresentationMethod.MAG_STRIPE`.

{% hint style="danger" %}
**BIN whitelist requirement:** The full PAN will only be returned if the card's BIN range has been whitelisted in the SDI configuration files on the terminal. Cards whose BIN falls outside the whitelisted ranges will have their PAN truncated or masked in the Track 2 data. Ensure the BIN ranges for the loyalty/fidelity cards you intend to read are added to the SDI configuration before deploying.
{% endhint %}

{% hint style="danger" %}
If the card is also an EMV chip card, AGPA may prefer chip or contactless depending on terminal configuration. Restricting to `MAG_STRIPE` only will force the swipe path.
{% endhint %}

***

## Available PresentationMethod Values

The full set of `PresentationMethod` enum values that can be passed to a `CardAcquisitionRequest`:

<table><thead><tr><th width="208.4444580078125">Value</th><th>Description</th></tr></thead><tbody><tr><td><code>MAG_STRIPE</code></td><td>Magnetic stripe swipe</td></tr><tr><td><code>CHIP</code></td><td>EMV contact chip</td></tr><tr><td><code>CTLS_CARD</code></td><td>Contactless card</td></tr><tr><td><code>CTLS_PHONE</code></td><td>Contactless phone / device</td></tr><tr><td><code>CTLS_MAG_STRIPE</code></td><td>Contactless mag stripe fallback</td></tr><tr><td><code>KEYED</code></td><td>Manual key entry</td></tr><tr><td><code>MANUAL</code></td><td>Manual entry (alternate)</td></tr><tr><td><code>RFID</code></td><td>NFC / RFID tag</td></tr><tr><td><code>SCANNED</code></td><td>Barcode / QR scan</td></tr><tr><td><code>FILE</code></td><td>File-based card data</td></tr><tr><td><code>CHIP_SYNCHRONOUS</code></td><td>Synchronous chip</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.verifone.com/psdk-latest/reference-material/how-tos/reading-nfc-tag-uids-and-msr-t2.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
