TuCapi Business · Desarrolladores
Cobros en dólares desde tu código.
Una API REST para crear cobros, consultar órdenes y leer tu saldo. Llaves secretas con permisos por scope, idempotencia en cada escritura y webhooks firmados para enterarte de cada pago.
- OpenAPI 3
- REST + JSON
- OpenAPI 3
- curl · Node · Python · PHP
- 4 lenguajes
- curl · Node · Python · PHP
- documentación
- es / en
- documentación
curl -X POST https://api.business.tucapi.com/v1/charges \
-H "Authorization: Bearer $TUCAPI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ORD-1042" \
-d '{
"amount": "125.00",
"description": "Pedido #1042",
"reference": "ORD-1042",
"metadata": { "customerId": "c_88" },
"allowedMethods": ["paypal", "card"],
"expiresAt": "2026-09-16T12:00:00Z"
}'{
"object": "charge",
"id": "9b1e2d3c-4f5a-4b6c-8d7e-0f1a2b3c4d5e",
"status": "open",
"amount": "125.00",
"currency": "USD",
"checkoutUrl": "https://pay.tucapi.com/k7x2m9qz",
"embedUrl": "https://pay.tucapi.com/embed/k7x2m9qz",
"expiresAt": "2026-09-16T12:00:00Z"
}Guía de inicio
Tu primera integración en cuatro pasos
- 1
Crea una llave secreta
En el panel, en Desarrolladores › Llaves de API. Tipo Secret, entorno Live, solo los scopes que necesitas.
- 2
Crea el cobro
POST /v1/charges con Idempotency-Key y tu número de pedido en reference.
- 3
Envía al cliente
Redirige a checkoutUrl o integra embedUrl en tu sitio, en los dominios que autorices.
- 4
Confirma por webhook
Recibe order.paid, verifica la firma y marca el pedido como pagado.
API
Endpoints disponibles
Base: https://api.business.tucapi.com/v1 · Autenticación: Authorization: Bearer tcb_sk_live_…
| Endpoint | Qué hace | Scope |
|---|---|---|
| POST/v1/charges | Crea un cobro y devuelve el link de pago | orders:write |
| GET/v1/charges/{id} | Consulta un cobro y sus órdenes | orders:read |
| GET/v1/orders | Lista órdenes con filtros y paginación por cursor | orders:read |
| GET/v1/orders/{id} | Consulta una orden: método, monto, neto y estado | orders:read |
| GET/v1/balance | Saldo disponible y pendiente (USDT, 1 a 1 con el dólar) | balance:read |
- 300
- lecturas por minuto, por llave
- 60
- escrituras por minuto, por llave
- 24 h
- validez de una Idempotency-Key
- 6
- intentos por webhook, hasta 24 h
Webhooks
Te avisamos de cada pago, con firma verificable
Cada aviso llega con la cabecera TuCapi-Signature: t=…,v1=…. La firma es HMAC-SHA256 de t + "." + cuerpo con tu secret. Rechaza los avisos con más de 5 minutos de diferencia.
| Evento | Cuándo llega |
|---|---|
| order.created | Tu cliente eligió el método de pago |
| order.paid | El pago se confirmó y se acreditó el neto |
| order.expired | La orden venció sin pagarse |
| payout.created | Pediste un retiro |
| payout.completed | El retiro se completó |
| payout.failed | El retiro falló y el saldo se devolvió |
| webhook.test | Prueba manual desde el panel |
Si tu endpoint no responde 2xx en 10 segundos, reintentamos a 1 min, 5 min, 30 min, 2 h y 24 h. También puedes reenviar un aviso a mano desde el panel.
const crypto = require("crypto");
function verifyTuCapi(rawBody, header, secret, toleranceSec = 300) {
const parts = header.split(",").map((p) => p.trim());
const t = parts.find((p) => p.startsWith("t="))?.slice(2);
const v1 = parts.filter((p) => p.startsWith("v1=")).map((p) => p.slice(3));
if (!t || v1.length === 0) throw new Error("cabecera inválida");
if (Math.abs(Date.now() / 1000 - Number(t)) > toleranceSec) {
throw new Error("fuera de ventana");
}
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.`)
.update(rawBody)
.digest("hex");
const ok = v1.some(
(sig) =>
sig.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(sig, "hex"), Buffer.from(expected, "hex")),
);
if (!ok) throw new Error("firma inválida");
}POST /webhooks/tucapi HTTP/1.1
Content-Type: application/json
TuCapi-Signature: t=1726000000,v1=5f1a…9c
TuCapi-Event-Id: evt_2b1c9d0e4f5a4a6b8c7d9e0f1a2b3c4d
TuCapi-Event-Type: order.paid
TuCapi-Attempt: 1Llaves de API
Acceso mínimo para cada integración
Llaves secretas
Formato tcb_sk_live_…. Se muestran una sola vez y guardamos solo su huella (hash), nunca la llave. Solo el dueño de la cuenta puede crearlas.
Scopes
orders:write, orders:read y balance:read. Si a la llave le falta el scope del endpoint, la API responde 403 insufficient_scope.
Checkout integrado
Muestra el pago dentro de tu sitio con embedUrl. Solo funciona en los dominios que autorices en el panel.
Hoy la API funciona solo en producción: cada cobro pagado es real.
Documentación
Todo lo que necesitas para integrar
Empieza a integrar
Abre la cuenta de tu empresa, crea tu llave y haz tu primer cobro por API.