> 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 pago con código QR

## Resumen

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

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

## Integración del SDK

### Comprobar 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;
}
```

### Crear los datos de entrada de pago QR

Crear `PaymentInputData`Contiene los parámetros de la transacción usados para construir la carga útil de pago QR.

Use `PaymentInputData.PaymentInputBuilder` con:

* `withQRCodePaymentParameters` para proporcionar `amount`, `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 el código QR tiene los siguientes campos.

| Campo          | Formato                       | Longitud     | Requisito | Descripción                                                                      |
| -------------- | ----------------------------- | ------------ | --------- | -------------------------------------------------------------------------------- |
| `aid`          | Hexadecimal (ISO/IEC 7816-5)  | 5 a 16 bytes | Requerido | Use `"0000000000"` para permitir que el SDK use el AID primario.                 |
| `amount`       | 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. 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.                                                    |

### Generar datos de pago 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 maneja 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. Vea [Realizar la 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 una falla durante el pago con código QR.
* `onNextTransactionReady`

  El SDK ha terminado la desactivación del servicio de pago. Este callback solo se desencadena después de que se complete la generación del código QR. Úselo para recuperar el estado de desactivación y verificar 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 ha sido procesado y es exitoso.


        //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 manejar 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.
      	//Recuperar 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.
         	// Verificar si se necesita reabastecimiento.
          if (digitalizedCardStatus.needsReplenishment())
          {
               // lógica para activar el proceso de reabastecimiento.
          }else{
              // lógica para activar el restablecimiento de la tarjeta predeterminada.
          }
      }
    }
```

{% endcode %}

### Obtener datos de pago QR

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

`QRCodeData` contiene los siguientes campos.

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

### Manejar palabra de estado

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

* `9000` indica una generación de carga útil exitosa. Puede leer los otros campos en `QRCodeData`.
* Otros valores indican una falla. No use los otros campos en `QRCodeData`.

Consulte la tabla a continuación 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 en el <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 requerido, CDCVM local ingresado, etc. 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 la 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 excede el límite definido por el emisor.</td></tr><tr><td>6986</td><td>El importe de la transacción excede el límite definido por el usuario final.</td></tr><tr><td>6985</td><td>Se alcanzó el límite de ATC, o el AID seleccionado no corresponde a una aplicación de pago que cumpla con esta especificación.</td></tr></tbody></table>

### Manejar errores

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

Si los datos de entrada son null, 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 se ha establecido una tarjeta predeterminada.                           | Establezca 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 `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 son invá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.                                   | Reabastezca las credenciales antes de intentar otro pago.                                                                                                                                      |

### Generar y mostrar 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 SDK de NFC Wallet.

Después de generar los datos de pago del 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.

Varias bibliotecas están 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.
