# Financiar cuenta (recarga)

### Objetivo

Permitir a un usuario **agregar fondos a su cuenta del mercado** utilizando métodos de pago locales familiares, **sin exponer stablecoins, wallets o conceptos de blockchain.** Estamos usando USDC en Stellar para este ejemplo.&#x20;

***

### Actores

* **Usuario**
* **Frontend de OfferHub**
* **Orquestador de OfferHub (Backend)**
* **Supabase** (perfil de usuario y vinculación de cuenta)
* **API de Airtm**
* **Rails de pago de Airtm**

***

### Precondiciones

* El usuario está autenticado vía Supabase
* El usuario tiene un perfil válido en OfferHub
* El usuario ha **vinculado una cuenta Airtm** (KYC completado)
* OfferHub tiene credenciales válidas de la API de Airtm
* Los endpoints de webhook están registrados y verificados

Si la cuenta Airtm no está vinculada, el usuario es redirigido al **flujo de incorporación de Airtm** primero.

***

### Resumen del flujo

El flujo de financiación es **iniciado por el usuario**, **ejecutado por Airtm**, y **orquestado por OfferHub**.

OfferHub nunca recibe ni retiene fondos de usuarios.

***

### Flujo paso a paso

#### 1. El usuario inicia la recarga

```
Usuario → UI de OfferHub:
  “Agregar fondos”
```

El usuario selecciona:

* monto
* moneda / método de pago (según lo soportado por Airtm)

OfferHub valida:

* sesión de usuario (Supabase)
* vinculación de cuenta Airtm

***

#### 2. OfferHub crea la intención de pago en Airtm

```
Orquestador de OfferHub → API de Airtm:
  Crear Purchase (intención de pay-in)
```

La solicitud incluye:

* referencia de usuario Airtm (email o ID de usuario)
* monto
* moneda
* referencias de retorno / callback

Este paso **aún no mueve fondos** — crea una intención de pago.

***

#### 3. El usuario completa el pago vía Airtm

```
Usuario → Flujo de pago alojado por Airtm
```

Airtm se encarga de:

* selección del método de pago
* rails locales (transferencia bancaria, wallet, etc.)
* controles de cumplimiento
* ejecución de la transacción

OfferHub está **no involucrado** durante este paso.

***

#### 4. Airtm confirma el pago (Webhook)

```
Airtm → Webhook de OfferHub:
  Purchase confirmado
```

El webhook incluye:

* ID de la purchase
* referencia de usuario Airtm
* monto
* estado final

OfferHub debe:

* verificar la firma del webhook
* asegurar idempotencia
* persistir el evento

***

#### 5. OfferHub actualiza el saldo del marketplace

OfferHub:

* registra la recarga exitosa en su libro mayor interno (estado derivado)
* marca al usuario como **listo para financiar**
* actualiza el estado de la UI

> Importante:\
> El “saldo” de OfferHub es **una vista**, no custodia.\
> Airtm sigue siendo el sistema de registro de los fondos.

***

### Post-condiciones

* El usuario tiene saldo disponible para:
  * financiar escrows
  * comprar bienes o servicios
* No se han transferido fondos al marketplace ni al escrow todavía
* El registro de auditoría contiene:
  * intención de pay-in
  * evento de confirmación
  * vinculación de usuario

***

### Resultados

* ✅ El saldo del usuario en el marketplace aumentó (derivado)
* ✅ El saldo en Airtm aumentó (fuente de la verdad)
* ✅ Entrada en el registro de auditoría creada
* ✅ El usuario es elegible para financiar escrows

***

### Escenarios de falla y manejo

#### Pago fallido

* Airtm envía webhook de fallo
* OfferHub actualiza la UI y registra la razón
* Sin cambio de saldo

#### Webhook no recibido

* OfferHub consulta el estado de la purchase en Airtm
* El trabajo de conciliación vuelve a intentar

#### Webhook duplicado

* La clave de idempotencia previene el doble crédito

***

### Notas de seguridad y cumplimiento

* OfferHub nunca almacena:
  * detalles bancarios
  * credenciales de pago
  * saldos de Airtm
* Todos los endpoints de webhook deben:
  * verificar firmas
  * hacer cumplir la protección contra reprodución
* Todas las acciones de financiación deben registrarse

***

### Diagrama de secuencia (simplificado)

```
Usuario → UI de OfferHub: Agregar fondos
OfferHub → API de Airtm: Crear Purchase
Usuario → Airtm: Completar pago
Airtm → Webhook de OfferHub: Purchase confirmada
OfferHub → Supabase: Actualizar saldo derivado
```

***

### Razonamiento del diseño

#### Por qué Airtm posee el saldo

* entidad financiera regulada
* responsabilidad de cumplimiento
* evita riesgo de custodia

#### Por qué OfferHub rastrea un saldo derivado

* mejora la experiencia de usuario
* habilita verificaciones de elegibilidad instantáneas
* evita llamadas constantes a la API

***

### Nota educativa

Este flujo funcionará para cualquier activo emitido en la red Stellar, solo tienes que apuntar al [Trustline](https://docs.trustlesswork.com/trustless-work/es/introduccion/stellar-and-soroban-the-backbone-of-trustless-work/trustlines). Para este ejemplo estamos usando USDc en Stellar.&#x20;
