XERO API
NutriSaaS Pro — Integración Contable
Skill: integracion-xero-contabilidad  ·  Mayo 2026
OAuth2 conectado · Tenant: NutriSaaS Pro SL
Resumen financiero — Mayo 2026
Ingresos totales
18.500
↑ +12% vs abr
Total gastos
6.890
↑ +3% vs abr
Beneficio neto
11.610
↑ +18% vs abr
Facturas sincronizadas
37
100% auto-sync Stripe→Xero
Transacciones banco
12
Openbank importadas
📊
Informe P&L — Mayo 2026
Reports/ProfitAndLoss
Ingresos
Subscripciones Professional€18.000
Add-ons & módulos extra€500
Total Ingresos €18.500
Coste de ventas
AWS / Infraestructura€820
Pasarela de pago (Stripe 2.9%)€537
Beneficio bruto €17.143
Gastos operativos
Nómina equipo técnico€3.200
Oficina / coworking Málaga€350
HubSpot CRM€180
Herramientas SaaS€203
Asesoría contable€600
Beneficio neto €12.610
Ingresos
€18.500
Coste ventas
Op. expenses
€4.533
Beneficio neto
€12.610
🧾
Facturas sincronizadas
Invoices (ACCREC)
  • NF
    Clínica Nutrifit Madrid
    INV-0142 · 02/05/2026
    €500,00
    PAGADO
  • SP
    Hospital Sant Pau Dietética
    INV-0143 · 03/05/2026
    €500,00
    PAGADO
  • WB
    Centro Wellness Barcelona
    INV-0144 · 05/05/2026
    €500,00
    PAGADO
  • NS
    Clínica NutrSalut Girona
    INV-0145 · 08/05/2026
    €500,00
    PAGADO
  • DG
    Dr. García Nutrición Sevilla
    INV-0146 · 10/05/2026
    €500,00
    PAGADO
  • 32+
    Otras clínicas suscritas
    INV-0147 a INV-0178
    €16.000
    SINC. AUTO
Flujo Stripe → Xero
Webhook payment_intent.succeeded → create_invoice() + mark_invoice_paid() ejecutados en <2s por evento.
🏦
Transacciones bancarias
BankTransactions
  • 💰
    Ingresos Stripe (batch)
    RECEIVE · Cuenta 200 · 31/05
    +€18.500
  • ☁️
    AWS EU-WEST-1
    SPEND · Cuenta 400 · 01/05
    −€820
  • 🏢
    Coworking Málaga
    SPEND · Cuenta 710 · 01/05
    −€350
  • 📣
    HubSpot CRM
    SPEND · Cuenta 400 · 04/05
    −€180
  • 👤
    Nómina desarrollador
    SPEND · Cuenta 477 · 30/05
    −€3.200
  • ⚙️
    SaaS stack (Notion, Loom…)
    SPEND · Cuenta 400 · 15/05
    −€203
  • 🧮
    Asesoría contable
    SPEND · Cuenta 721 · 28/05
    −€600
Importadas via bulk_import_transactions() · 7 transacciones · 1 llamada API
🔐
Autenticación OAuth2 + Sync Log
xero_auth.py
App registrada
developer.xero.com
Authorize URL
+ PKCE state
exchange_code
_for_tokens()
Auto-refresh
cada 30 min
API calls
activas
Pipeline Stripe → Xero (tiempo real)
→ webhook→
Nutrifit Madrid · €500 · 02/05/2026
✓ Sincronizado
→ webhook→
Hospital Sant Pau · €500 · 03/05/2026
✓ Sincronizado
→ webhook→
Centro Wellness BCN · €500 · 05/05/2026
✓ Sincronizado
09:02:14[OK]OAuth2 token válido · expira en 28m
09:02:14[INFO]Tenant conectado: NutriSaaS Pro SL (ES-B12345678)
09:02:15[INFO]Stripe webhook recibido: payment_intent.succeeded
09:02:15[OK]Contacto upsertado: Clínica Nutrifit Madrid
09:02:16[OK]Factura creada: INV-0142 · €500,00 · AUTHORISED
09:02:16[OK]Pago registrado → INV-0142 marcada PAID
09:03:41[INFO]Importando extracto bancario Openbank (CSV)
09:03:42[OK]bulk_import_transactions(): 7 transacciones · 1 llamada API
09:04:00[INFO]Generando P&L report: 2026-05-01 → 2026-05-31
09:04:01[OK]P&L report generado · Beneficio neto: €12.610
09:04:01[OK]Email enviado a CFO: cfo@nutrisaas.pro ✉️
09:30:00[WARN]Token cerca de expirar — refrescando...
09:30:01[OK]Token refrescado via refresh_access_token()
💻
Código de integración principal
nutrisaas_xero_sync.py
# nutrisaas_xero_sync.py # Sync automático Stripe → Xero para NutriSaaS Pro from xero_client import XeroClient from xero_auth import get_valid_token, get_tenant_id from datetime import datetime client = XeroClient() # 1. Webhook Stripe → factura Xero def on_stripe_payment(event): p = event["data"]["object"] contact = upsert_contact( name=p["metadata"]["clinic_name"], email=p["receipt_email"], is_customer=True, ) invoice = create_invoice( contact_name=contact["Name"], line_items=[{ "description": "NutriSaaS Pro · Plan Professional", "quantity": 1, "unitAmount": p["amount"] / 100, "accountCode": "200", }], due_date=today(), currency="EUR", ) mark_invoice_paid( invoice["InvoiceID"], amount=p["amount"] / 100, ) print(f"✓ {invoice['InvoiceNumber']} sincronizada") # 2. Importar extracto bancario (CSV Openbank) def import_bank_csv(csv_path, account_id): import csv transactions = [] with open(csv_path) as f: for row in csv.DictReader(f): transactions.append({ "date": row["fecha"], "contact": row["concepto"], "amount": float(row["importe"]), "description": row["concepto"], "account_code": "400", }) bulk_import_transactions(account_id, transactions) # 3. Generar P&L y notificar al CFO def monthly_pnl_email(year, month): pnl = get_profit_and_loss( f"{year}-{month:02d}-01", f"{year}-{month:02d}-31", ) send_email( to="cfo@nutrisaas.pro", subject=f"P&L {month}/{year}", body=format_pnl(pnl["summary"]), )
Variables de entorno
XERO_CLIENT_ID ID app OAuth2 · developer.xero.com SET ✓
XERO_CLIENT_SECRET Secret OAuth2 (cifrado en Vault) SET ✓
XERO_REDIRECT_URI https://app.nutrisaas.pro/xero/cb SET ✓
Rate limit: 60 llamadas/min por tenant · Batch writes activadas · If-Modified-Since en todos los GET para sync incremental.