Integraciones
API REST para código propio
Tres pasos: crear un cobro, enviar al comprador a la página de pago y recibir el aviso firmado cuando se confirma.
- Base
https://pagosbi.com/api/v1- Autenticación
- Cabecera
Authorization: Bearer <clave de API> - Formato
- JSON. Importes como cadenas decimales ("15.00").
1. Crear un cobro
POST /cobros
curl -X POST https://pagosbi.com/api/v1/cobros \
-H "Authorization: Bearer pgd_live_7Kq2mXv9RtLpW4nB" \
-H "Content-Type: application/json" \
-d '{
"importe": "15.00",
"referencia": "Pedido #4821",
"descripcion": "Aceite de coco 500 ml x2",
"url_retorno": "https://tutienda.com/gracias?pedido=4821",
"caducidad_min": 15,
"meta": { "pedido_id": 4821, "cliente_email": "ana.r@gmail.com" }
}'
Respuesta 201 Created:
{
"id": "PGD-2026-000512",
"estado": "esperando",
"importe_pedido": "15.00",
"importe_unico": "15.23",
"moneda": "USDT",
"url_pago": "https://pagosbi.com/p/PGD-2026-000512",
"caduca_en": "2026-09-04T15:57:12Z",
"creado_en": "2026-09-04T15:42:12Z",
"referencia": "Pedido #4821"
}
Redirige al comprador a url_pago. Si prefieres mostrar el QR en tu propia página, la respuesta incluye también tu qr_url y el pay_id.
2. Consultar un cobro
GET /cobros/{id}
{
"id": "PGD-2026-000512",
"estado": "pagado",
"importe_pedido": "15.00",
"importe_unico": "15.23",
"importe_recibido": "15.23",
"pagado_en": "2026-09-04T15:44:03Z",
"transaccion": {
"binance_tx_id": "1847392018273645",
"pagador": { "nombre": "Ana R.", "pay_id": "***45 218" }
},
"avisos": [
{ "intento": 1, "enviado_en": "2026-09-04T15:44:05Z", "codigo": 200, "estado": "entregado" }
]
}
Estados posibles: esperando, detectado, pagado, caducado.
3. Recibir el aviso
Cuando el cobro pasa a pagado (y también al pasar a caducado), hacemos un POST a tu dirección de avisos:
POST /pgd/aviso HTTP/1.1
Host: tutienda.com
Content-Type: application/json
X-PGD-Firma: sha256=3f7a9c...e21b
X-PGD-Marca-Tiempo: 1788554643
X-PGD-Evento: cobro.pagado
{
"evento": "cobro.pagado",
"cobro": { "id": "PGD-2026-000512", "estado": "pagado", "importe_unico": "15.23",
"importe_recibido": "15.23", "referencia": "Pedido #4821",
"meta": { "pedido_id": 4821 } }
}
Responde 200 en menos de 10 segundos. Si no, reintentamos hasta 6 veces (1, 5, 15, 60, 240 y 720 minutos). Cada aviso es idempotente: usa el id del cobro para no entregar dos veces.
Verificar la firma
La firma es HMAC-SHA256(secreto, marca_tiempo + "." + cuerpo_crudo), en hexadecimal. Rechaza avisos con marca de tiempo de más de 5 minutos.
# Python (Flask)
import hmac, hashlib, time
from flask import request, abort
SECRETO = "whsec_9a4Ff2ZkQ8mT1vLr6Dp3Xc"
@app.post("/pgd/aviso")
def aviso():
ts = request.headers.get("X-PGD-Marca-Tiempo", "")
firma = request.headers.get("X-PGD-Firma", "").replace("sha256=", "")
if abs(time.time() - int(ts or 0)) > 300:
abort(400)
esperada = hmac.new(SECRETO.encode(), f"{ts}.".encode() + request.get_data(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(esperada, firma):
abort(401)
datos = request.get_json()
if datos["evento"] == "cobro.pagado":
marcar_pedido_pagado(datos["cobro"]["meta"]["pedido_id"])
return "", 200
// PHP
$ts = $_SERVER['HTTP_X_PGD_MARCA_TIEMPO'] ?? '';
$firma = str_replace('sha256=', '', $_SERVER['HTTP_X_PGD_FIRMA'] ?? '');
$cuerpo = file_get_contents('php://input');
$esperada = hash_hmac('sha256', $ts . '.' . $cuerpo, $SECRETO);
if (!hash_equals($esperada, $firma)) { http_response_code(401); exit; }
Errores
| Código | Motivo |
|---|---|
401 | Clave de API inválida o regenerada. |
402 | Suscripción impagada o suspendida. |
409 sin_importes_libres | Ya hay 90 cobros abiertos en esa cuenta. Espera a que caduque alguno. |
422 | Cuerpo inválido (importe no numérico, caducidad fuera de 5–60 min). |
429 | Más de 60 peticiones por minuto. |
Otros puntos de acceso
| Método | Ruta | Uso |
|---|---|---|
GET | /cobros?estado=pagado&desde=2026-09-01 | Listar cobros con filtros y paginación (pagina, por_pagina). |
POST | /cobros/{id}/cancelar | Cancelar un cobro en espera y liberar su importe. |
POST | /cobros/{id}/reenviar-aviso | Volver a enviar el aviso a tu tienda. |
GET | /tiendas | Tus tiendas conectadas (plan Negocio). |