# 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í.

<Callout type="note" title="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í.

</Callout>

## 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`](/api-nexa/quotes#create-quote-op-1) <N /> | T→N | Tesser solicita una cotización en GTQ para un cliente |
| 2 | [`POST /v1/quotes/{tesser_quote_id}/accept`](/api-nexa/quotes#accept-quote-op-2) <N /> | T→N | Fijar la cotización |
| 3 | [`POST /v1/quotes/{tesser_quote_id}/deposits`](/api-nexa/deposits#report-usdc-deposit-op-3) <N /> | T→N | Tesser reporta el USDC recibido en custodia, con evaluación de riesgo |
| 4 | [`POST`/`HEAD /v1/webhooks/nexa/{organizationId}`](/api-tesser/webhooks#receive-nexa-webhook-op-4) <T /> | N→T | Eventos de Nexa hacia Tesser: decisiones de acreditación, fallas del desembolso |
| 5 | [`POST /v1/payments`](/api-nexa/payments#create-payment-op-5) <N /> | T→N | Instruir el desembolso en GTQ al beneficiario fijo |
| 6 | [`GET /v1/accounts/{id}`](/api-tesser/accounts#get-an-account-by-id) <T /> | N→T | API principal existente: saldo en USDC de Nexa |
| 7 | [`POST /v1/treasury/withdrawals`](/api-tesser/treasury#create-withdrawal) <T /> | N→T | API principal existente: retirar USDC |
| 8 | [`GET /v1/quotes/{tesser_quote_id}`](/api-nexa/quotes#get-quote-optional-op-8) <N /> *(opcional)* | T→N | Conciliación y recuperación de estado |
| 9 | [`GET /v1/payments/{nexa_payment_id}`](/api-nexa/payments#get-payment-optional-op-9) <N /> *(opcional)* | T→N | Conciliación y recuperación de estado |
| 10 | [`POST /v1/webhooks/tesser`](/api-nexa/webhooks#receive-tesser-webhook-nexa-implements-this) <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.

<Mermaid
  chart={`flowchart LR
    T["Tesser"]
    N["Banco Nexa"]
    T -- "llamadas de API" --> N
    T -- "webhooks" --> N
    N -- "llamadas de API" --> T
    N -- "webhooks" --> T`}
/>

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](/api-nexa/quotes#create-quote-op-1) <N /> responde `201` |
| 2 | **Webhook**, de Nexa a Tesser | N→T | [Recibir webhook de Nexa](/api-tesser/webhooks#receive-nexa-webhook-op-4) <T /> responde `2xx` |
| 3 | **Llamada de API**, de Nexa a Tesser | N→T | [Consultar una cuenta por ID](/api-tesser/accounts#get-an-account-by-id) <T /> responde `200` |
| 4 | **Webhook**, de Tesser a Nexa | T→N | [Recibir webhook de Tesser](/api-nexa/webhooks#receive-tesser-webhook-nexa-implements-this) <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/quotes`](/api-nexa/quotes#create-quote-op-1)
  detrá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](/es/authentication) ·
[1 · Cotización y aceptación](/es/flow-nexa/quote-accept)

### 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}`](/api-tesser/webhooks#receive-nexa-webhook-op-4).
- **Conviene comprobar primero la conectividad** con
  [`HEAD /v1/webhooks/nexa/{organizationId}`](/api-tesser/webhooks#verify-webhook-connectivity-op-4)
  <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](/es/webhooks-guide) ·
[3 · Decisión de acreditación](/es/flow-nexa/credit-decision)

### 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}`](/api-tesser/accounts#get-an-account-by-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](/es/flow-nexa/treasury)

### 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/tesser`](/api-nexa/webhooks#receive-tesser-webhook-nexa-implements-this)
  y 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](/es/authentication) ·
[Guía de webhooks](/es/webhooks-guide)

### 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](/api-nexa/quotes#accept-quote-op-2) <N /> y recorrerlas en orden
en las [páginas de flujo](/es/flow-nexa/lifecycle). Antes de escribir nada,
se deben leer las cuatro [reglas del
contrato](/es/flow-nexa/lifecycle#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](/es/flow-nexa/lifecycle) | Alcance, glosario, la máquina de estados y luego una página por fase con diagramas y modos de falla |
| [Autenticación](/es/authentication) | mTLS en ambos sentidos, intercambio y rotación de certificados |
| [Guía de webhooks](/es/webhooks-guide) | Envoltorio, catálogo de eventos, deduplicación, reglas de ordenamiento |
| [Prueba de extremo a extremo](/es/e2e-test) | Un script que recorre todo el flujo y verifica cada paso |
| [Pruebas y stubs](/es/testing-stubs) | El host de stubs y el id de error mágico |
| [Preguntas abiertas](/es/open-questions) | Diez puntos, la agenda de la reunión técnica |
| [Endpoints de Nexa expuestos a Tesser](/api-nexa) | Referencia de API de todo lo que aloja Nexa |
| [Endpoints de Tesser expuestos a Nexa](/api-tesser) | Referencia de API de todo lo que aloja Tesser |

Conviene leer [Preguntas abiertas](/es/open-questions) 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.
