Especificación Técnica Servicio API QR MLD con OAUTH 2.0
1. INTRODUCCION
El presente documento describe los lineamientos y especificaciones técnicas para la integración con la API de Generación y Consulta de Códigos QR MLD de ATC (Redenlace Bolivia). El servicio permite a establecimientos y aplicaciones cliente generar códigos QR de cobro y verificar el estado de las transacciones asociadas.
La integración contempla los siguientes flujos:
- Autenticación mediante OAuth 2.0 (Client Credentials) para obtención del Access Token.
- Generación de un código QR de pago.
- Verificación del estado de la transacción QR.
- Notificación automática de pago confirmado mediante Webhook.
Credenciales
El Token Basic (Authorization), el client_id y el access_token de producción son proporcionados exclusivamente por ATC para cada integrador habilitado. Los valores mostrados en este documento corresponden únicamente al ambiente de pruebas.
Todos los servicios de la API requieren el envío de los siguientes encabezados HTTP en cada petición. El Access Token debe obtenerse previamente mediante el servicio de autenticación OAuth 2.0 (ver sección 3.1).
| Header | Descripción | Oblig. | Ejemplo |
|---|
Authorization | Token de autorización. Se envía como Bearer seguido del access_token obtenido en la autenticación. | Sí | Bearer 1442981c-....-....-b...-ea12258c9... |
client_id | Identificador único del cliente integrador. Proporcionado por ATC. | Sí | 1e063b89-....-....-....-ed73d60cbc67 |
Content-Type | Formato del cuerpo de la petición. Para todos los servicios JSON. | Sí | application/json |

Autenticación previa obligatoria
Para obtener el access_token que se usa en el header Authorization, primero debe invocarse el servicio de autenticación OAuth (sección 3.1). El token Basic requerido en ese paso es provisto por ATC.
3. GENERAR TRANSACCION QR
3.1. Autenticación — Obtención del Access Token
Antes de poder generar un QR, el integrador debe obtener un Access Token válido mediante el flujo OAuth 2.0 Client Credentials.
| Atributo | Valor |
|---|
| Método HTTP | POST |
| URL (TEST) | /oauth-client-credentials/access-token?grant_type=client_credentials |
| Content-Type | application/x-www-form-urlencoded |
| Query Param | grant_type=client_credentials |
Request — Autenticación (obtener Access Token)
600;">POST /oauth-client-credentials/access-token?grant_type=client_credentials
Headers:
Authorization: Basic ODBiM2M1NWQtNWNiNi00OWRlLTkxYTAtMDcwZDM1M2IwMDQ3OmQ2OWVlZjQxLTFkMmYtNDBlZC1iNGQ0LTc5MzFiYjljYmI3NA==
Content-Type: application/x-www-form-urlencoded
600;">POST /oauth-client-credentials/access-token?grant_type=client_credentials
Headers:
Authorization: Basic ODBiM2M1NWQtNWNiNi00OWRlLTkxYTAtMDcwZDM1M2IwMDQ3OmQ2OWVlZjQxLTFkMmYtNDBlZC1iNGQ0LTc5MzFiYjljYmI3NA==
Content-Type: application/x-www-form-urlencoded
Response — Access Token
{
"access_token": "1442981c-....-....-b...-ea12258c9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "api.qr"
}
{
"access_token": "1442981c-....-....-b...-ea12258c9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "api.qr"
}
| Header | Descripción | Obligatorio |
|---|
Authorization | Codificado en Base64 (client_id:client_secret). | Sí |
Content-Type | application/x-www-form-urlencoded | Sí |
Respuesta exitosa — Access Token
| Campo | Tipo | Descripción |
|---|
access_token | String | Token de portador para usar en los headers de los servicios QR. |
token_type | String | Tipo de token. Siempre Bearer. |
expires_in | Integer | Tiempo de validez en segundos. |
scope | String | Alcance del token otorgado. |
3.2 Servicio de Generación de QR
Una vez obtenido el Access Token, se puede invocar el servicio de generación del código QR de pago.
| Atributo | Valor |
|---|
| Método HTTP | POST |
| URL | /qr/mld/v2/generate |
Header: access_token | {access_token obtenido en autenticación} |
Header: client_id | {provisto por APP al momento de tener un cliente en el devportal} |
Header: Content-Type | application/json |
Request — Generar QR
600;">POST /qr/mld/v2/generate
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-....-....-....-ed73d60cbc67
Content-Type: application/json
600;">POST /qr/mld/v2/generate
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-....-....-....-ed73d60cbc67
Content-Type: application/json
Campos del Request Body
{
"glosa": "Pago de servicio",
"moneda": "BOB",
"monto": 10.5,
"numeroReferencia": "4024",
"vigencia": 45,
"idEstablecimiento": 422717,
"nombreEstablecimiento": "Tienda Central",
"webhook": {
"url": "https://dominio.com/qr/confirmed",
"key": "x-api-key",
"value": "46bc-b2a2-ea12258c99ab"
}
}
{
"glosa": "Pago de servicio",
"moneda": "BOB",
"monto": 10.5,
"numeroReferencia": "4024",
"vigencia": 45,
"idEstablecimiento": 422717,
"nombreEstablecimiento": "Tienda Central",
"webhook": {
"url": "https://dominio.com/qr/confirmed",
"key": "x-api-key",
"value": "46bc-b2a2-ea12258c99ab"
}
}
| Campo | Tipo | Obligatorio | Descripción |
|---|
glosa | String | Sí | Descripción del pago o concepto del cobro. Ej: Pago de servicio. |
moneda | String | Sí | Código ISO de moneda. Valores permitidos: BOB. |
monto | Decimal | Sí | Importe del pago. Máximo 2 decimales. Ej: 10.50. |
numeroReferencia | String | Sí | Referencia interna del sistema originante (asignada por el integrador). Ej: 2320. |
vigencia | Integer | Sí | Tiempo de validez del QR en segundos. Ej: 45. |
idEstablecimiento | Integer | Sí | Identificador del establecimiento registrado en ATC. Ej: 422717. |
nombreEstablecimiento | String | Sí | Nombre del establecimiento habilitado. Ej: Tienda Central. |
webhook.url | String | Si | Endpoint que recibirá la confirmación del pago. |
webhook.key | String | Si | Nombre de la cabecera utilizada para autenticación del webhook. |
webhook.value | String | Si | Valor de autenticación enviado en la cabecera del webhook. |
Campos de la Respuesta Exitosa
Response — QR generado
{
"success": true,
"message": "QR generado exitosamente",
"data": {
"numeroReferencia": "153980",
"estado": "PENDIENTE",
"fechaExpiracion": "2026-03-12T18:01:52.304302",
"moneda": "BOB",
"monto": 10.5,
"numeroReferenciaOriginante": "2320",
"qr": "iVBORw0KGgoAAAANSUhEUgAAAT8AAAE/CAYAAAAwps..."
}
}
{
"success": true,
"message": "QR generado exitosamente",
"data": {
"numeroReferencia": "153980",
"estado": "PENDIENTE",
"fechaExpiracion": "2026-03-12T18:01:52.304302",
"moneda": "BOB",
"monto": 10.5,
"numeroReferenciaOriginante": "2320",
"qr": "iVBORw0KGgoAAAANSUhEUgAAAT8AAAE/CAYAAAAwps..."
}
}
| Campo | Tipo | Descripción |
|---|
success | Boolean | true si el QR se generó correctamente. |
message | String | Mensaje descriptivo del resultado de la operación. |
data.numeroReferencia | String | Referencia interna asignada por ATC a la transacción QR. Usar este valor para consultas posteriores. |
data.estado | String | Estado inicial del QR recién generado. Siempre PENDIENTE. |
data.fechaExpiracion | String (ISO 8601) | Fecha y hora de expiración del QR. Formato: yyyy-MM-dd'T'HH:mm:ss. |
data.moneda | String | Moneda de la transacción. Ej: BOB. |
data.monto | Decimal | Importe del QR generado. |
data.numeroReferenciaOriginante | String | Referencia interna del sistema integrador tal como fue enviada en el request. |
data.qr | String (Base64) | Imagen PNG del código QR codificada en Base64. Decodificar para mostrar al usuario. |
4. Verificar Estado QR
Permite consultar el estado actual de un QR previamente generado. Se usa el numeroReferencia interno asignado por ATC (campo data.numeroReferencia de la respuesta de generación), no el numeroReferencia originante del integrador.
| Atributo | Valor |
|---|
| Método HTTP | GET |
| ENDPOINT | /qr/mld/v2/verify/153980 |
Header: access_token | {access_token obtenido en autenticación} |
Header: client_id | {provisto por la APP al momento de tener un cliente en el devportal} |
Header: Content-Type | application/json |
| Parámetro de ruta | {numeroReferencia} — Referencia interna ATC. Ej: 153980 |
Request — Consulta de Estado
600;">GET /qr/mld/v2/verify/153980
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-....-....-....-ed73d60cbc67
Content-Type: application/json
600;">GET /qr/mld/v2/verify/153980
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-....-....-....-ed73d60cbc67
Content-Type: application/json
4.1 Campos de la Respuesta Exitosa
{
"success": true,
"message": "Estado de QR consultado exitosamente",
"data": {
"estado": "PENDIENTE",
"mensaje": "QR generado, esperando pago",
"importe": 10.5,
"moneda": "BOB",
"numeroReferenciaOriginante": "4023",
"numeroReferencia": "200393",
"clienteOrigen": {
"nombreCliente": "",
"numeroCuenta": "",
"ciNitCliente": ""
},
"bancoOrigen": {
"numeroOrdenAch": "",
"codigoBanco": "",
"nombreBanco": "",
"fechaTransaccion": ""
}
}
}
{
"success": true,
"message": "Estado de QR consultado exitosamente",
"data": {
"estado": "PENDIENTE",
"mensaje": "QR generado, esperando pago",
"importe": 10.5,
"moneda": "BOB",
"numeroReferenciaOriginante": "4023",
"numeroReferencia": "200393",
"clienteOrigen": {
"nombreCliente": "",
"numeroCuenta": "",
"ciNitCliente": ""
},
"bancoOrigen": {
"numeroOrdenAch": "",
"codigoBanco": "",
"nombreBanco": "",
"fechaTransaccion": ""
}
}
}
| Campo | Tipo | Descripción |
|---|
estado | String | Nombre del estado de la transacción. Valores posibles: PENDIENTE, PAGADO, CANCELADO, EXPIRADO, ERROR. |
mensaje | String | Mensaje descriptivo del estado de la transacción. |
importe | Decimal (BigDecimal) | Monto de la transacción. |
moneda | String | Moneda de la transacción. Ej: BOB. |
numeroReferenciaOriginante | String | Referencia del sistema integrador enviada al generar el QR. |
numeroReferencia | String | Referencia interna del sistema ATC. |
clienteOrigen | Object | Datos del cliente pagador. Ver estructura ClienteOrigen. |
bancoOrigen | Object | Datos del banco del pagador. Ver estructura BancoOrigen. |
Estructura Cliente Origen
| Campo | Tipo | Descripción |
|---|
nombreCliente | String | Nombre completo del titular de la cuenta pagadora. |
numeroCuenta | String | Número de cuenta bancaria del pagador. |
ciNitCliente | String | Número de CI o NIT del pagador. |
Estructura Banco Origen
| Campo | Tipo | Descripción |
|---|
nombreBanco | String | Nombre de la entidad financiera del pagador. |
fechaTransaccion | String (ISO 8601) | Fecha y hora en que se procesó el pago en el banco. |
numeroOrdenAch | String | Número de orden de ACH. |
codigoBanco | String | Código de la entidad financiera del pagador. |
4.2 Webhook — Notificación de Pago
Cuando el cliente realiza el pago del QR, ATC envía automáticamente una notificación HTTP POST a la Webhook (Url, key, Value) especificada al generar el QR. El cuerpo del POST sigue exactamente la misma estructura de la respuesta de consulta de estado (sección 4.1).
| Atributo | Descripción |
|---|
| Método HTTP | POST (enviado por ATC al sistema del integrador) |
| URL destino | La webhookUrl especificada al generar el QR. |
| Content-Type enviado | application/json |
| Respuesta esperada | El servidor del integrador DEBE responder HTTP 200 para confirmar recepción. |
Webhook — Notificación POST recibida por el integrador
POST https://dominio.com/qr/confirmed
POST https://dominio.com/qr/confirmed
Body (enviado por ATC):
{
"detalleRespuesta": "Transacción procesada correctamente",
"codigoRespuesta": "SUCCESS",
"numeroReferencia": "233324",
"monto": 10.5,
"fechaHoraTransaccion": "2026-05-26T14:35:20",
"moneda": "BOB",
"clienteOrigen": {
"ciCliente": "12345678",
"nombreCliente": "Juan Perez",
"numeroCuenta": "1234567890"
},
"bancoOrigen": {
"codigoBanco": "101",
"nombreBanco": "Banco Unión",
"numeroOrdenAch": "987654321"
}
}
{
"detalleRespuesta": "Transacción procesada correctamente",
"codigoRespuesta": "SUCCESS",
"numeroReferencia": "233324",
"monto": 10.5,
"fechaHoraTransaccion": "2026-05-26T14:35:20",
"moneda": "BOB",
"clienteOrigen": {
"ciCliente": "12345678",
"nombreCliente": "Juan Perez",
"numeroCuenta": "1234567890"
},
"bancoOrigen": {
"codigoBanco": "101",
"nombreBanco": "Banco Unión",
"numeroOrdenAch": "987654321"
}
}
Validación del Webhook: Procesar el pago únicamente cuando sea (Exitoso/Pagado). Validar que el numeroReferencia y el importe coincidan con la transacción.
4.3 Respuesta de Error — Consulta Estado
Response — Error (referencia no encontrada)
{
"success": false,
"message": "Error al consultar estado de QR",
"errors": [
{
"field": "numeroReferencia",
"message": "Transacción no encontrada con número de referencia: 260825000010075",
"code": "TRANSACCION_NO_ENCONTRADA"
}
]
}
{
"success": false,
"message": "Error al consultar estado de QR",
"errors": [
{
"field": "numeroReferencia",
"message": "Transacción no encontrada con número de referencia: 260825000010075",
"code": "TRANSACCION_NO_ENCONTRADA"
}
]
}
| Campo | Tipo | Descripción |
|---|
success | Boolean | false en caso de error en la consulta. |
message | String | Descripción general del error. |
errors[].field | String | Campo que originó el error. |
errors[].message | String | Descripción detallada del error. |
errors[].code | String | Código de error interno. Ej: TRANSACCION_NO_ENCONTRADA. |
5. Estado
El campo estado de la respuesta de consulta y del webhook devuelve un valor de texto que describe el estado actual de la transacción QR.
5.1 Valores del campo estado
| Estado | Descripción | Acción recomendada |
|---|
PENDIENTE | El QR fue generado correctamente. Aún no se ha registrado ningún pago ni interacción. | Esperar el webhook o consultar nuevamente según el tiempo de vigencia. |
PAGADO | El pago fue confirmado y procesado exitosamente. | Acreditar el pago en el sistema. Estado final positivo. |
CANCELADO | El QR fue cancelado antes de completarse el pago. | Informar al usuario. Generar un nuevo QR si corresponde. |
EXPIRADO | El tiempo de vigencia del QR transcurrió sin que se realizara el pago. | Informar al usuario. Generar un nuevo QR si corresponde. |
ERROR | Ocurrió un error en el procesamiento de la transacción. | Revisar el campo mensaje. Contactar a ATC si el error persiste. |
5.3 Estado del QR (generación)
| Valor | Descripción |
|---|
PENDIENTE | Estado inicial al generar el QR. El cliente aún no realizó el pago. |
ERROR | Ocurrió un error en el procesamiento de la transacción. |
6. Ejemplos
6.1 Generar Transacción QR
Request — Autenticación (obtener Access Token)
600;">POST /oauth-client-credentials/access-token?grant_type=client_credentials
Headers:
Authorization: Basic ODBiM2M1NWQtNWNiNi00OWRlLTkxYTAtMDcwZDM1M2IwMDQ3OmQ2OWVlZjQxLTFkMmYtNDBlZC1iNGQ0LTc5MzFiYjljYmI3NA==
Content-Type: application/x-www-form-urlencoded
600;">POST /oauth-client-credentials/access-token?grant_type=client_credentials
Headers:
Authorization: Basic ODBiM2M1NWQtNWNiNi00OWRlLTkxYTAtMDcwZDM1M2IwMDQ3OmQ2OWVlZjQxLTFkMmYtNDBlZC1iNGQ0LTc5MzFiYjljYmI3NA==
Content-Type: application/x-www-form-urlencoded
Response — Access Token
{
"access_token": "1442981c-....-....-b...-ea12258c9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "api.qr"
}
{
"access_token": "1442981c-....-....-b...-ea12258c9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "api.qr"
}
Request — Generar QR
600;">POST /desarrollo/qr/mld/v2/generate
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-33cb-4a13-a625-ed73d60cbc67
Content-Type: application/json
600;">POST /desarrollo/qr/mld/v2/generate
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-33cb-4a13-a625-ed73d60cbc67
Content-Type: application/json
{
"glosa": "Pago de servicio",
"moneda": "BOB",
"monto": 10.5,
"numeroReferencia": "4024",
"vigencia": 45,
"idEstablecimiento": 422717,
"nombreEstablecimiento": "Tienda Central",
"webhook": {
"url": "https://dominio.com/qr/confirmed",
"key": "x-api-key",
"value": "46bc-b2a2-ea12258c99ab"
}
}
{
"glosa": "Pago de servicio",
"moneda": "BOB",
"monto": 10.5,
"numeroReferencia": "4024",
"vigencia": 45,
"idEstablecimiento": 422717,
"nombreEstablecimiento": "Tienda Central",
"webhook": {
"url": "https://dominio.com/qr/confirmed",
"key": "x-api-key",
"value": "46bc-b2a2-ea12258c99ab"
}
}
Response — QR generado
{
"success": true,
"message": "QR generado exitosamente",
"data": {
"numeroReferencia": "153980",
"estado": "PENDIENTE",
"fechaExpiracion": "2026-03-12T18:01:52.304302",
"moneda": "BOB",
"monto": 10.5,
"numeroReferenciaOriginante": "2320",
"qr": "iVBORw0KGgoAAAANSUhEUgAAAT8AAAE/CAYAAAAwps..."
}
}
{
"success": true,
"message": "QR generado exitosamente",
"data": {
"numeroReferencia": "153980",
"estado": "PENDIENTE",
"fechaExpiracion": "2026-03-12T18:01:52.304302",
"moneda": "BOB",
"monto": 10.5,
"numeroReferenciaOriginante": "2320",
"qr": "iVBORw0KGgoAAAANSUhEUgAAAT8AAAE/CAYAAAAwps..."
}
}
6.2 Verificar Estado QR
Request — Consulta de Estado
600;">GET /qr/mld/v2/verify/153980
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-....-....-....-ed73d60cbc67
Content-Type: application/json
600;">GET /qr/mld/v2/verify/153980
Headers:
access_token: 1442981c-....-....-b...-ea12258c9...
client_id: 1e063b89-....-....-....-ed73d60cbc67
Content-Type: application/json
Response — Estado QR (pago exitoso)
{
"success": true,
"message": "Estado de QR consultado exitosamente",
"data": {
"estado": "PENDIENTE",
"mensaje": "QR generado, esperando pago",
"importe": 10.5,
"moneda": "BOB",
"numeroReferenciaOriginante": "4023",
"numeroReferencia": "153980",
"clienteOrigen": {
"nombreCliente": "",
"numeroCuenta": "",
"ciNitCliente": ""
},
"bancoOrigen": {
"numeroOrdenAch": "",
"codigoBanco": "",
"nombreBanco": "",
"fechaTransaccion": ""
}
}
}
{
"success": true,
"message": "Estado de QR consultado exitosamente",
"data": {
"estado": "PENDIENTE",
"mensaje": "QR generado, esperando pago",
"importe": 10.5,
"moneda": "BOB",
"numeroReferenciaOriginante": "4023",
"numeroReferencia": "153980",
"clienteOrigen": {
"nombreCliente": "",
"numeroCuenta": "",
"ciNitCliente": ""
},
"bancoOrigen": {
"numeroOrdenAch": "",
"codigoBanco": "",
"nombreBanco": "",
"fechaTransaccion": ""
}
}
}
Response — Error (referencia no encontrada)
{
"success": false,
"message": "Error al consultar estado de QR",
"errors": [
{
"field": "numeroReferencia",
"message": "Transacción no encontrada con número de referencia: 260825000010075",
"code": "TRANSACCION_NO_ENCONTRADA"
}
]
}
{
"success": false,
"message": "Error al consultar estado de QR",
"errors": [
{
"field": "numeroReferencia",
"message": "Transacción no encontrada con número de referencia: 260825000010075",
"code": "TRANSACCION_NO_ENCONTRADA"
}
]
}
Webhook — Notificación POST recibida por el integrador
POST https://dominio.com/qr/confirmed
POST https://dominio.com/qr/confirmed
Body (enviado por ATC):
{
"detalleRespuesta": "Transacción procesada correctamente",
"codigoRespuesta": "SUCCESS",
"numeroReferencia": "233324",
"monto": 10.5,
"fechaHoraTransaccion": "2026-05-26T14:35:20",
"moneda": "BOB",
"clienteOrigen": {
"ciCliente": "12345678",
"nombreCliente": "Juan Perez",
"numeroCuenta": "1234567890"
},
"bancoOrigen": {
"codigoBanco": "101",
"nombreBanco": "Banco Unión",
"numeroOrdenAch": "987654321"
}
}
{
"detalleRespuesta": "Transacción procesada correctamente",
"codigoRespuesta": "SUCCESS",
"numeroReferencia": "233324",
"monto": 10.5,
"fechaHoraTransaccion": "2026-05-26T14:35:20",
"moneda": "BOB",
"clienteOrigen": {
"ciCliente": "12345678",
"nombreCliente": "Juan Perez",
"numeroCuenta": "1234567890"
},
"bancoOrigen": {
"codigoBanco": "101",
"nombreBanco": "Banco Unión",
"numeroOrdenAch": "987654321"
}
}
7. Ambientes
El siguiente cuadro contiene los datos de los ambientes disponibles con la URL base y el tipo de token requerido. Las credenciales específicas (Token Basic, client_id, access_token) son proporcionadas por ATC para cada ambiente y cada integrador habilitado.
| Ambiente | URL Base | Credenciales | Estado |
|---|
| Desarrollo | https://atcgwapitest.redenlace.com.bo/desarrollo/ | Provisto por ATC | Activo |
| Certificación | https://atcgwapitest.redenlace.com.bo/sandbox/ | Provisto por ATC | Activo |
| Producción | https://api.redenlace.com.bo/ | Provisto por ATC | Restringido |