MII-009: Wallet y Creditos
id: MII-009
type: Epic
status: Pendiente
priority: P0
phase: 3
story_points: 13
created_date: 2026-01-10
updated_date: 2026-01-10
simco_version: "4.0.0"
Metadata
| Campo |
Valor |
| ID |
MII-009 |
| Nombre |
Wallet y Creditos |
| Fase |
3 - Monetizacion |
| Prioridad |
P0 |
| Story Points |
13 |
| Estado |
Pendiente |
1. Descripcion
Implementar el sistema de wallet de creditos que permite a los usuarios consumir creditos por sesion de inventario, con registro transparente de costos y precios.
Objetivo
Crear un sistema de monetizacion justo y transparente basado en consumo, donde el usuario paga el doble del costo real de la IA.
2. Requerimientos Relacionados
| RF |
Descripcion |
Prioridad |
| FR-080 |
Cartera de creditos por usuario/tienda |
P0 |
| FR-081 |
Consumo de creditos por sesion (configurable) |
P0 |
| FR-082 |
Motor de costos COGS IA (proveedor, frames, costo) |
P0 |
| FR-083 |
Regla de precio: 2x COGS IA |
P0 |
| FR-084 |
Transparencia: mostrar creditos y equivalencia MXN |
P1 |
3. Criterios de Aceptacion
AC-001: Wallet de Usuario
DADO que soy un usuario registrado
CUANDO veo mi wallet
ENTONCES veo mi saldo de creditos
Y veo el equivalente aproximado en MXN
Y veo el historial de transacciones
AC-002: Consumo por Sesion
DADO que tengo creditos suficientes
CUANDO inicio una sesion de inventario
ENTONCES se reservan creditos estimados
Y al completar, se cobra el monto real
Y si falla, se liberan los creditos reservados
AC-003: Creditos Insuficientes
DADO que no tengo creditos suficientes
CUANDO intento iniciar una sesion
ENTONCES veo un mensaje indicando falta de saldo
Y me ofrecen comprar un paquete
Y no puedo continuar sin creditos
AC-004: Calculo de COGS
DADO que una sesion se proceso
CUANDO el sistema calcula el costo
ENTONCES registra:
- Proveedor de IA usado
- Numero de frames procesados
- Tokens/llamadas consumidas
- Costo en USD y MXN
AC-005: Precio = 2x COGS
DADO que el COGS de una sesion es X
CUANDO se calcula el precio al usuario
ENTONCES el precio es 2 * X
Y se muestra de forma transparente
AC-006: Transparencia
DADO que complete una sesion
CUANDO veo el detalle de consumo
ENTONCES veo:
- Creditos consumidos
- Costo base (COGS)
- Precio cobrado (2x)
- Equivalente en MXN
4. Tareas Tecnicas
| ID |
Tarea |
Estimacion |
Estado |
| T-001 |
Crear modulo credits en NestJS |
1 SP |
Pendiente |
| T-002 |
Implementar entidad CreditWallet |
1 SP |
Pendiente |
| T-003 |
Implementar transacciones atomicas |
2 SP |
Pendiente |
| T-004 |
Crear motor de COGS |
2 SP |
Pendiente |
| T-005 |
Implementar regla de pricing 2x |
1 SP |
Pendiente |
| T-006 |
Crear pantalla de wallet en mobile |
2 SP |
Pendiente |
| T-007 |
Implementar validacion pre-sesion |
1 SP |
Pendiente |
| T-008 |
Crear historial de transacciones |
2 SP |
Pendiente |
| T-009 |
Implementar jobs de reconciliacion |
1 SP |
Pendiente |
5. Modelo de Datos
Tabla: credit_wallets
CREATE TABLE credit_wallets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) UNIQUE,
balance DECIMAL(12,4) DEFAULT 0,
reserved DECIMAL(12,4) DEFAULT 0,
lifetime_credits DECIMAL(12,4) DEFAULT 0,
lifetime_spent DECIMAL(12,4) DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- balance: creditos disponibles
-- reserved: creditos reservados para sesiones en progreso
-- lifetime_credits: total creditos comprados
-- lifetime_spent: total creditos consumidos
Tabla: credit_transactions
CREATE TABLE credit_transactions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
wallet_id UUID REFERENCES credit_wallets(id),
type VARCHAR(20), -- 'PURCHASE', 'CONSUMPTION', 'REFUND', 'BONUS', 'REFERRAL'
amount DECIMAL(12,4) NOT NULL,
balance_after DECIMAL(12,4),
reference_type VARCHAR(50), -- 'PAYMENT', 'SESSION', 'REFERRAL_REWARD'
reference_id UUID,
metadata JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
Tabla: cogs_records
CREATE TABLE cogs_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID REFERENCES inventory_sessions(id),
provider VARCHAR(50) NOT NULL,
frames_processed INT,
api_calls INT,
tokens_used INT,
cost_usd DECIMAL(10,6),
exchange_rate DECIMAL(10,4),
cost_mxn DECIMAL(10,4),
price_to_user DECIMAL(10,4), -- 2x cost_mxn
margin DECIMAL(10,4),
calculated_at TIMESTAMP DEFAULT NOW()
);
Tabla: pricing_rules
CREATE TABLE pricing_rules (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100),
type VARCHAR(50), -- 'MULTIPLIER', 'FIXED', 'TIERED'
config JSONB,
is_active BOOLEAN DEFAULT true,
priority INT DEFAULT 0,
valid_from TIMESTAMP,
valid_until TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
6. Motor de COGS
Calculo de Costo
interface COGSCalculation {
provider: string;
framesProcessed: number;
apiCalls: number;
tokensUsed: number;
// Costos
costPerFrame: number; // USD
costPerToken: number; // USD
fixedCost: number; // USD por sesion
// Totales
totalCostUSD: number;
exchangeRate: number; // USD/MXN
totalCostMXN: number;
// Precio usuario
multiplier: number; // 2x por defecto
priceToUser: number; // MXN
margin: number; // MXN
}
function calculateCOGS(session: InventorySession): COGSCalculation {
const provider = getActiveProvider();
const costs = provider.getCosts();
const totalCostUSD =
(session.framesProcessed * costs.perFrame) +
(session.tokensUsed * costs.perToken) +
costs.fixed;
const rate = getExchangeRate('USD', 'MXN');
const totalCostMXN = totalCostUSD * rate;
const multiplier = getPricingMultiplier();
const priceToUser = totalCostMXN * multiplier;
return {
provider: provider.name,
framesProcessed: session.framesProcessed,
tokensUsed: session.tokensUsed,
totalCostUSD,
exchangeRate: rate,
totalCostMXN,
multiplier,
priceToUser,
margin: priceToUser - totalCostMXN
};
}
7. Endpoints API
| Metodo |
Endpoint |
Descripcion |
Auth |
| GET |
/credits/wallet |
Obtener wallet actual |
JWT |
| GET |
/credits/transactions |
Historial transacciones |
JWT |
| GET |
/credits/balance |
Solo balance |
JWT |
| POST |
/credits/reserve |
Reservar para sesion |
JWT |
| POST |
/credits/consume |
Consumir despues de sesion |
JWT |
| POST |
/credits/release |
Liberar reserva |
JWT |
| GET |
/credits/estimate |
Estimar costo sesion |
JWT |
8. Pantallas Mobile
| Pantalla |
Componentes |
| WalletScreen |
Balance, equivalente MXN, botones |
| TransactionHistoryScreen |
Lista transacciones, filtros |
| TransactionDetailScreen |
Detalle, COGS, breakdown |
| InsufficientCreditsModal |
Mensaje, CTA comprar |
| ConsumptionSummaryModal |
Post-sesion, desglose |
9. UI de Wallet
┌─────────────────────────────────────────┐
│ MI WALLET │
├─────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ │ │
│ │ 12.5 │ │
│ │ CREDITOS │ │
│ │ │ │
│ │ ≈ $156.25 MXN │ │
│ └─────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ [+] RECARGAR CREDITOS │ │
│ └─────────────────────────────────┘ │
│ │
│ MOVIMIENTOS RECIENTES │
│ ───────────────────── │
│ │
│ 📥 Recarga $100 MXN +8.0 │
│ Ayer, 3:45 PM │
│ │
│ 📤 Inventario Tienda 1 -1.2 │
│ Ayer, 10:30 AM │
│ │
│ 📥 Bono de referido +1.0 │
│ 8 Ene, 5:00 PM │
│ │
│ [Ver todo el historial →] │
│ │
└─────────────────────────────────────────┘
10. Flujo de Consumo
┌─────────────────────────────────────────────────────────────────┐
│ FLUJO DE CONSUMO │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Iniciar │──▶│ Reservar │──▶│ Procesar │──▶│ Calcular │ │
│ │ Sesion │ │ Creditos │ │ Video │ │ COGS │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ │ │ balance -= estimated │ │
│ │ │ reserved += estimated │ │
│ │ │ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ Consumir │ │
│ │ Real │ │
│ └──────────┘ │
│ │ │
│ reserved -= estimated │ │
│ balance += (estimated - real) │
│ lifetime_spent += real │
│ │
│ SI FALLA: │
│ ───────── │
│ reserved -= estimated │
│ balance += estimated (devolucion) │
│ │
└─────────────────────────────────────────────────────────────────┘
11. Dependencias
Entrada (Requiere)
- MII-002: Autenticacion (usuario)
- MII-005: Procesamiento IA (COGS)
Salida (Bloquea)
- MII-010: Paquetes de Recarga
- MII-011, 012, 013: Pagos
- MII-014: Referidos (rewards)
12. Configuracion
| Parametro |
Valor Default |
Descripcion |
| PRICING_MULTIPLIER |
2.0 |
Factor sobre COGS |
| MIN_RESERVE |
2.0 |
Creditos minimos a reservar |
| EXCHANGE_RATE_TTL |
1h |
Cache de tipo de cambio |
| FREE_CREDITS_SIGNUP |
3.0 |
Creditos gratis al registrar |
13. Riesgos
| Riesgo |
Probabilidad |
Impacto |
Mitigacion |
| Costos IA suben |
Media |
Alto |
Pricing dinamico, alertas |
| Race conditions |
Media |
Alto |
Transacciones atomicas |
| Tipo cambio volatil |
Baja |
Medio |
Cache, margen buffer |
14. Notas de Implementacion
- Usar transacciones DB para atomicidad
- Implementar lock optimista en wallet
- Cache de tipo de cambio con TTL
- Considerar creditos con expiracion (futuro)
- Log detallado de cada transaccion
15. Referencias
Ultima Actualizacion: 2026-01-10