QR de comerciante EMVCo
La especificación de código QR de EMVCo es el formato TLV que subyace a la mayoría de los sistemas nacionales de pago móvil: PIX (Brasil), PromptPay (Tailandia), UPI (India), SGQR (Singapur), DuitNow (Malasia), BPS PayNow (Singapur) y muchos más. Entender el formato base EMVCo significa entender una docena de derivados regionales a la vez.
Canonical spec:EMV QR Code Specification for Payment Systems, Merchant Presented Mode v1.1 (2020) and Consumer Presented Mode v1.1 (2020).
Encoding: TLV (Tag-Length-Value) with 2-digit tags, 2-digit lengths, variable value. CRC16-CCITT trailer for integrity.
Encoding: TLV (Tag-Length-Value) with 2-digit tags, 2-digit lengths, variable value. CRC16-CCITT trailer for integrity.
Merchant Presented vs Consumer Presented
- MPM (Merchant Presented Mode). QR estático o dinámico mostrado por el comerciante. El consumidor lo escanea desde su app bancaria/cartera y autoriza el pago. El 99% de los pagos QR del mundo real usan MPM.
- CPM (Consumer Presented Mode). La app del consumidor genera un QR de corta duración (generalmente 30–60 segundos); el comerciante lo escanea. Menos común; usado donde la conectividad del consumidor es poco fiable (India rural pre-ubiquidad UPI, algunos sistemas de MRT/tránsito).
Estructura MPM
El payload MPM es una secuencia plana de registros TLV terminada por un CRC:
| Tag | Nombre | Longitud | Notas |
|---|---|---|---|
00 | Indicador de formato de payload | 2 | Siempre 01. |
01 | Método de inicio | 2 | 11 estático / 12 dinámico. |
02–51 | Información de cuenta del comerciante | variable | Específico del esquema. Cada esquema reserva su propia etiqueta: PIX usa 26, UPI también usa 26, SGQR usa 51. |
52 | Código de categoría del comerciante (MCC) | 4 | ISO 18245 4-digit code. |
53 | Divisa de la transacción | 3 | ISO 4217 numeric. 840=USD, 978=EUR, 356=INR, 986=BRL, 764=THB. |
54 | Importe de la transacción | variable | Decimal como cadena. Omitir para QRs de importe en el escaneo. |
58 | Código de país | 2 | ISO 3166 alpha-2. |
59 | Nombre del comerciante | variable | Máximo 25 caracteres según spec; muchos esquemas relajan esto. |
60 | Ciudad del comerciante | variable | Máximo 15 caracteres. |
62 | Plantilla de datos adicionales | variable | Referencia de factura, fidelización, ID de terminal. |
63 | CRC | 4 | CRC16-CCITT sobre todo lo anterior a esta etiqueta. |
Vectores de prueba canónicos
| Caso | Entradas | TLV inicial esperado |
|---|---|---|
| Static MPM, USD, sin importe | merchant=Acme Corp | 00020101021152045999...53037405802US5909Acme Corp6009LAS VEGAS |
| Dynamic MPM, EUR, importe 25.00 | (same)amount=25.00 | Starts 000201010212 (POI method 12 = dynamic), incluye 540525.00. |
Errores comunes
- CRC calculado incorrectamente. El CRC16-CCITT cubre el payload COMPLETO incluyendo la etiqueta
63y la longitud04, todo hasta pero sin incluir el valor CRC de 4 dígitos. La mayoría de los errores provienen de calcularlo solo sobre el payload o incluir el propio valor CRC. - El campo de longitud tiene 2 dígitos. Incluso un valor de 1 carácter toma longitud
01. Un valor de 100 caracteres toma longitud??, pero EMVCo limita los valores a 99 caracteres porque la longitud tiene 2 dígitos. Los valores más largos deben dividirse en múltiples sub-TLVs. - El código de divisa es numérico, no alfa. USD es
840, noUSD. EUR es978. BRL es986. ISO 4217 tiene tanto alfa-3 como numérico; EMVCo requiere numérico. - El código de país es alfa-2. US, IN, BR, TH. ISO 3166-1 alfa-2. Curiosamente opuesto a la regla del código de divisa.
- Estático vs dinámico. Si omites el importe (etiqueta
54), usa el método POI11(estático). QR estático + campo de importe es legalmente válido según la spec pero algunas apps lo rechazan. QR dinámico sin importe viola la spec. - Límite de caracteres del nombre del comerciante. Según la spec, máximo 25 caracteres. Algunos esquemas regionales lo relajan (PIX permite 25, SGQR permite 40). Ajusta por esquema si apuntas a un país específico.
- MCC
0000. La spec permite0000como desconocido, pero muchos adquirentes lo rechazan en el cierre. Siempre usa un MCC real cuando lo tengas.
Compatibilidad de escáneres
| App / dispositivo | Soporte | Notas |
|---|---|---|
| App bancaria / cartera | Nativo | Las apps regionales en cada país (Nubank / apps UPI / TrueMoney / GrabPay) analizan el payload EMVCo de forma nativa. |
| Cámara iOS | Cadena en bruto | No reconocido como pago. El usuario debe abrir su app bancaria y escanear desde allí. |
| Cámara Android | Cadena en bruto | Igual, no analizado. |
| Google Lens | Cadena en bruto | Muestra el texto decodificado. |
| Terminales de pago industriales | Nativo | Los escáneres POS modernos incluyen análisis EMVCo en el firmware para los esquemas regionales que soportan. |
Ver también
- /emvco-merchant-qr-code/, generador EMVCo genérico.
- /pix-qr-code/, /upi-qr-code/, /promptpay-qr-code/, variantes regionales.
- /standards/, volver al índice de estándares.