Saltar al contenido principal

Integración en App Fintech

Esta guía explica cómo integrar Ozzie en una aplicación fintech o bancaria existente. Al final, tu app hará el onboarding de usuarios en Ozzie automáticamente, sincronizará transacciones, mostrará el plan financiero y presentará un coach de IA — todo impulsado por la API de Ozzie.


Visión general de la arquitectura

Tu App (Frontend)
|
| Llamadas a la API
v
Tu Servidor Backend
|
|── POST /users (creación de usuario)
|── POST /users/{id}/intake (intake financiero)
|── POST /users/{id}/plan (generación del plan)
|── POST /users/{id}/goals (establecimiento de metas)
|── POST /users/{id}/money-moves/generate
|── POST /users/{id}/chat/messages
v
API de Ozzie (api.ozzieapp.com/v1)

Principio fundamental: tu frontend nunca llama a Ozzie directamente. Todas las llamadas a la API de Ozzie se hacen del lado del servidor, donde tus credenciales están seguras. Tu frontend habla con tu backend, que orquesta las llamadas a Ozzie.


Prerrequisitos

  • Un client_id y client_secret de la API de Ozzie (obtenerlos en el dashboard de Ozzie o por email en commercial@ozzieapp.com)
  • Un servidor backend (ejemplos en Node.js abajo, pero el patrón aplica a cualquier stack)
  • Un mecanismo para vincular tus IDs de usuario internos con los IDs de usuario de Ozzie

Paso 1: Crear usuario Ozzie al registrarse

Cuando un nuevo usuario completa el registro en tu app, crea su perfil de Ozzie en la misma transacción (o como un paso asíncrono inmediato).

// lib/ozzie.js — cliente compartido de Ozzie
const BASE_URL = 'https://api.ozzieapp.com/v1';
const token = Buffer.from(
`${process.env.OZZIE_CLIENT_ID}:${process.env.OZZIE_CLIENT_SECRET}`
).toString('base64');
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
};

export async function ozzieRequest(method, path, body = null) {
const response = await fetch(`${BASE_URL}${path}`, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Error API Ozzie: ${error.error?.code}${error.error?.message}`);
}
return response.json();
}
// routes/auth.js — llamado durante el registro
export async function handleSignup(req, res) {
const { email, name, language, phone } = req.body;
const internalUser = await db.users.create({ email, name, language, phone });

const { data: ozzieUser } = await ozzieRequest('POST', '/users', {
external_user_id: internalUser.id,
name: internalUser.name,
language: internalUser.language || 'es',
phone_e164: internalUser.phone,
});

await db.users.update(internalUser.id, { ozzie_user_id: ozzieUser.id });
res.json({ user: internalUser });
}
tip

Almacena ozzie_user_id en tu tabla de usuarios junto a tu propio ID. Toda llamada posterior a Ozzie lo requiere.


Paso 2: Recopilar intake financiero

Después del registro, pide al usuario que complete su perfil financiero. Puedes recopilar esto en un flujo de onboarding de varios pasos o en un único formulario.


Paso 3: Generar el plan

Una vez enviado el intake, genera el plan financiero del usuario. Puedes hacerlo de forma inline con el envío del intake o activarlo como un job en background.


Paso 4: Mostrar datos de Ozzie en tu UI

Tu frontend obtiene datos de tu backend, que hace de proxy de Ozzie:

app.get('/api/dashboard', requireAuth, async (req, res) => {
const user = await db.users.findById(req.user.id);
const ozId = user.ozzie_user_id;

const [planRes, goalRes, movesRes] = await Promise.all([
ozzieRequest('POST', `/users/${ozId}/plan`),
ozzieRequest('GET', `/users/${ozId}/goals`),
ozzieRequest('GET', `/users/${ozId}/money-moves?status=available&limit=1`),
]);

res.json({
plan: planRes.data,
goal: goalRes.data,
currentMove: movesRes.data[0] ?? null,
});
});

Paso 5: Integrar el coach de IA

Agrega una interfaz de chat que reenvíe mensajes del usuario al coach de Ozzie:

app.post('/api/chat', requireAuth, async (req, res) => {
const user = await db.users.findById(req.user.id);
const { message } = req.body;

const { data } = await ozzieRequest(
'POST',
`/users/${user.ozzie_user_id}/chat/messages`,
{ message }
);

res.json(data);
});

Consejos y buenas prácticas

Detección de idioma

const language = req.headers['accept-language']?.split(',')[0]?.split('-')[0] ?? 'es';
const ozzieLanguage = ['en', 'pt', 'es'].includes(language) ? language : 'es';

Manejo de errores

try {
const { data } = await ozzieRequest('POST', `/users/${ozId}/plan`);
return data;
} catch (err) {
if (err.message.includes('INTAKE_REQUIRED')) {
return { redirect: '/onboarding/intake' };
}
if (err.message.includes('RATE_LIMIT_EXCEEDED')) {
await delay(5000);
return ozzieRequest('POST', `/users/${ozId}/plan`);
}
throw err;
}
aviso

Los datos de plan en caché pueden volverse obsoletos si el usuario envía nuevas transacciones o actualiza el intake. Invalida y actualiza el caché siempre que envíes nuevos datos a Ozzie.