+
+
CoDi y SPEI
+
Recibe pagos con QR CoDi o transferencia SPEI
+
+
+ {/* Tabs */}
+
+
+
+
+
+ {activeTab === 'codi' && (
+ <>
+ {/* Generate QR */}
+
+
+
+ Generar QR de Cobro
+
+
+
+
+
+
+ $
+ setQrAmount(e.target.value)}
+ placeholder="0.00"
+ className="input pl-8"
+ min="1"
+ step="0.01"
+ />
+
+
+
+
+ setQrDescription(e.target.value)}
+ placeholder="Venta de productos"
+ className="input"
+ />
+
+
+
+
+
+
+ {/* How it works */}
+
+
+
+ Como funciona CoDi
+
+
+ - Genera un QR con el monto a cobrar
+ - El cliente escanea el QR con su app bancaria
+ - El pago se refleja en segundos en tu cuenta
+ - Sin comisiones - es gratis
+
+
+
+ {/* CoDi Transactions */}
+
+
+
+ Cobros CoDi Recientes
+
+
+ {codiTransactions && codiTransactions.length > 0 ? (
+
+
+
+
+ | Fecha |
+ Monto |
+ Descripcion |
+ Estado |
+
+
+
+ {codiTransactions.map((tx) => (
+
+ |
+ {new Date(tx.createdAt).toLocaleDateString('es-MX', {
+ day: 'numeric',
+ month: 'short',
+ hour: '2-digit',
+ minute: '2-digit',
+ })}
+ |
+
+ ${tx.amount.toLocaleString('es-MX', { minimumFractionDigits: 2 })}
+ |
+
+ {tx.description || '-'}
+ |
+ {getStatusBadge(tx.status)} |
+
+ ))}
+
+
+
+ ) : (
+
+
+
No hay cobros CoDi aun
+
Genera un QR para empezar a cobrar
+
+ )}
+
+ >
+ )}
+
+ {activeTab === 'spei' && (
+ <>
+ {/* CLABE Card */}
+ {speiInfo ? (
+
+
+
+
+
Tu CLABE Virtual
+
Recibe transferencias SPEI directamente
+
+
+
+
+
CLABE:
+
+
+ {speiInfo.clabe}
+
+
+
+
+
+
+
+
Beneficiario:
+
{speiInfo.beneficiaryName}
+
+
+
Banco:
+
{speiInfo.bankName}
+
+
+
+
+
+ ) : (
+
+
+
+
No tienes CLABE virtual
+
+ Crea tu CLABE virtual para recibir transferencias SPEI
+
+
+
+
+ )}
+
+ {/* How it works */}
+
+
+
+ Como funciona SPEI
+
+
+ - Comparte tu CLABE con el cliente
+ - El cliente hace una transferencia desde su banco
+ - El dinero llega en minutos a tu cuenta
+ - Recibes notificacion cuando llegue el pago
+
+
+
+ {/* SPEI Transactions */}
+
+
+
+ Transferencias Recibidas
+
+
+ {speiTransactions && speiTransactions.length > 0 ? (
+
+
+
+
+ | Fecha |
+ Monto |
+ De |
+ Referencia |
+
+
+
+ {speiTransactions.map((tx) => (
+
+ |
+ {new Date(tx.createdAt).toLocaleDateString('es-MX', {
+ day: 'numeric',
+ month: 'short',
+ hour: '2-digit',
+ minute: '2-digit',
+ })}
+ |
+
+ +${tx.amount.toLocaleString('es-MX', { minimumFractionDigits: 2 })}
+ |
+
+ {tx.senderName}
+ {tx.senderBank}
+ |
+ {tx.reference} |
+
+ ))}
+
+
+
+ ) : (
+
+
+
No hay transferencias recibidas aun
+
Las transferencias SPEI apareceran aqui
+
+ )}
+
+ >
+ )}
+
+ );
+}
diff --git a/src/pages/Tokens.tsx b/src/pages/Tokens.tsx
new file mode 100644
index 0000000..da6b70d
--- /dev/null
+++ b/src/pages/Tokens.tsx
@@ -0,0 +1,328 @@
+import { useState } from 'react';
+import { useQuery, useMutation } from '@tanstack/react-query';
+import { Coins, Package, TrendingUp, Clock, Check, ShoppingCart, MessageSquare, FileText, Sparkles } from 'lucide-react';
+import { billingApi } from '../lib/api';
+
+interface TokenBalance {
+ availableTokens: number;
+ usedTokens: number;
+ totalTokens: number;
+ expiresAt?: string;
+}
+
+interface TokenPackage {
+ code: string;
+ name: string;
+ tokens: number;
+ price: number;
+ pricePerToken: number;
+ popular?: boolean;
+ savings?: number;
+}
+
+interface TokenUsage {
+ id: string;
+ service: 'whatsapp' | 'llm' | 'ocr' | 'invoice';
+ tokensUsed: number;
+ description: string;
+ createdAt: string;
+}
+
+export function Tokens() {
+ const [selectedPackage, setSelectedPackage] = useState