Desarrolladores
Una API de pagos cripto pensada para la liquidación directa
Crea una factura con una sola petición autenticada y Unheld te devuelve la dirección a pagar, el importe exacto y la profundidad de confirmación que esperará. Los pagos se liquidan directamente en un monedero que tú controlas: la API nunca toma custodia de aquello sobre lo que informa.
Crear una factura
Un solo POST. El importe se escribe como lo escribiría una persona y se escala en el servidor según los decimales del propio activo, así que nunca conviertes a unidades base a mano.
curl -X POST https://api.unheld.io/api/v1/invoices \
-H "Authorization: Bearer $UNHELD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chainId": "11155111",
"assetType": "native",
"amountDecimal": "0.05",
"expiresInSeconds": 900,
"metadata": { "orderId": "A-1043" }
}'Respuesta
{
"id": "e2b0…",
"status": "CREATED",
"receiveAddress": "0x…",
"expectedAmount": "50000000000000000",
"minConfirmations": 3,
"expiresAt": "2026-08-10T14:15:00.000Z",
"instructions": {
"chainId": "11155111",
"to": "0x…",
"amount": "50000000000000000",
"assetType": "native"
}
}receiveAddress se deriva de tu monedero y queda ligada a esta factura. expectedAmount está en unidades base. minConfirmations es el umbral propio de la cadena, no un ajuste que nos hayamos inventado.
Autenticación y ámbitos
Las claves son tokens bearer, se crean en el panel y se muestran una sola vez. Cada clave lleva una lista explícita de ámbitos y una petición se rechaza si la clave no tiene el ámbito de esa ruta.
Ámbitos disponibles
- invoices:write
- invoices:read
- webhooks:write
- webhooks:read
- balances:read
- customers:write
- customers:read
- subscriptions:write
- subscriptions:read
Concede el conjunto más estrecho que funcione. Una clave que solo crea facturas no puede leer tus clientes, y una clave de lectura filtrada no puede mover nada, porque nada en esta API puede hacerlo.
Webhooks que puedes verificar
Cada entrega va firmada. La firma es un HMAC-SHA256 de la marca de tiempo y el cuerpo en bruto unidos por un punto, calculado con tu secreto de webhook y enviado como una cadena hexadecimal.
Verificar una entrega
const signature = crypto
.createHmac("sha256", webhookSecret)
.update(`${req.headers["x-timestamp"]}.${rawBody}`)
.digest("hex");
crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(req.headers["x-signature"])
);Compara los resúmenes en tiempo constante, rechaza una marca de tiempo fuera de tu ventana de tolerancia y trata X-Request-Id como clave de idempotencia: los reintentos la reutilizan, así que recibir dos veces el mismo evento es normal y no debe procesarse dos veces.
Eventos de factura
Un pago recorre estados en vez de pasar de impagado a pagado, y cada transición es un webhook. El pago de menos y el pago de más son eventos propios, no errores.
| Evento | Qué ha pasado |
|---|---|
| invoice.created | La factura existe y la dirección de recepción está vigilada. |
| invoice.receiving | Se ha visto en la cadena una transacción de pago, pero aún no está confirmada. |
| invoice.confirming | El pago se está confirmando y no ha alcanzado el umbral de la cadena. |
| invoice.paid | Confirmado por completo a la profundidad que exige la cadena. Puedes entregar. |
| invoice.underpaid | Llegó menos de lo esperado. Los pagos parciales se acumulan, así que una segunda transferencia puede completarlo. |
| invoice.overpaid | Llegó más de lo esperado, registrado con exactitud en vez de redondearse. |
| invoice.expired | La ventana se cerró sin pago completo. |
Prueba todo el flujo gratis
Prueba la creación de facturas, la detección, las confirmaciones y los webhooks sin usar fondos reales. Los tokens de prueba no tienen valor monetario. La actividad testnet no es un pago real.
Alcance
- Nunca retiene fondos. No hay un endpoint de saldo del que retirar, porque los pagos llegan a tu dirección y ahí se quedan.
- No convierte ni liquida en moneda fiduciaria. Los pagos llegan en el activo y por la cadena con que se enviaron.
- Todavía no hay SDK oficiales. Aquí todo es HTTP puro, y publicamos ejemplos en lugar de paquetes que mantendríamos mal.
Preguntas de desarrollo
¿Hay un entorno de pruebas?
Prueba la creación de facturas, la detección, las confirmaciones y los webhooks sin usar fondos reales. Los tokens de prueba no tienen valor monetario. La actividad testnet no es un pago real.
¿Cómo evito procesar dos veces el mismo webhook?
Usa X-Request-Id como clave de idempotencia. Los reintentos reutilizan el mismo valor, así que regístralo e ignora una repetición. Los reintentos son esperables: una entrega que falla se reintenta según un calendario en lugar de descartarse.
¿Tengo que convertir yo los importes a unidades base?
No. Envía amountDecimal como lo escribiría una persona y la API lo escala según los decimales del activo. La respuesta devuelve expectedAmount en unidades base, de modo que ambas representaciones son explícitas y no pueden desviarse.
Ejemplos verificados con la API en vivo el .
Construye primero contra testnet
Crea una clave, apúntala a una cadena de testnet y recorre todo el flujo antes de que se mueva nada real.
Empieza gratisPrecios · Lo que puedes aceptar hoy. · Tu dinero no pasa por nosotros.