> 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/es/implement-nfc-wallet/make-payment/other-payment-methods/implement-qr-code-payment.md).

# Implementar pagos con código QR

## Resumen

El SDK de Wallet NFC solo admite pagos con código QR para tarjetas EMV PURE de marca blanca de Thales.

Antes de implementar pagos con código QR, complete **Tokenización**. Consulte [Tokenizar una tarjeta](/nfc-wallet-sdk-ios/es/implement-nfc-wallet/tokenize-a-card.md).

## Integración del SDK

### Compruebe los requisitos previos

Confirme que la tarjeta digitalizada admite pagos con código QR usando `DigitalizedCardDetails.paymentTypeSupported()`. Esta API devuelve una lista de tipos de pago compatibles. Verifique que `PaymentType.QR` está presente.

```java
public boolean isQRCodeSupported(DigitalizedCardDetails card) {
    final PaymentType[] supported = card.paymentTypeSupported();

    for (PaymentType p : supported) {
        if (p == PaymentType.QR) {
            return true;
        }
    }
    return false;
}
```

### Cree los datos de entrada del pago con QR

Cree `PaymentInputData`. Contiene los parámetros de la transacción usados para construir la carga útil del pago con código QR.

Use `PaymentInputData.PaymentInputBuilder` con:

* `withQRCodePaymentParameters` para proporcionar `importe`, `currencyCode` y `countryCode`
* `withPureQRCodePaymentParameters` para proporcionar `idd` (iddData) y `aid` (aidData)

Use los siguientes valores de ejemplo como marcadores de posición.

```java
String QR_NOMINAL_VALID_AID = “0000000000”;
String QR_NOMINAL_VALID_AMOUNT =  “000000000500”;
char currencyCode = 789;
String QR_NOMINAL_VALID_IDD = “000000000000000000000000000000”;

PaymentInputData paymentInputData = new PaymentInputData.PaymentInputBuilder(PaymentType.QR)
                .withQRCodePaymentParameters(QR_NOMINAL_VALID_AMOUNT, QR_NOMINAL_VALID_CURRENCY, (char)0)
                .withPureQRCodePaymentParameters(QR_NOMINAL_VALID_IDD.getBytes(), QR_NOMINAL_VALID_AID.getBytes())
                .build();
```

`PaymentInputData` para código QR tiene los siguientes campos.

| Campo          | Formato                       | Longitud        | Requisito | Descripción                                                                      |
| -------------- | ----------------------------- | --------------- | --------- | -------------------------------------------------------------------------------- |
| `aid`          | Hexadecimal (ISO/IEC 7816-5)  | De 5 a 16 bytes | Requerido | Use `"0000000000"` para permitir que el SDK use el AID principal.                |
| `importe`      | Hexadecimal codificado en BCD | 6 bytes         | Requerido | Importe de la transacción en formato BCD. Ejemplo: 5,22 EUR es `"000000000522"`. |
| `currencyCode` | Numérico 3 (ISO-4217)         | 3 caracteres    | Requerido | Moneda de la transacción. Por ejemplo, use `"978"` para EUR.                     |
| `countryCode`  | Numérico 3 (ISO 3166-1)       | 3 caracteres    | Requerido | Código de país de la transacción.                                                |
| `idd`          | Hexadecimal                   | 15 bytes        | Opcional  | Datos específicos del emisor.                                                    |

### Genere los datos de pago con QR

En su aplicación de billetera digital, llame a `PaymentBusinessService.generateApplicationCryptogram()` usando el tipo de pago `PaymentType.QR` para generar la carga útil que se codificará en un código QR.

Debe implementar un `QRCodePaymentServiceListener`.

```java
final PaymentBusinessService pbs = PaymentBusinessManager.getPaymentBusinessService();
pbs.generateApplicationCryptogram(
        PaymentType.QR, 
        paymentInputData, 
        qrCodePaymentServiceListener);
```

### Implemente `QRCodePaymentServiceListener`

El listener del código QR gestiona los eventos durante la generación del código QR.

El listener del código QR tiene cuatro callbacks:

* `onAuthenticationRequired`

  El SDK indica que se requiere verificación CDCVM. Consulte [Realizar verificación CDCVM](/nfc-wallet-sdk-android/es/implement-nfc-wallet/make-payment/implement-contactless-payments/5.-perform-cdcvm-verification.md).
* `onDataReadyForPayment`

  Los datos de salida del código QR están listos.
* `onError`

  El SDK ha encontrado un fallo durante el pago con código QR.
* `onNextTransactionReady`

  El SDK ha finalizado la desactivación del servicio de pago. Este callback solo se activa después de que se complete la generación del código QR. Úselo para recuperar el estado de desactivación y comprobar el estado de la tarjeta digitalizada.

El siguiente fragmento de código muestra una implementación básica del listener:

{% code expandable="true" %}

```java
QRCodePaymentServiceListener l = new QRCodePaymentServiceListener() {

    @Override
    public void onDataReadyForPayment(PaymentService paymentService,TransactionContext transactionContext) {
        //El pago se ha procesado y se ha completado correctamente.


        //Recupere los datos de salida del código QR generados por el SDK
        //para que la MPA construya la carga útil y genere el símbolo del código QR
        QRCodeData qrCodeData = paymentService.getQRCodeData();

        // Lógica para mostrar el código QR en la pantalla
    }

    @Override
    public void onAuthenticationRequired(PaymentService activatedPaymentService, CHVerificationMethod cvm, long cvmResetTimeout)
        //El SDK solicita que se realice una verificación CVM.

        if (chVerificationMethod == CHVerificationMethod.DEVICE_KEYGUARD) {
            // Lógica para usar el bloqueo del dispositivo para la verificación CVM
        } else if (chVerificationMethod == CHVerificationMethod.BIOMETRICS) {
            // Lógica para usar la biometría para la verificación CVM
        }

    }

    @Override
    public void onError(TransactionContext transactionContext, PaymentServiceErrorCode paymentServiceErrorCode, String s) {
        // Lógica para gestionar un error durante el pago.
    }

		@Override
    public void onNextTransactionReady(DeactivationStatus deactivationStatus, DigitalizedCardStatus digitalizedCardStatus, DigitalizedCard        		digitalizedCard) {
        // El proceso de desactivación del servicio de pago ha finalizado.
      	//Recupere el estado de desactivación
      if (deactivationStatus.getSdkStatusCode() == DEACTIVATION_SUCCESS) {
           // El proceso de desactivación ha finalizado correctamente. Listo para realizar el siguiente pago.
      else{
          // El proceso de desactivación ha fallado.
         	// Compruebe si es necesario reponer.
          if (digitalizedCardStatus.needsReplenishment())
          {
               // lógica para activar el proceso de reposición.
          }else{
              // lógica para activar el restablecimiento de la tarjeta predeterminada.
          }
      }
    }
```

{% endcode %}

### Obtenga los datos de pago con QR

Obtener `QRCodeData` cuando `QRCodePaymentServiceListener.onDataReadyForPayment()` se activa.

`QRCodeData` contiene los siguientes campos.

| Campo                  | Descripción                                                                                                                |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `statusWord`           | Palabra de estado de la transacción. `9000` indica éxito. Consulte [Gestión de la palabra de estado](#handle-status-word). |
| `cid`                  | Datos de información del criptograma. Determina si CDCVM es necesario para esta transacción.                               |
| `chipDataField`        | Campo de datos del chip calculado por NFC, incluido el criptograma.                                                        |
| `condensedPaymentData` | No aplicable.                                                                                                              |
| `cardMainAid`          | AID principal utilizado para el pago.                                                                                      |
| `cardMainAppTemplate`  | Plantilla principal de la aplicación utilizada para el pago.                                                               |
| `cardAliasAid`         | AID alternativo utilizado para el pago.                                                                                    |
| `cardAliasAppTemplate` | Plantilla alternativa de la aplicación utilizada para el pago.                                                             |
| `commonDataTemplate`   | Plantilla de datos comunes calculada durante el pago.                                                                      |

### Gestión de la palabra de estado

Compruebe siempre `statusWord` antes de usar cualquier otro campo.

* `9000` indica una generación correcta de la carga útil. Puede leer los demás campos en `QRCodeData`.
* Otros valores indican un fallo. No use los demás campos en `QRCodeData`.

Consulte la tabla siguiente para más detalles:

<table><thead><tr><th width="225">Valor de la palabra de estado</th><th>Descripción</th></tr></thead><tbody><tr><td>9000</td><td><p>Una transacción exitosa. Todos los campos del <code>QRCodeData</code> objeto están disponibles si el <code>cid</code> valor es <code>0x8x</code>.<br>Donde:</p><ul><li>El primer dígito indica "Solicitud de procesar la transacción en línea".</li><li>El segundo dígito indica información CVM, como Sin CVM requerida, CDCVM local introducida, y así sucesivamente. Si el CID no está en el formato 0x8x, los campos están vacíos.</li></ul></td></tr><tr><td>6989</td><td>Se requiere verificación del cliente debido a los valores CIAC y no se define ningún método en el Control de Aplicación.</td></tr><tr><td>6988</td><td>No se permite un importe de transacción cero.</td></tr><tr><td>6987</td><td>El importe de la transacción supera el límite definido por el emisor.</td></tr><tr><td>6986</td><td>El importe de la transacción supera el límite definido por el usuario final.</td></tr><tr><td>6985</td><td>Se ha alcanzado el límite ATC, o el AID seleccionado no se refiere a una aplicación de pago compatible con esta especificación.</td></tr></tbody></table>

### Gestione los errores

Cuando se llame a `QRCodePaymentServiceListener#onError(…)` la función, se proporcionarán un código de error y un mensaje.

Si los datos de entrada son nulos, están vacíos o el listener no es una instancia de `QRCodePaymentServiceListener`, se lanzará una `IllegalArgumentException` con un mensaje.

La siguiente tabla muestra los códigos de error del código QR:

| Código de error                 | Descripción                                                                 | Acción recomendada                                                                                                                                                                             |
| ------------------------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NO_DEFAULT_CARD`               | No hay ninguna tarjeta predeterminada configurada.                          | Configure una tarjeta predeterminada antes de iniciar un pago con código QR.                                                                                                                   |
| `QR_CODE_PAYMENT_NOT_SUPPORTED` | La tarjeta predeterminada no admite pagos con código QR.                    | Llamar a `DigitalizedCardDetails#paymentTypeSupported()` y verifique `PaymentType.QR` está presente.                                                                                           |
| `QR_CODE_WRONG_STATE`           | El servicio de pago ya está activado cuando inicia un pago con código QR.   | Si el usuario final cancela CDCVM, llame a `PaymentBusinessService#deactivate()`.                                                                                                              |
| `QR_CODE_INPUT_INVALID`         | Los datos de entrada están presentes, pero uno o más campos no son válidos. | Proporcione datos de entrada válidos e incluya todos los campos requeridos. El SDK valida la estructura JSON, los valores hexadecimales, los rangos de valores y las longitudes de los campos. |
| `QR_CODE_OUTPUT_INVALID`        | Los datos de salida no se pueden analizar y no están disponibles.           | Trate el pago con código QR como fallido y no muestre el código QR.                                                                                                                            |
| `CARD_OUT_OF_PAYMENT_KEYS`      | No hay credenciales de pago disponibles.                                    | Reponga las credenciales antes de intentar otro pago.                                                                                                                                          |

### Genere y muestre la imagen del código QR

Su aplicación de billetera digital genera la carga útil del código QR usando los datos proporcionados por el NFC Wallet SDK.

Después de generar los datos de pago con código QR, su aplicación de billetera digital debe:

* Construir un símbolo de carga útil usando uno de los criptogramas generados por el SDK.
* Codificar en Base64.
* Mostrar el símbolo del código QR.

Hay varias bibliotecas disponibles, como la biblioteca ZXing, para renderizar el código QR.

Su aplicación de billetera digital puede elegir el nivel de corrección (L, M, Q, H) para ajustar la corrección de errores.


---

# 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/es/implement-nfc-wallet/make-payment/other-payment-methods/implement-qr-code-payment.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.
