Inicio rápido
Felix Pago le vende USDC a Banco Nexa a cambio de GTQ. Tesser orquesta la operación: cotiza con Nexa, reporta el USDC que llega a la custodia BitGo de Nexa e instruye el desembolso en GTQ. Felix y Nexa nunca se comunican entre sí.
Alcance de esta integración: un solo beneficiario fijo, sin última milla
Nexa siempre paga al mismo beneficiario, acordado fuera de banda y que nunca aparece en el cuerpo de una llamada de API. Ese beneficiario es el socio de desembolso, que ejecuta el desembolso de última milla hacia los receptores de remesas individuales.
Nexa no participa en la última milla. En todo este contrato no hay datos de beneficiario por destinatario, ni objetos de destino, ni campos de cumplimiento del beneficiario, porque todos los desembolsos van al mismo lugar. Que Nexa asuma los desembolsos de remesas de última milla es una etapa posterior del programa, fuera de alcance aquí.
Las partes
| Parte | Rol en esta integración |
|---|---|
| Banco Nexa | Cotiza el tipo de cambio, compra el USDC, acredita los GTQ y ejecuta el desembolso. Aloja la API de cotizaciones, depósitos y pagos. |
| Tesser | Orquestador. Emite cada cotización, vigila la billetera de custodia BitGo de Nexa, reporta los depósitos con evaluación de riesgo e instruye el desembolso. Aloja el receptor de webhooks que Nexa invoca, más la API principal que Nexa usa para tesorería. |
| Felix Pago | El remitente que compra GTQ. Al inicio interactúa mediante el bot de Slack de Tesser. Felix nunca llama a Nexa. |
Las diez operaciones
En todo el portal, [N] significa lo aloja Nexa y lo llama Tesser, y [T] significa lo aloja Tesser y lo llama Nexa. La dirección que se indica abajo es quien llama → quien recibe.
| # | Operación | Dirección | Propósito |
|---|---|---|---|
| 1 | POST /v1/quotes [N] | T→N | Tesser solicita una cotización en GTQ para un cliente |
| 2 | POST /v1/quotes/{tesser_quote_id}/accept [N] | T→N | Fijar la cotización |
| 3 | POST /v1/quotes/{tesser_quote_id}/deposits [N] | T→N | Tesser reporta el USDC recibido en custodia, con evaluación de riesgo |
| 4 | POST/HEAD /v1/webhooks/nexa/{organizationId} [T] | N→T | Eventos de Nexa hacia Tesser: decisiones de acreditación, fallas del desembolso |
| 5 | POST /v1/payments [N] | T→N | Instruir el desembolso en GTQ al beneficiario fijo |
| 6 | GET /v1/accounts/{id} [T] | N→T | API principal existente: saldo en USDC de Nexa |
| 7 | POST /v1/treasury/withdrawals [T] | N→T | API principal existente: retirar USDC |
| 8 | GET /v1/quotes/{tesser_quote_id} [N] (opcional) | T→N | Conciliación y recuperación de estado |
| 9 | GET /v1/payments/{nexa_payment_id} [N] (opcional) | T→N | Conciliación y recuperación de estado |
| 10 | POST /v1/webhooks/tesser [N] | T→N | Eventos de Tesser hacia Nexa: estado del retiro, da soporte a la operación 7 |
La palabra "opcional" en las operaciones 8 y 9 se refiere únicamente a la obligación de implementarlas que tiene Nexa. De cualquier forma, ambas quedan aquí totalmente especificadas, probadas y con un stub (endpoint simulado) disponible.
Las cuatro conexiones
Esas diez operaciones viajan sobre apenas cuatro conexiones. Dos partes, dos tipos de tráfico (llamadas de API y webhooks), cada uno en ambos sentidos. Eso es toda la integración.
Basta con poner a funcionar esas cuatro, una llamada por cada una, y todo lo demás es más de lo mismo.
Conviene construirlas en este orden
Cada hito es una llamada funcionando, de extremo a extremo, con el modelo de seguridad real. Los hitos posteriores reutilizan las credenciales que validan los anteriores, así que el orden no es arbitrario.
| # | Conexión | Dirección | La llamada que lo comprueba |
|---|---|---|---|
| 1 | Llamada de API, de Tesser a Nexa, sobre mTLS | T→N | Crear cotización [N] responde 201 |
| 2 | Webhook, de Nexa a Tesser | N→T | Recibir webhook de Nexa [T] responde 2xx |
| 3 | Llamada de API, de Nexa a Tesser | N→T | Consultar una cuenta por ID [T] responde 200 |
| 4 | Webhook, de Tesser a Nexa | T→N | Recibir webhook de Tesser [N] responde 2xx |
1 · mTLS y luego crear una cotización [N]
El primer hito es el intercambio de certificados, no el endpoint. Todo lo demás en esta integración depende de él, así que conviene hacerlo primero y comprobarlo con la llamada más sencilla del contrato.
- Nexa habilita
POST /v1/quotesdetrás de mTLS y decide cómo validar el certificado de cliente de Tesser: fijar la huella digital del certificado hoja, o validarlo contra una CA emisora proporcionada por Tesser. Nexa también emite la llave de API de Nexa para Felix. - Tesser presenta ese certificado de cliente además del encabezado
Authorization: Bearer <felix_api_key>en cada llamada.
Listo cuando: un POST /v1/quotes responde 201 con un precio,
quoted_gtq y usdc_amount sobre una conexión autenticada mutuamente.
Detalles: Autenticación · 1 · Cotización y aceptación
2 · Nexa envía un webhook a Tesser [T]
Toda decisión de Nexa en este flujo es asíncrona, así que este tramo carga con más partes de la integración que cualquier otra pieza individual.
- Nexa registra la huella digital SHA-256 de su certificado de cliente
contra su llave de API de Tesser durante el onboarding, y luego entrega
los eventos a
POST /v1/webhooks/nexa/{organizationId}. - Conviene comprobar primero la conectividad con
HEAD /v1/webhooks/nexa/{organizationId}[T], que usa la misma ruta y la misma autenticación, sin cuerpo y sin consumir ningún evento.
Listo cuando: se entrega un evento real y se confirma con 2xx.
quote.credit.sent es la opción natural.
Detalles: Guía de webhooks · 3 · Decisión de acreditación
3 · Nexa consulta su saldo en USDC [T]
Este es un endpoint ya existente y en producción de la API principal de Tesser, y reutiliza exactamente el certificado que registró el hito 2, así que es la confirmación más barata posible de que las credenciales salientes de Nexa sirven para llamadas de API y no solo para enviar webhooks.
- Nexa llama a
GET /v1/accounts/{id}con el ID de la cuenta de billetera que se compartió durante el onboarding.
Listo cuando: se obtiene un 200 con el saldo en USDC de la cuenta.
Detalles: 5 · Tesorería
4 · Tesser envía un webhook a Nexa [N]
Va al final porque es el único tramo que implica trabajo nuevo en la plataforma de Tesser: hoy el emisor de webhooks de Tesser firma con Ed25519 y se está ampliando para que presente un certificado de cliente en las entregas hacia Nexa.
- Nexa habilita
POST /v1/webhooks/tessery se suscribe a los eventos de estado de retiro.
Listo cuando: se entrega un evento de estado de retiro y se confirma con
2xx.
Detalles: Autenticación · Guía de webhooks
Después: el resto del flujo
Con las cuatro conexiones comprobadas, cada operación restante sigue uno de esos mismos dos patrones, así que el trabajo está en el flujo y no en la plomería. Conviene retomarlas en aceptar cotización [N] y recorrerlas en orden en las páginas de flujo. Antes de escribir nada, se deben leer las cuatro reglas del contrato. Ellas definen la mayoría de los casos límite de esta integración.
Dónde está cada cosa
| Flujo: la perspectiva de Nexa | Alcance, glosario, la máquina de estados y luego una página por fase con diagramas y modos de falla |
| Autenticación | mTLS en ambos sentidos, intercambio y rotación de certificados |
| Guía de webhooks | Envoltorio, catálogo de eventos, deduplicación, reglas de ordenamiento |
| Prueba de extremo a extremo | Un script que recorre todo el flujo y verifica cada paso |
| Pruebas y stubs | El host de stubs y el id de error mágico |
| Preguntas abiertas | Diez puntos, la agenda de la reunión técnica |
| Endpoints de Nexa expuestos a Tesser | Referencia de API de todo lo que aloja Nexa |
| Endpoints de Tesser expuestos a Nexa | Referencia de API de todo lo que aloja Tesser |
Conviene leer Preguntas abiertas antes del hito 1. Varias de ellas (la ventana de validez de la cotización y la elección de Nexa sobre validación de certificados) necesitan respuesta para que la primera llamada pueda tener éxito.