Especificación Técnica Servicio API QR SIMPLE con OAuth 2.0

1. INTRODUCCIÓN

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 SIMPLE 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:

  1. Autenticación mediante OAuth 2.0 (Client Credentials) para obtención del Access Token.
  2. Generación de un código QR de pago.
  3. Verificación del estado de la transacción QR.
  4. 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.
information icon
Las llaves obtenidas a través de este Developer Portal son exclusivamente para el ambiente Sandbox. Para solicitar las llaves de Producción, se debe seguir el siguiente proceso:
  1. Coordinar con el equipo de ATC para realizar las pruebas en el ambiente Sandbox.
  2. Las pruebas en Sandbox deben ser aprobadas por nuestro equipo de integraciones.
  3. Completar el formulario de checklist correspondiente que te otorgará nuestro equipo de integraciones.
  4. Una vez concluidas y aprobadas las pruebas, y con el checklist debidamente llenado, se podrá solicitar la generación de las llaves productivas. Sin la aprobación de las pruebas en Sandbox y el checklist completo, no se generarán llaves de producción.

2. HEADER

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 TRANSACCIÓN 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.

AtributoValor
Método HTTPPOST
URL (TEST)/oauth-client-credentials/access-token?grant_type=client_credentials
Content-Typeapplication/x-www-form-urlencoded
Query Paramgrant_type=client_credentials

Request — Autenticación (obtener Access Token)

http
600;">POST /oauth-client-credentials/access-token?grant_type=client_credentials Headers: Authorization: Basic ODBiM2M1NWQtNWNiNi00OWRlLTkxYTAtMDcwZDM1== Content-Type: application/x-www-form-urlencoded

Header de autenticación

HeaderDescripciónObligatorio
AuthorizationToken Basic. Codificado en Base64 (client_id:client_secret).Sí
Content-Typeapplication/x-www-form-urlencodedSí

Respuesta exitosa — Access Token

json
{ "access_token": "1442981c-....-....-b...-ea12258c9...", "token_type": "Bearer", "expires_in": 3600, "scope": "api.qr" }
CampoTipoDescripción
access_tokenStringToken de portador para usar en los headers de los servicios QR.
token_typeStringTipo de token. Siempre 'Bearer'.
expires_inIntegerTiempo de validez en segundos.
scopeStringAlcance 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.

Request — Generar QR

AtributoValor
Método HTTPPOST
URL/qr/simple/v2/generate
Header: access_token{access_token obtenido en autenticación}
Header: client_id{client_id provisto por ATC}
Header: Content-Typeapplication/json
http
600;">POST /qr/simple/v2/generate Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json

Campos del Request Body

json
{ "glosa": "Pago de servicio", "moneda": "BOB", "monto": 10.5, "numeroReferencia": "4024", "vigencia": 45, "idEstablecimiento": xxxxxx, "nombreEstablecimiento": "Tienda Central", "webhook": { "url": "https://dominio.com/qr/confirmed", "key": "x-api-key", "value": "46bc-b2a2-ea12258c99ab" } }
CampoTipoObligatorioDescripción
glosaStringSíDescripción del pago o concepto del cobro. Ej: 'Pago de servicio'.
monedaStringSíCódigo ISO de moneda. Valores permitidos: BOB.
montoDecimalSíImporte del pago. Máximo 2 decimales. Ej: 10.50.
numeroReferenciaStringSíReferencia interna del sistema originante (asignada por el integrador). Ej: '2320'.
vigenciaIntegerSíTiempo de validez del QR en segundos. Ej: 45.
idEstablecimientoIntegerSíIdentificador del establecimiento registrado en ATC.
nombreEstablecimientoStringSíNombre del establecimiento habilitado. Ej: 'Tienda Central'.
webhook.urlStringSíEndpoint que recibirá la confirmación del pago.
webhook.keyStringSíNombre de la cabecera utilizada para autenticación del webhook.
webhook.valueStringSíValor de autenticación enviado en la cabecera del webhook.

Campos de la Respuesta Exitosa

Response — QR generado

json
{ "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..." } }
CampoTipoDescripción
successBooleantrue si el QR se generó correctamente.
messageStringMensaje descriptivo del resultado de la operación.
data.numeroReferenciaStringReferencia interna asignada por ATC a la transacción QR. Usar este valor para consultas posteriores.
data.estadoStringEstado inicial del QR recién generado. Siempre 'PENDIENTE'.
data.fechaExpiracionString (ISO 8601)Fecha y hora de expiración del QR. Formato: yyyy-MM-dd'T'HH:mm:ss.
data.monedaStringMoneda de la transacción. Ej: 'BOB'.
data.montoDecimalImporte del QR generado.
data.numeroReferenciaOriginanteStringReferencia interna del sistema integrador tal como fue enviada en el request.
data.qrString (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.
AtributoValor
Método HTTPGET
URL/qr/simple/v2/verify/{numeroReferencia}
Header: access_token{access_token obtenido en autenticación}
Header: client_id{client_id provisto por ATC}
Header: Content-Typeapplication/json
Parámetro de ruta{numeroReferencia} — Referencia interna ATC. Ej: 458263
http
600;">GET /qr/simple/v2/verify/1111545 Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json

4.1. Campos de la Respuesta Exitosa

Response — Estado QR (pago exitoso)

json
{ "success": true, "message": "Estado de QR consultado exitosamente", "data": { "estado": "PENDIENTE", "mensaje": "QR generado, esperando pago", "importe": 10.5, "moneda": "BOB", "numeroReferenciaOriginante": "4023", "numeroReferencia": "1111545", "clienteOrigen": { "nombreCliente": "", "numeroCuenta": "", "ciNitCliente": "" }, "bancoOrigen": { "numeroOrdenAch": "", "codigoBanco": "", "nombreBanco": "", "fechaTransaccion": "" } } }
CampoTipoDescripción
estadoStringNombre del estado de la transacción. Valores posibles: PENDIENTE, PAGADO, CANCELADO, EXPIRADO, ERROR.
mensajeStringMensaje descriptivo del estado de la transacción.
importeDecimal (BigDecimal)Monto de la transacción.
monedaStringMoneda de la transacción. Ej: BOB.
numeroReferenciaOriginanteStringReferencia del sistema integrador enviada al generar el QR.
numeroReferenciaStringReferencia interna del sistema ATC.
clienteOrigenObjectDatos del cliente pagador. Ver estructura ClienteOrigen.
bancoOrigenObjectDatos del banco del pagador. Ver estructura BancoOrigen.

Estructura Cliente Origen

CampoTipoDescripción
nombreClienteStringNombre completo del titular de la cuenta pagadora.
numeroCuentaStringNúmero de cuenta bancaria del pagador.
ciNitClienteStringNúmero de CI o NIT del pagador.

Estructura Banco Origen

CampoTipoDescripción
nombreBancoStringNombre de la entidad financiera del pagador.
fechaTransaccionString (ISO 8601)Fecha y hora en que se procesó el pago en el banco.
numeroOrdenAchStringNúmero de orden ACH.
codigoBancoStringCó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).

Webhook — Notificación POST recibida por el integrador

http
POST https://dominio.com/qr/confirmed
AtributoDescripción
Método HTTPPOST (enviado por ATC al sistema del integrador)
URL destinoLa webhookUrl especificada al generar el QR.
Content-Type enviadoapplication/json
Respuesta esperadaEl servidor del integrador DEBE responder HTTP 200 para confirmar recepción.
json
{ "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" } }
information icon
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

json
{ "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" } ] }
CampoTipoDescripción
successBooleanfalse en caso de error en la consulta.
messageStringDescripción general del error.
errors[].fieldStringCampo que originó el error.
errors[].messageStringDescripción detallada del error.
errors[].codeStringCódigo de error interno. Ej: TRANSACCION_NO_ENCONTRADA.

5. CANCELAR QR GENERADO

Permite realizar la cancelación de un QR previamente generado (pero no la cancelación de un QR pagado). Se usa el numeroReferencia interno asignado por ATC (campo data.numeroReferencia de la respuesta de generación), no el numeroReferencia originante del integrador.
AtributoValor
Método HTTPPOST
URL/qr/simple/v2/cancel/{numeroReferencia}
Header: access_token{access_token obtenido en autenticación}
Header: client_id{client_id provisto por ATC}
Header: Content-Typeapplication/json
Parámetro de ruta{numeroReferencia} — Referencia interna ATC. Ej: 11199226
http
600;">POST /qr/simple/v2/cancel/11199226 Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json

5.1. Campos de la Respuesta Exitosa

Response — cancelar QR (cancelación exitosa de un qr generado, pero no pagado)

json
{ "success": true, "message": "Transacción cancelada", "data": { "estado": "CANCELADO", "mensaje": "Transacción cancelada", "importe": 10.50, "moneda": "BOB", "numeroReferenciaOriginante": "7070", "numeroReferencia": "11199226" } }
CampoTipoDescripción
successBooleantrue si la acción de cancelar se ejecutó correctamente.
messageStringMensaje descriptivo del resultado de la operación.
data.estadoStringEstado del QR recién cancelado. mensaje mostrado 'CANCELADO'.
data.mensajeStringMensaje descriptivo del resultado de la operación.
data.importeDecimalImporte del QR de se ha generado y luego ser cancelado.
data.monedaStringMoneda de la transacción. Ej: 'BOB'.
data.numeroReferenciaOriginanteStringReferencia interna del sistema integrador tal como fue enviada en el request.
data.numeroReferenciaStringReferencia interna asignada por ATC a la transacción QR que se ha generado.

5.2. Cuando se realiza la cancelación de un QR cancelado.

Cuando se intenta realizar la cancelación de qr ya cancelado, este retorna un mensaje de error en la operación.

request de cancelación de un QR, con un numeroReferencia ya cancelado

http
600;">POST /qr/simple/v2/cancel/11199226 Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json

Campos de la Respuesta

Response — cancelar QR (cancelación de un qr cancelado, pero no pagado)

json
{ "success": false, "message": "Error al anular QR", "errors": [ { "field": "numeroReferencia", "message": "El QR ya está en estado CANCELADO, no se puede anular (solo se anulan QR en estado PENDIENTE)", "code": "ESTADO_INVALIDO" } ] }
CampoTipoDescripción
successBooleanfalso si la acción de cancelar se ejecutó correctamente.
messageStringMensaje descriptivo del resultado de la operación - Error al anular QR.
errors.fieldStringMensaje descriptivo del campo donde se encuentra el error: numeroReferencia`.
errors.mensajeStringMensaje descriptivo del resultado de la operación.
errors.codeStringMensaje descriptivo del resultado de la operación de codigo: ESTADO_INVALIDO

5.3. Cuando se realiza la cancelación de un QR pagado.

Cuando se intenta realizar la cancelación de qr ya pagado, este retorna un mensaje de error en la operación.

request de cancelación de un QR, con un numeroReferencia ya pagado

http
600;">POST /qr/simple/v2/cancel/11199241 Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json

Campos de la Respuesta

Response — cancelar QR (cancelación de un qr pagado)

json
{ "success": false, "message": "Error al anular QR", "errors": [ { "field": "numeroReferencia", "message": "El QR ya está en estado PAGADO, no se puede anular (solo se anulan QR en estado PENDIENTE)", "code": "ESTADO_INVALIDO" } ] }
CampoTipoDescripción
successBooleanfalse si la acción de cancelar se no ejecutó correctamente.
messageStringMensaje descriptivo del resultado de la operación - Error al anular QR.
errors.fieldStringMensaje descriptivo del campo donde se encuentra el error: numeroReferencia`.
errors.mensajeStringMensaje descriptivo del resultado de la operación.
errors.codeStringMensaje descriptivo del resultado de la operación de codigo: ESTADO_INVALIDO

6. 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.

6.1. Valores del campo estado

EstadoDescripciónAcción recomendada
PENDIENTEEl 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.
PAGADOEl pago fue confirmado y procesado exitosamente.Acreditar el pago en el sistema. Estado final positivo.
CANCELADOEl QR fue cancelado antes de completarse el pago.Informar al usuario. Generar un nuevo QR si corresponde.
EXPIRADOEl tiempo de vigencia del QR transcurrió sin que se realizara el pago.Informar al usuario. Generar un nuevo QR si corresponde.
ERROROcurrió un error en el procesamiento de la transacción.Revisar el campo mensaje. Contactar a ATC si el error persiste.

6.2. Estado del QR (generación)

ValorDescripción
PENDIENTEEstado inicial al generar el QR. El cliente aún no realizó el pago.
ERROROcurrió un error en el procesamiento de la transacción.

7. EJEMPLOS

7.1. Generar Transacción QR

Request — Autenticación (obtener Access Token)

http
600;">POST /oauth-client-credentials/access-token?grant_type=client_credentials Headers: Authorization: Basic ODBiM2M1NWQtNWNiNi00OWRlLTkxYTAtMDcwZDM1M2IwMDQ== Content-Type: application/x-www-form-urlencoded

Response — Access Token

json
{ "access_token": "1442981c-....-....-b...-ea12258c9...", "token_type": "Bearer", "expires_in": 3600, "scope": "api.qr" }

Request — Generar QR

http
600;">POST /qr/simple/v2/generate Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json
json
{ "glosa": "Pago de servicio", "moneda": "BOB", "monto": 10.5, "numeroReferencia": "4024", "vigencia": 45, "idEstablecimiento": xxxxxx, "nombreEstablecimiento": "Tienda Central", "webhook": { "url": "https://dominio.com/qr/confirmed", "key": "x-api-key", "value": "46bc-b2a2-ea12258c99ab" } }

Response — QR generado

json
{ "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..." } }

7.2. Verificar Estado QR

Request — Consulta de Estado

http
600;">GET /qr/simple/v2/verify/1111545 Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json

Response — Estado QR (pago exitoso)

json
{ "success": true, "message": "Estado de QR consultado exitosamente", "data": { "estado": "PENDIENTE", "mensaje": "QR generado, esperando pago", "importe": 10.5, "moneda": "BOB", "numeroReferenciaOriginante": "4023", "numeroReferencia": "1111545", "clienteOrigen": { "nombreCliente": "", "numeroCuenta": "", "ciNitCliente": "" }, "bancoOrigen": { "numeroOrdenAch": "", "codigoBanco": "", "nombreBanco": "", "fechaTransaccion": "" } } }

Response — Error (referencia no encontrada)

json
{ "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

http
POST https://dominio.com/qr/confirmed
json
{ "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.3. CANCELAR QR

Request — CANCELAR QR

http
600;">POST /qr/simple/v2/cancel/11199226 Headers: access_token: 1442981c-....-....-b...-ea12258c9... client_id: 1e063b89-....-....-....-ed73d60cbc67 Content-Type: application/json

Response — CANCELAR QR (Consulta Exitosa)

json
{ "success": true, "message": "Transacción cancelada", "data": { "estado": "CANCELADO", "mensaje": "Transacción cancelada", "importe": 10.50, "moneda": "BOB", "numeroReferenciaOriginante": "7070", "numeroReferencia": "11199226" } }

Response — Error (QR ya pagado)

json
{ "success": false, "message": "Error al anular QR", "errors": [ { "field": "numeroReferencia", "message": "El QR ya está en estado PAGADO, no se puede anular (solo se anulan QR en estado PENDIENTE)", "code": "ESTADO_INVALIDO" } ] }

Response — Error (QR cancelado anteriormente)

json
{ "success": false, "message": "Error al anular QR", "errors": [ { "field": "numeroReferencia", "message": "El QR ya está en estado CANCELADO, no se puede anular (solo se anulan QR en estado PENDIENTE)", "code": "ESTADO_INVALIDO" } ] }

8. 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.
AmbienteURL baseCredencialesEstado
Certificaciónhttps://atcgwapitest.redenlace.com.bo/sandbox/Provisto por ATCActivo
Producciónhttps://api.redenlace.com.bo/Provisto por ATCRestringido