Crear Códigos QR

Nota

Esta especificación está sujeta a cambios. El estándar colombiano EASPBV está evolucionando para soportar las capacidades de la red Bre-B. Passport colabora activamente con entidades del sector para definir un modelo robusto y flexible de integración de códigos QR para pagos en tiempo real.

Visión General

Este endpoint permite crear un Código QR compatible con Bre-B utilizando la API de la Plataforma PaaS de Passport. El código QR codifica información de pago y metadatos contextuales de acuerdo con el estándar colombiano EASPBV, devolviendo un identificador único del QR y los detalles asociados.

Tipos de QR

Bre-B maneja 2 tipos funcionales:

  1. Estático (STATIC):

    • No lleva valor (sin amount).

  2. Dinámico (DYNAMIC)

    • Siempre lleva valor (con amount).

    • No existe QR dinámico sin valor.

Importante

QRs dinámicos, “valor” (sin el objeto amount definido) no es válido.

Detalles del Endpoint

Parámetro

Descripción

Endpoint

https://api.paas.sandbox.co.passportfintech.com/v1/qrcodes

Método

POST

Encabezados

Content-Type: application/json, Authorization

Autenticación

Token de Acceso (Bearer Token)

Reglas de Importe (Tag 54)

El Tag 54 (amount.value) es el único valor monetario que Bre-B utiliza para procesar el pago.

  • El importe que se envía en amount.value debe incluir ya sumado cualquier:

    • TIP

    • INC

    • VAT

Cuerpo de la Solicitud

Parámetro

Tipo

Cardinalidad

Descripción

key_id

String

Obligatorio

ID único de la llave Bre-B asociada a la cuenta del comercio.

customer_id

String

Obligatorio

ID único del cliente (comercio) que inicia la transacción.

type

ENUM

Obligatorio

Tipo de código QR: STATIC o DYNAMIC.

channel

ENUM

Obligatorio

Canal en el cual se presentará el QR: MAN, POS, APP, ECOMM, MPS, ATM.

additional_info

Objeto

Obligatorio VER SECCION: Regla de Obligatoriedad.

Objeto con metadatos adicionales de la transacción.

additional_info.transaction_purpose

ENUM

Obligatorio

Finalidad de la transacción: 00: Compras 02: Anulaciones 03: Transferencias 04: Retiro 05: Recaudo 06: Recargas 07: Depósito

Se debe enviar el código de 2 dígitos.

qr_code_reference

String

Obligatorio

Referencia única que se puede añadir y enviar a la red bre-b, relacionada con el pago.

Máximo 17 caracteres alfanuméricos. La letra P no está permitida.

Luego en Bre-B la lógica interna le agrega a ese campo el identificador del adquirente “CO.COM.VISI.TRXID” y la letra P que corresponde a una identificación interna del Nodo.

Por ejemplo. Si se envía a plataforma Passport PaaS al crear el QR

qr_code_reference:"11213344556677889"

Al recibir el pago de ese QR se obtendrá:

qr_code_reference:"CO.COM.VISI.TRXIDP11213344556677889"

additional_info.invoice_number

String

Opcional

Número de factura (máx. 25 caracteres).

additional_info.mobile_phone_number

String

Opcional

Número móvil vinculado a la transacción.

additional_info.store_label

String

Opcional

Identificador de tienda.

additional_info.loyalty_label

String

Opcional

Referencia a programa de lealtad del comprador.

additional_info.reference_label

String

Opcional

Referencia única de la transacción.

additional_info.customer_label

String

Opcional

Identificador único del comprador.

additional_info.terminal_label

String

Obligatorio

ID del terminal de punto de venta (POS).

additional_info.customer_info

ENUM

Opcional

Datos por solicitar al consumidor:

Usar uno de los DIGITOs:

A - Direccion del comprador.

M - Número móvil del comprador.

E - Email del comprador.

additional_info.channel_presentation

String

Opcional

Código de 3 dígitos que indica cómo fue presentado el QR.

vat

Objeto

Condicional

Información del IVA si se incluye monto. Obligatorio para QR dinámicos.

vat.vat_type

ENUM

Condicional

Tipo de cálculo del IVA: FIXED, PERCENTAGE, WALLET.

vat.vat_value

String

Condicional

Valor fijo en COP o porcentaje (5 decimales).

vat.vat_base

String

Condicional

Base del valor sobre el cual se calcula el IVA.

inc

Objeto

Condicional

Información del INC. Aplicable si se incluye monto.

inc.inc_type

ENUM

Condicional

Tipo de cálculo del INC: FIXED, PERCENTAGE, WALLET.

inc.inc_value

String

Condicional

Valor fijo en COP o porcentaje (5 decimales).

amount

Objeto

Opcional

Valor de la transacción codificada en el QR.

amount.value

String

Opcional

Valor del pago (e.g., "100000.00").

amount.currency

ENUM

Opcional

Debe ser COP.

tip

Objeto

Opcional

Información sobre propina (opcional).

tip.tip_type

ENUM

Opcional

Método de cálculo: REQUEST, FIXED, PERCENTAGE.

tip.tip_value

String

Opcional

Requerido si el tipo es FIXED.

tip.tip_percentage

String

Opcional

Requerido si el tipo es PERCENTAGE.

Regla de Obligatoriedad - Objeto: additional_info

El objeto additional.info es opcional. Si se incluye, debe contener obligatoriamente los parámetros terminal_label y transaction_purpose.

Ejemplo de Solicitud

curl --location 'https://api.paas-sandbox.co.passportfintech.com/v1/qrcodes' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --data '{ "key_id": "e7f75ffc-22b8-4cfe-884b-8ebcb008b680", "customer_id": "31eb66c3-f309-48ce-8b12-086f9e76b84c", "type": "DYNAMIC", "channel": "MPOS", "vat": { "vat_type": "FIXED", "vat_value": "100.00", "vat_base_value": "100.00" }, "inc": { "inc_type": "FIXED", "inc_value": "10.00" }, "amount": { "value": "100000.00", "currency": "COP" }, "additional_info":{ "transaction_purpose": "00", "invoice_number": "123", "terminal_label": "01", "store_label": "sasc0193", "mobile_phone_number": "3503503456", "loyalty_label": "1234", "reference_label": "pago impuesto", "customer_label": "0001", "customer_info": "EMAIL", "channel_presentation": "400" }, "qr_code_reference": "uniquereferencefortracking" }'
curl --location 'https://api.paas.sandbox.co.passportfintech.com/v1/qrcodes' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer YOUR_ACCES_TOKEN' \ --data '{ "key_id": "e7f75ffc-22b8-4cfe-884b-8ebcb008b680", "customer_id": "31eb66c3-f309-48ce-8b12-086f9e76b84c", "type": "STATIC", "channel": "POS", "additional_info":{ "transaction_purpose": "PURCHASE" } }'

Cuerpo de la Respuesta

  • Código HTTP: 201 Created.

  • Retorna un código QR creado y asociado a los metadatos de la solicitud.

Ejemplo de Respuesta

{ "created_at": "2025-05-12T20:30:17.547227Z", "qr_code_data": "00020101021226550015CO.COM.VISI.LLA0332jimmyjohns1111402545255@test.com49270015CO.COM.VISI.RED0104VISI52045782530317054130000100000.005802CO5919Test Business O9F126006Bogota61059827362120808PURCHASE80290017CO.COM.VISI.CANAL0104MPOS81260016CO.COM.VISI.CIVA01020282290015CO.COM.VISI.IVA0106100.0083300016CO.COM.VISI.BASE0106100.0084260016CO.COM.VISI.CINC01020285280015CO.COM.VISI.INC010510.0090610017CO.COM.VISI.TRXID01364A07229A-7B14-4B63-85D5-79572E130E0763040351", "qr_code_image": "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", "acquirer_network_identifier": "VISI", "inc": { "inc_value": "10.00", "inc_type": "FIXED" }, "key_id": "7756cfcb-0d28-4e89-bbc0-d4ebdc5b6ca1", "id": "7aa184b7-c549-467b-917f-460b4224b459", "entity_customer_id": "0d93dea5-00c4-4a9e-b3fa-cbaf5280818b", "merchant": { "merchant_category_code": "1234", "country": "CO", "merchant_name": "Test Business O9F12", "merchant_city": "Bogota", "merchant_zip_code": "98273" }, "status": "ACTIVE", "type": "DYNAMIC", "key": { "key_type": "EMAIL", "key_value": "jimmyjohns1111402545255@test.com" }, "channel": "MPOS", "amount": { "currency": "COP", "value": "100000" }, "additional_info": { "transaction_purpose": "00" }, "vat": { "vat_type": "FIXED", "vat_value": "100.00", "vat_base_value": "100.00" }, "qr_code_reference": "uniquereferencefortracking" }
{ "customer_id": "31eb66c3-f309-48ce-8b12-086f9e76b84c", "status": "ACTIVE", "key": { "key_type": "ID", "key_value": "36606864" }, "type": "STATIC", "qr_code_data": "00020101021126310015CO.COM.VISI.LLA01083660686449270015CO.COM.VISI.RED0104VISI5204578253031705802CO5914Merchant CWSPZ6006Bogota61059827362120808PURCHASE80280017CO.COM.VISI.CANAL0103POS90310017CO.COM.VISI.TRXID010600000063045CB4", "acquirer_network_identifier": "VISI", "created_at": "2025-10-10T11:47:52.365840Z", "additional_info": { "transaction_purpose": "PURCHASE" }, "key_id": "e7f75ffc-22b8-4cfe-884b-8ebcb008b680", "merchant": { "merchant_category_code": "0412", "merchant_country": "CO", "merchant_name": "Merchant CWSPZ", "merchant_city": "Medellin", "merchant_post_code": "101010" }, "channel": "POS", "id": "ffd0d013-1fe9-4b36-bf3f-9d9850b5b638" }
Importante
  1. La respuesta de Códigos QR incluye la imagen en formato Base64. Puedes usar cualquier librería de frontend para convertirla en una imagen legible para tu audiencia.

  2. Los códigos QR también son visibles en el dashboard para fines de validación.

  3. El id que se devuelve es el qr_code_id, el cual se puede usar en otras peticiones

Errores Comunes y Manejo

Código HTTP

Significado

Descripción

400 Bad Request

Datos inválidos

Faltan campos requeridos o contienen valores incorrectos.

401 Unauthorized

Token inválido

El token de acceso ha expirado o es inválido.

403 Forbidden

Acceso denegado

La solicitud no está autorizada para validar la entidad.

500 Server Error

Error del servidor

Se produjo un error inesperado al procesar la validación.

Buenas Prácticas

  • Verifica que el key_id y customer_id sean válidos y estén asociados correctamente.

  • Usa el campo channel_presentation para detallar cómo y dónde se muestra el QR.

  • Si se incluye un monto, asegúrate de incluir los objetos vat e inc con la estructura y tipos adecuados

Consideraciones para Lectura de QRs e iniciación de Pagos

INC, VAT y TIP son Informativos (no sumables al pagar)

Al leer un QR, aunque aparezcan campos INC, VAT y TIP, estos son informativos.

  • Si se crea un pago, NO se deben sumar esos valores al importe.

  • El pago se crea solo con el amount.value

Lectura de QR Estático (Sin Importe):

Al leer un QR STATIC, se debe validar si contiene importe (amount.value):

  • Si NO tiene importe: solicitar en la terminal que el cliente ingrese el valor.

  • Si SÍ tiene importe: es un QR “híbrido” y el cliente puede modificar el valor a enviar en el pago.

QR Dinámico Sin Valor: Inválido

Un QR dinámico sin valor no debe aceptarse.