> For the complete documentation index, see [llms.txt](https://docs.payments.thalescloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payments.thalescloud.io/nfc-wallet-sdk-android/implement-nfc-wallet/make-payment/implement-contactless-payments/2.-implement-contactless-payment-callbacks.md).

# 2. Implement contactless payment callbacks

## Overview

During APDU processing, NFC Wallet SDK calls your application with payment lifecycle events.

Implement `ContactlessPaymentServiceListener` in your digital wallet application to:

* Detect when a contactless transaction starts and completes.
* Trigger step-up authentication when CDCVM is required.
* Handle errors and recover for the next transaction.

## SDK integration

### Implement `ContactlessPaymentServiceListener`

Create a listener instance and implement the callbacks you need.

```java
// Instantiate a listener for the HCE service.
PaymentServiceListener myPaymentListener = new ContactlessPaymentServiceListener() {

    @Override
    public void onTransactionStarted() {
        /*
         * Triggered when the first APDU is exchanged with the POS terminal.
         */
    }

    @Override
    public void onAuthenticationRequired(
            PaymentService activatedPaymentService,
            CHVerificationMethod chVerificationMethod,
            long cvmResetTimeout) {
        /*
         * Triggered when the end user must authenticate (CDCVM).
         *
         * Use chVerificationMethod to determine the required method.
         * cvmResetTimeout applies only to some methods (for example, wallet PIN).
         * Use it to tell the end user how long the verification stays valid.
         */
    }

    @Override
    public void onReadyToTap(PaymentService paymentService) {
        /*
         * Triggered after successful authentication.
         * Prompt the end user to tap again before cvmResetTimeout expires.
         */
    }

    @Override
    public void onTransactionCompleted(TransactionContext transactionContext) {
        /*
         * Triggered when the transaction completes successfully.
         * Use TransactionContext to display details (amount, date, and more).
         */
    }

    @Override
    public void onTransactionInterrupted() {
        /*
         * Triggered when the NFC link to the POS terminal is interrupted.
         * Prompt the end user to tap again.
         * Optional callback
         */
    }

    @Override
    public void onError(
            TransactionContext transactionContext,
            PaymentServiceErrorCode paymentServiceErrorCode,
            String message) {
        /*
         * Triggered when the transaction cannot complete successfully.
         */
    }

    @Override
    public void onFirstTapCompleted() {
        /*
         * Indicates the first-tap APDU processing completed.
         * Supported only for PFP-based transactions.
         */
    }

    @Override
    public void onNextTransactionReady(
            DeactivationStatus deactivationStatus,
            DigitalizedCardStatus digitalizedCardStatus,
            DigitalizedCard digitalizedCard) {
        /*
         * Triggered after a transaction completes.
         * Use it to verify the card state and prepare for the next payment.
         */
    }
};
```

### Return the listener from your HCE service

In your class extending `AsyncHCEService`, return the listener from `setupListener()`.

```java
public class MyHCEService extends AsyncHCEService {

    @Override
    public PaymentServiceListener setupListener() {
        return myPaymentListener;
    }
}
```

## Callback flow (typical)

Callbacks are usually triggered in this order.

`onTransactionInterrupted()` can occur any time after `onTransactionStarted()`.

1. `onTransactionStarted()` after the first APDU exchange with the POS terminal.
2. `onAuthenticationRequired()` when the end user must complete CDCVM.
3. `onReadyToTap()` after successful authentication, to request a second tap.
4. `onTransactionCompleted()` when the transaction completes successfully.
5. `onTransactionInterrupted()` (optional) when the NFC link to the POS terminal drops. See [Handle POS terminal disconnects](#handle-pos-terminal-disconnects-optional).
6. `onNextTransactionReady()` when the SDK is ready for the next transaction.

If an error occurs, the SDK triggers `onError()` instead of completing the flow.

## Handle POS terminal disconnects (optional)

The SDK can notify you when the NFC link to the POS terminal is interrupted.

Use `onTransactionInterrupted()` to prompt the end user to tap again.

Configure the retry behavior before starting contactless payments:

* `PaymentSetting.setRetryLimit(int)`

  Sets how many POS terminal disconnects are tolerated before failing the transaction.

  Default is `0`.

  With `0`, the SDK triggers `onError()` on the first disconnect.
* `PaymentSetting.setTransactionRetryTimeout(long)`

  Sets how long the POS terminal can retry after a disconnect.

  If no APDU is received during this interval, the SDK triggers `onError()`.

  Range is `500` to `10000` milliseconds.

  Default is `2000` milliseconds.


---

# 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.payments.thalescloud.io/nfc-wallet-sdk-android/implement-nfc-wallet/make-payment/implement-contactless-payments/2.-implement-contactless-payment-callbacks.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.
