Skip to content

Add idempotency keys to POST /usage and POST /settle to prevent double billing #34

Description

@mikewheeleer

Implement idempotency keys on POST /usage and POST /settle to prevent double billing

Description

POST /api/v1/usage and POST /api/v1/settle in src/index.ts are not idempotent: a network retry that re-sends the same request will double-count usage or settle twice, because each call blindly mutates usageStore. For a billing surface that mirrors an on-chain settle(), replay safety is essential. This issue adds an Idempotency-Key header so retried requests return the original result instead of mutating again.

Requirements and context

  • Repository scope: Agentpay-Org/Agentpay-backend only.
  • Honour an Idempotency-Key request header on POST /api/v1/usage, POST /api/v1/usage/bulk, and POST /api/v1/settle.
  • Store the first response keyed by (apiKey-or-ip, idempotency-key) with a TTL; on replay return the stored status + body verbatim and set an Idempotency-Replayed: true header.
  • Detect key reuse with a different body and respond 409 idempotency_conflict (with requestId).
  • Cap the idempotency cache and evict by age, mirroring the existing EVENT_LOG_CAP eviction pattern.
  • Do not change the success-path response shapes.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b feature/payments-04-idempotency-keys
  • Implement changes
    • Write code in: a reusable src/middleware/idempotency.ts plus the route wiring in src/index.ts.
    • Write comprehensive tests in: new src/middleware/idempotency.test.ts — first call, replay, conflict, TTL expiry.
    • Add documentation: document the header behaviour in docs/idempotency.md.
    • Add TSDoc on the middleware factory.
    • Validate security assumptions: key namespacing per caller, no cross-tenant replay.
  • Test and commit

Test and commit

  • Run npm run build, npm test, and npm run lint.
  • Cover edge cases: same key/same body, same key/different body, missing key (passthrough), expired key.
  • Include the full npm test output in the PR description.

Example commit message

feat: add idempotency-key support to usage and settle endpoints

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • 💬 Join the AgentPay community on Discord for questions, reviews, and faster merges: https://discord.gg/eXvRKkgcv
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.

Metadata

Metadata

Assignees

No one assigned

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions