{
  "id": "ledger-api/stripe-webhook-idempotency",
  "slug": "stripe-webhook-idempotency",
  "title": "Session: stripe-webhook-idempotency — 2026-09-01",
  "type": "source",
  "project": "ledger-api",
  "date": "2026-09-01",
  "started": "2026-09-01T14:00:00+00:00",
  "ended": "2026-09-01T15:48:00+00:00",
  "model": "gpt-5-codex",
  "cwd": "/home/dev/code/ledger-api",
  "git_branch": "feat/stripe-webhooks",
  "permission_mode": "default",
  "user_messages": 1,
  "tool_calls": 3,
  "tools_used": [
    "Bash",
    "Edit",
    "Write"
  ],
  "is_subagent": false,
  "wikilinks_out": [
    "Idempotency",
    "PostgreSQL",
    "Stripe",
    "ledger-api"
  ],
  "body_text": "Project: ledger-api · Branch: feat/stripe-webhooks · Mode: default · Model: gpt-5-codex\n\nSummary\n\nMade Stripe webhook handling idempotent: every event id is recorded in a processed_events table inside the same transaction as the side effect, so retries from Stripe can never double-credit an invoice.\n\nConversation\n\nTurn 1 — User\n\nStripe retries webhooks. Make sure we never apply the same event twice.\n\nTurn 1 — Assistant\n\nInsert the event id into processed_events (unique) in the same transaction as the invoice update; on a unique-violation, return 200 and skip. Signature verification stays first.\n\n@router.post(\"/webhooks/stripe\")\nasync def stripe_webhook(request: Request, db: Session = Depends(get_db)):\n    event = verify_signature(await request.body(), request.headers)\n    try:\n        with db.begin():\n            db.add(ProcessedEvent(id=event.id))\n            apply_event(db, event)\n    except IntegrityError:\n        return {\"status\": \"duplicate\"}   # already handled\n    return {\"status\": \"ok\"}\n\nTools used in this turn:\n\n- Edit: ledger/webhooks.py\n- Write: migrations/versions/0004_processed_events.py\n- Bash: pytest tests/test_webhooks.py -q — 6 passed\n\nConnections\n\n- ledger-api\n- Stripe\n- Idempotency\n- PostgreSQL",
  "sha256": "c690426a18526843",
  "source_url": "sessions/ledger-api/2026-09-01-stripe-webhook-idempotency.html"
}