Acepta pagos con Bre-b

Bre-B ofrece un flujo alternativo para aceptar pagos por transferencia bancaria en Colombia. En lugar de requerir los datos de la cuenta del pagador, Kushki genera un código QR que el usuario escanea desde su aplicación bancaria para autorizar el pago en tiempo real.

Este flujo convive con el proceso ACH existente — ningún cambio es requerido en integraciones actuales.

Detalles de operación

ParámetroDetalle
MonedaCOP
Campo adicional requeridoflowType = "BRE_B" en el cuerpo del token
Consulta de listado de bancosNo requerida para este flujo
Resultado del initCódigo QR (base64 PNG) para pago desde app bancaria
Vigencia del QR10 minutos. Pasado ese tiempo el QR se invalida y debe generarse un nuevo token e init.
Tiempo de procesamientoTiempo real
CancelaciónPATCH /transfer/v1/cancel/{token} — disponible mientras la transacción no tenga estado final. Retorna HTTP 204 No Content.
WebhookSin cambios respecto al flujo ACH
Códigos de errorSin cambios respecto al flujo ACH

1. Crea el token

Realiza la petición del token usando el mismo endpoint que el flujo ACH. Para activar el flujo Bre-B, incluye el campo flow. No es necesario consultar el listado de bancos antes de este paso.

Campos requeridos

CampoTipoDescripción
amount.subtotalIva0numberMonto de la transacción (sin IVA)
amount.subtotalIvanumberMonto de la transacción (con IVA). Igual a subtotalIva0 si iva = 0
amount.ivanumberValor del IVA (0 si no aplica)
currencystringMoneda. Debe ser “COP”
flow.processorNamestringNUEVO campo requerido. Debe ser “BRE-B” para activar este flujo
flow.typestringNUEVO campo requerido. Debe ser “QR” para activar este flujo

Campos opcionales

callbackUrl · userType · documentType · documentNumber · paymentDescription · email · bankId

  • Javascript
  • Python
  • PHP
var options = {
'method': 'POST',
'url': 'https://api-uat.kushkipagos.com/transfer/v1/tokens',
'headers': { 'Public-Merchant-Id': '', 'Content-Type': 'application/json' },
body: JSON.stringify({
"amount": { "subtotalIva0": 1000, "subtotalIva": 1000, "iva": 0 },
"currency": "COP",
"flow":{
"processorName":"BRE-B",
"type":"QR"
}
})
};
request(options, function(error, response) {
var data = JSON.parse(response.body);
console.log('token:', data.token);
});
payload = json.dumps({
"amount": { "subtotalIva0": 1000, "subtotalIva": 1000, "iva": 0 },
"currency": "COP",
"flow":{
"processorName":"BRE-B",
"type":"QR"
}
})
headers = {'Public-Merchant-Id': '', 'Content-Type': 'application/json'}
response = requests.post('https://api-uat.kushkipagos.com/transfer/v1/tokens',
headers=headers, data=payload)
print('token:', response.json()['token'])
$body->append(json_encode([
"amount" => ["subtotalIva0" => 1000, "subtotalIva" => 1000, "iva" => 0],
"currency" => "COP",
"flow" => [
"processorName" => "BRE-B",
"type" => "QR"
]
]));
// POST a /transfer/v1/tokens con Public-Merchant-Id
echo json_decode($client->getResponse()->getBody(), true)['token'];

2. Genera el código QR

Con el token obtenido, inicializa la transacción. Kushki retorna un código QR en formato base64 que debes mostrar al usuario para que lo escanee desde su aplicación bancaria.

  • Javascript
  • Python
  • PHP
var options = {
'method': 'POST',
'url': 'https://api-uat.kushkipagos.com/transfer/v1/init',
'headers': { 'Private-Merchant-Id': '', 'Content-Type': 'application/json' },
body: JSON.stringify({
"token": "{{token}}",
"amount": { "subtotalIva": 0, "subtotalIva0": 1000, "iva": 0 },
// "fullResponse": "v2" // opcional — incluye el objeto details en la respuesta
})
};
request(options, function(error, response) {
var data = JSON.parse(response.body);
console.log('qr:', data.qr);
console.log('ref:', data.transactionReference);
});
payload = json.dumps({
"token": "{{token}}",
"amount": { "subtotalIva": 0, "subtotalIva0": 1000, "iva": 0 },
# "fullResponse": "v2" # opcional — incluye el objeto details en la respuesta
})
headers = {'Private-Merchant-Id': '', 'Content-Type': 'application/json'}
data = requests.post('https://api-uat.kushkipagos.com/transfer/v1/init',
headers=headers, data=payload).json()
print('qr:', data['qr'])
$body->append(json_encode([
"token" => "{{token}}",
"amount" => ["subtotalIva" => 0, "subtotalIva0" => 1000, "iva" => 0],
// "fullResponse" => "v2" // opcional
]));
// POST a /transfer/v1/init con Private-Merchant-Id
$data = json_decode($client->getResponse()->getBody(), true);
echo $data['qr'];

Ejemplo de respuesta — sin fullResponse

{
"qr": "data:image/png;base64,iVBORw0KGgoAAAANS...",
"transactionReference": "f2110170-8eec-4214-b2d0-38970d44f8e1"
}

Ejemplo de respuesta — con fullResponse: “v2”

{
"qr": "data:image/png;base64,iVBORw0KGgoAAAANS...",
"transactionReference": "f2110170-8eec-4214-b2d0-38970d44f8e1",
"details": {
"status": "initializedTransaction",
"amount": { "currency": "COP", "iva": 0, "subtotalIva": 1000, "subtotalIva0": 1000 },
"created": 1784125900901,
"merchantId": "20000000106921087000",
"merchantName": "Mi Comercio Colombia"
}
}

Cómo renderizar el campo qr

El campo qr contiene una cadena Data URI completa (data:image/png;base64,...). Para mostrarlo en web:

<img src="{qr}" alt="Escanea para pagar" width="250" />

En apps nativas, decodifica el base64 y renderiza el bitmap con el componente de imagen de tu plataforma.

3. Muestra el QR al usuario y espera el pago

El usuario escanea el QR desde su aplicación bancaria y autoriza el pago. Kushki notifica el resultado de forma asíncrona. El QR expira en 10 minutos. Si el usuario no escanea en ese tiempo, deberás generar un nuevo token e init. Para monitorear el resultado: configura un webhook (ver paso 5) o consulta Get Status manualmente. Mientras el pago está pendiente, puedes cancelar la transacción (ver paso 4).

4. Cancela la transacción (opcional)

Si el usuario no puede completar el pago o necesitas invalidar el QR activo, cancela la transacción antes de que alcance un estado final.

Cuándo usar la cancelación Usa este endpoint cuando el usuario ingrese un monto incorrecto, decida no completar el pago, o necesites emitir un nuevo QR antes de que el QR original expire (vigencia de 10 minutos). Solo es posible si la transacción aún no tiene un estado final.

Endpoint PATCH https://{api-url}/transfer/v1/cancel/{token}

Donde {token} es el token obtenido en el paso 1.

Respuesta exitosa (HTTP 204 No Content) La cancelación exitosa retorna HTTP 204 sin cuerpo en la respuesta.

Error — transacción con estado final (HTTP 400)

{
"code": "T023",
"message": "Transacción posee un estado final."
}

5. Consulta el estado de la transacción

El estado final del pago llega de forma asíncrona. Puedes recibirlo de dos maneras:

  • Webhook: Kushki notifica automáticamente cuando el pago es aprobado o rechazado. Sin cambios respecto al flujo ACH.
  • Get Status: Consulta manualmente el estado usando el token en el path.
  • Javascript
  • Python
  • PHP
var options = {
'method': 'GET',
'url': 'https://api-uat.kushkipagos.com/transfer/v1/status/{{token}}', // token del paso 1
'headers': { 'Private-Merchant-Id': '' }
};
request(options, function(error, response) {
console.log(response.body);
});
token = '{{token}}' # token obtenido en el paso 1
url = f'https://api-uat.kushkipagos.com/transfer/v1/status/{token}'
headers = {'Private-Merchant-Id': ''}
response = requests.get(url, headers=headers)
print(response.text)
$token = '{{token}}'; // token del paso 1
$request->setRequestUrl("https://api-uat.kushkipagos.com/transfer/v1/status/{$token}");
$request->setRequestMethod('GET');
$request->setHeaders(['Private-Merchant-Id' => '']);
$client->enqueue($request)->send();
echo $client->getResponse()->getBody();

6. Prueba tu integración

El ambiente UAT simula escenarios mediante el valor de transaction_amount, que corresponde a la suma de todos los campos del objeto amount en la petición (subtotalIva0 + subtotalIva + iva). Por ejemplo, para activar el escenario 1000 envía subtotalIva0: 500, subtotalIva: 500, iva: 0. Si la suma no coincide con ningún valor de la tabla, la respuesta es exitosa sin webhook.

transaction_amountHTTP statusEstadoWebhookNota
10000201SUCCESSDispara → PAIDHappy path con webhook
9999201SUCCESSNo disparaLa transacción queda inicializada
10000201SUCCESSDispara → PAIDHappy path con webhook
11000500ERRORNo disparaQR-CODE-0001
12000201SUCCESSDispara → rejectedTransacción rechazada
13000TIMEOUTNo disparaSe deja la transacción inicializada. Reutiliza el DELAY_MS existente.
99999999400ERRORNo disparaQR-CODE-0059 — monto fuera de rango
Cualquier otro201SUCCESSNo disparaRespuesta exitosa genérica

7. Prepara tu certificación

Toma en consideración las siguientes pautas para aprobar la certificación técnica:

  • Los cálculos de los montos son correctos (subtotalIva, subtotalIva0, iva).
  • El campo flowType se envía como "BRE_B" en la petición del token.
  • El código QR se muestra correctamente al usuario desde el campo qr de la respuesta del init.
  • Se implementa el endpoint de cancelación para los flujos donde el usuario no completa el pago.
  • Se muestran mensajes en pantalla de acuerdo con las respuestas de Kushki.
  • Si se reciben notificaciones por webhook, se responde con HTTP 200.
  • El botón de pago se deshabilita después del primer clic para evitar doble envío.
  • Todas las respuestas de Kushki se guardan y registran (requeridas en caso de soporte).
  • El logo de Kushki es visible. Descárgalo en s3.amazonaws.com/kushki-cdn-production/docs/Logo+Kushki.zip
  • Se envían todos los campos requeridos según la referencia API.

Artículos relacionados

Acepta pagos por transferencia (ACH)

Recibe transferencias bancarias

Configura webhooks

Recibe notificaciones del estado de tus pagos.

Cancelación — Referencia técnica

Referencia Técnica