feat: Stripe Checkout, Zeptomail, pre-alert linking, perfil 3-tab, carga-pesada landing

- payments: real Stripe Checkout Session (redirect flow), confirmBySession, webhook handler
- notifications: Zeptomail REST email, wa.me WhatsApp links, IntegrationsService injection
- auth: changePassword, updateProfile, disableMfa (TOTP-verified) endpoints
- packages: tryLinkPreAlert() auto-links on create (non-blocking)
- integrations: catalog updated (zeptomail, stripe_webhook_secret; removed sendgrid/whatsapp-api)
- web/portal/perfil: 3-tab layout (datos / contraseña / MFA)
- web/portal/pago: Stripe redirect + ?success=1&session_id= callback, cancelled banner
- web/admin/b2b: fix enum values (EN_COTIZACION, ACEPTADO)
- web/carga-pesada: rich marketing landing (FCL/LCL, 7-step process, sectors, INEN callout)
- tests: fix payments.service.spec (IntegrationsService+ConfigService mocks)
- tests: fix notifications.service.spec (IntegrationsService mock, phone in mockUser)
- all 104 tests passing, API + web builds clean
This commit is contained in:
Lizandro Guarnizo
2026-06-01 20:24:35 -05:00
parent b2f03e654f
commit 98ab5a309c
19 changed files with 979 additions and 134 deletions
+9 -2
View File
@@ -85,9 +85,14 @@ export const api = {
register: (body: any) => request<any>("/auth/register", { method: "POST", body: JSON.stringify(body) }),
login: (body: any) => request<any>("/auth/login", { method: "POST", body: JSON.stringify(body) }),
me: () => request<any>("/auth/me"),
updateProfile: (body: { firstName?: string; lastName?: string; phone?: string }) =>
request<any>("/auth/me", { method: "PATCH", body: JSON.stringify(body) }),
changePassword: (body: { oldPassword: string; newPassword: string }) =>
request<any>("/auth/password", { method: "PATCH", body: JSON.stringify(body) }),
logout: (refreshToken: string) => request<any>("/auth/logout", { method: "POST", body: JSON.stringify({ refreshToken }) }),
setupMfa: () => request<any>("/auth/mfa/setup", { method: "POST" }),
verifyMfa:(totpCode: string) => request<any>("/auth/mfa/verify", { method: "POST", body: JSON.stringify({ totpCode }) }),
setupMfa: () => request<any>("/auth/mfa/setup", { method: "POST" }),
verifyMfa: (totpCode: string) => request<any>("/auth/mfa/verify", { method: "POST", body: JSON.stringify({ totpCode }) }),
disableMfa: (totpCode: string) => request<any>("/auth/mfa/disable", { method: "POST", body: JSON.stringify({ totpCode }) }),
},
packages: {
list: (params?: Record<string,string>) => request<any[]>("/packages" + (params ? "?" + new URLSearchParams(params) : "")),
@@ -168,6 +173,8 @@ export const api = {
request<any>("/payments/intent", { method: "POST", body: JSON.stringify({ packageId, provider }) }),
confirm: (paymentId: string) =>
request<any>(`/payments/${paymentId}/confirm`, { method: "POST" }),
confirmSession: (sessionId: string) =>
request<any>("/payments/confirm-session", { method: "POST", body: JSON.stringify({ sessionId }) }),
},
consolidations: {
list: () => request<any[]>("/consolidations"),