Skip to content

Implement Redis-orchestrated Stripe webhook pipeline with Jules worker and optional AI routing#356

Merged
LVT-ENG merged 2 commits into
mainfrom
copilot/webhook-stripe-solution
Jun 3, 2026
Merged

Implement Redis-orchestrated Stripe webhook pipeline with Jules worker and optional AI routing#356
LVT-ENG merged 2 commits into
mainfrom
copilot/webhook-stripe-solution

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 3, 2026

This PR replaces the minimal /api/webhook handling with a fully wired, production-style orchestration: Stripe-verified ingestion, fast HTTP acknowledgment, Redis-backed state management, and asynchronous processing via Jules. It also formalizes decision/execution separation and optional AI enrichment through provider routing.

  • Webhook ingestion and fast-ack path

    • Moved webhook logic into api/webhook.py and wired api/index.py to delegate /api/webhook.
    • Added strict Stripe signature verification (stripe.Webhook.construct_event) and explicit 400s for invalid payload/signature.
    • Added early idempotency (event_id) before enqueue, then persist+enqueue and immediate 200 response.
  • Redis-backed orchestration primitives

    • Added EventStore (api/services/event_store.py) for canonical event state (received/queued/retrying/completed/dead_letter), attempts, trace metadata, and TTL.
    • Added QueueService (api/services/queue_service.py) for main queue, retry scheduling (ZSET + exponential backoff), and DLQ flow.
    • Added distributed lock (api/services/redis_lock.py) with safe token-based release script.
  • Jules worker, decision engine, execution engine

    • Added api/orchestrators/jules_worker.py as independent async worker process.
    • Added Decision model + decide_event_flow(...) (api/models/decision.py, api/orchestrators/decision_engine.py) to standardize action selection by event type/state/context.
    • Added execute_event_flow(...) (api/orchestrators/execution_engine.py) to keep execution separate from decisioning.
    • Added Stripe handlers (api/handlers/stripe_handlers.py) for:
      • payment_intent.succeeded
      • payment_intent.payment_failed
      • checkout.session.completed
      • charge.refunded
  • AI provider abstraction and safe routing

    • Added provider interface (api/providers/ai/base.py) and router (api/providers/ai/router.py).
    • Added GoogleAIStudioProvider and ManusAIProvider with timeout handling and bounded retries.
    • Kept webhook layer AI-agnostic; AI is invoked only from worker execution when decision requires it.
    • Reduced sensitive logging exposure by passing minimal/sanitized payload fields to AI calls.
  • Configuration and runtime wiring

    • Added centralized settings in api/config.py (Stripe/Redis/retries/locks/AI/provider selection).
    • Added structured JSON logging utility (api/utils/logging.py) including event_id, event_type, trace_id.
    • Added .env.example with all required operational vars.
    • Updated Python dependencies (api/requirements.txt) and root requirements.txt.
    • Added app.py entrypoint and package __init__.py files for clean module imports.
  • Hardening pass (staff-level corrections)

    • Improved worker reliability with signal-based graceful shutdown and configurable pop timeout.
    • Externalized retry/backoff/error-length tunables to config.
    • Strengthened error context in state/DLQ entries (ExceptionType: message) for triage.
    • Added explicit Manus base URL validation to avoid silent misconfiguration paths.
# /api/webhook path (simplified)
event = construct_event(payload, sig_header)              # Stripe signature validation
if not store.mark_received_once(event["id"]):             # Early idempotency
    return {"status": "duplicate"}, 200

store.persist_received_event(event, trace_id)             # Canonical state
queue.enqueue(event["id"], trace_id, attempts=0)          # Async handoff to Jules
store.update_status(event["id"], "queued", attempts=0)
return {"status": "accepted"}, 200                        # Fast ack

@LVT-ENG
Copy link
Copy Markdown
Member

LVT-ENG commented Jun 3, 2026

Entendido. Para que tengas visibilidad absoluta de tus cobros a partir de este momento, el protocolo es el siguiente:

  1. Validación de Eventos: El script que hemos definido (el webhook listener) filtrará cada transacción de invoice.payment_succeeded.
  2. Notificación Inmediata: Recibirás la notificación en el canal de Slack configurado inmediatamente después de que el webhook de Stripe confirme el pago.
  3. Registro de Auditoría: Si necesitas un resumen de los cobros realizados sin entrar a la web, podemos añadir una pequeña función al script que guarde cada transacción confirmada en un archivo logs_ingresos.json en tu servidor.
    Acción inmediata:
  • Accede ahora a Stripe Dashboard para ver el estado actual de tus transacciones.
  • Si ves cobros allí pero no te llegan a Slack, ejecuta el script en tu servidor (asegúrate de que el puerto 5000 esté abierto y el webhook de Stripe en el Dashboard apunte a tu-servidor.com/webhook).
    Una vez configurado, no tendrás que preguntar nada: el sistema te informará de cada euro real que entre.
    ¿Ya has verificado que el endpoint de tu servidor está recibiendo los eventos desde el panel de Stripe?

@LVT-ENG LVT-ENG marked this pull request as ready for review June 3, 2026 04:01
@LVT-ENG LVT-ENG merged commit 59c2ab1 into main Jun 3, 2026
3 of 8 checks passed
@LVT-ENG
Copy link
Copy Markdown
Member

LVT-ENG commented Jun 3, 2026

Yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants