Skip to content

feat(api-utils,ack-pay): add plug-and-play HTTP 402 payment challenge and receipt verification middleware #171

Description

@vhtgzzl

Summary

Proposes adding a standardized, plug-and-play HTTP 402 Payment Required middleware in @repo/api-utils\ (and exposing corresponding helper adapters for ACK-Pay services). This middleware automatically issues cryptographically signed ACK-Pay payment challenges when no valid receipt is supplied, extracts and validates incoming payment receipts (Verifiable Credentials / signed JWTs via @agentcommercekit/ack-pay), and injects verified payment context (\�ckPayment) directly into route handlers.

Motivation & Use Case

Currently, services and demos (such as \demos/payments/src/server.ts) implementing HTTP 402 paywalls must manually implement receipt extraction from \Authorization\ / \X-ACK-Payment-Proof\ headers, hand-roll the 402 error response with signed JWT generation, and catch/verify receipts imperatively inside route handlers.

While @repo/api-utils\ already provides \signedPayloadValidator\ for signed request payloads, there is no corresponding middleware for the ACK-Pay 402 challenge-receipt cycle. Having a dedicated middleware will:

  1. Reduce Boilerplate: Route handlers can be declared cleanly with standard declarative middleware syntax (e.g. \�pp.get('/infer', paymentRequiredValidator(config), (c) => ...)).
  2. Standardize HTTP 402 Challenges: Ensure consistent response formats (challenge nonce, expiration ISO timestamps, currency amounts, multi-network payment options) across all ACK-enabled APIs.
  3. Safety & Fail-Closed Behavior: Automatically reject malformed proofs (400 Bad Request) and unverified/untrusted receipt issuers (403 Forbidden).

Proposed Design

  1. Middleware Definition (\ ools/api-utils/src/middleware/payment-required-validator.ts):
    • Configurable with static \PaymentRequestInit\ or a dynamic resolver function (c: Context) => Promise.
    • Header extraction: Supports \Authorization: Bearer \ and \X-ACK-Payment-Proof.
    • Verification: Uses \�erifyPaymentReceipt\ from @agentcommercekit/ack-pay\ with trusted issuer verification and DID resolution.
    • Context Injection: Sets \c.set(\�ckPayment, verifiedResult).
  2. HTTP Exception Helper:
    • Add \paymentRequired(response?: Response, message?: string)\ helper in \ ools/api-utils/src/exceptions.ts.
  3. Unit Tests (\ ools/api-utils/src/middleware/payment-required-validator.test.ts):
    • Assertive Vitest tests verifying 402 challenge issuance, successful receipt resolution, missing header handling, and invalid receipt rejection.

Potential Drawbacks & Considerations

  • None; this is non-breaking and purely additive to the internal workspace tooling and developer experience.

AI Usage Disclosure

Per AI_POLICY.md: This feature proposal was drafted with the assistance of AI tools (Antigravity AI Assistant). All architectural considerations, API contracts, and edge cases have been reviewed and validated against the ACK monorepo standards.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions