Skip to content

Conversation

@dennj
Copy link
Contributor

@dennj dennj commented Nov 26, 2025

Proposed spec addition for bill/basket support in v2

Description

This PR introduces the basket field as an optional protocol extension to x402 v2, enabling structured, machine-readable representations of itemized line items in payment requests. This allows clients to render detailed invoices, receipts, and shopping carts without custom parsing logic.

Motivation

Currently, x402 v2 uses the extra field for additional payment information, but this is an unstructured object that requires custom client-side parsing. The basket field provides a standardized schema for common use cases like:

  • E-commerce & retail: Multi-item checkouts with quantities, taxes, and discounts
  • Grocery payments: Itemized receipts with UPC codes and per-item pricing
  • SaaS billing: Subscription components, add-ons, and usage-based charges
  • Agent-to-agent payments: LLM agents tracking itemized resource costs

This aligns x402 with modern payment APIs (Stripe, Square, PayPal) that expose structured line items.

Key Features

  • JSON Schema validation: Defined using JSON Schema (draft-07) for strict validation
  • Item tracking: Optional id field for inventory tracking, refunds, and correlation (follows Stripe ACP pattern)
  • Flexible metadata: Extensible metadata field for custom item data (UPCs, categories, etc.)
  • Tax & discount support: Per-item tax and discount fields for transparent pricing
  • String-based amounts: Uses strings for prices to prevent precision loss with large blockchain amounts
  • Backward compatible: Complements existing extra field, doesn't replace it
  • Chain-agnostic: Works with any x402 payment scheme and network
  • ACP-compatible: ~90% compatible with Stripe Agentic Commerce Protocol with simple field mapping

Example

{
  "scheme": "exact",
  "network": "base",
  "maxAmountRequired": "27130000",
  "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
  "payTo": "0x...",
  "extra": "Grocery purchase (3 items)",
  "basket": [
    {
      "id": "item_bananas_001",
      "name": "Organic Bananas (lb)",
      "price": "1990000",
      "quantity": 3,
      "metadata": {"upc": "4011"}
    },
    {
      "id": "item_milk_002",
      "name": "Milk - Whole (1 gal)",
      "price": "4990000",
      "quantity": 2,
      "tax": "350000",
      "metadata": {"upc": "041303001264"}
    },
    {
      "id": "item_coffee_003",
      "name": "Coffee Beans - Ethiopia (12oz)",
      "price": "14990000",
      "quantity": 1,
      "discount": "2000000",
      "metadata": {"member_discount": true}
    }
  ]
}

Design Rationale

Why strings for price/tax/discount?

  • Blockchain amounts can exceed JavaScript's MAX_SAFE_INTEGER (1 ETH = 10^18 wei)
  • Prevents floating-point precision errors
  • Matches blockchain native uint256 representation
  • Aligns with Stripe ACP's base_amount format
  • Consistent with existing x402 amount fields

Tests

Schema Validation

  • ✅ JSON Schema is valid (verified with python3 -m json.tool)
  • ✅ Schema follows draft-07 specification

Documentation

  • ✅ Comprehensive specification document with 5 real-world use cases
  • ✅ README with quick reference and validation examples
  • ✅ Integration guide showing usage with PaymentRequirements
  • ✅ Implementation notes for server-side validation

File Organization

Follows the standard x402 scheme proposal structure (per PR #537):

specs/schemes/basket/
├── basket.schema.json       # JSON Schema definition
├── scheme_basket.md         # Full specification
└── README.md                # Quick reference

Checklist

  • I have formatted and linted my code
  • All new and existing tests pass
  • My commits are signed (required for merge)

Additional Context

Real-World Usage

Latinum.ai is piloting basket support with Shuppa, a grocery delivery service in Dublin, as one of the first real-world grocery payment deployments on x402 v2 (https://latinumai.substack.com/p/what-did-we-learn-from-running-the). While still early-stage, this pilot has validated the schema's practical design for retail scenarios:

  • Itemized digital receipts with product details
  • Per-item tax calculation and transparency
  • Member discount tracking at the line-item level
  • Product metadata for inventory correlation

As x402 adoption grows beyond memecoin transfers, structured basket data will be essential for enabling real commerce use cases like grocery delivery, e-commerce, and SaaS billing.

Stripe Agentic Commerce Protocol (ACP) Compatibility

https://github.com/agentic-commerce-protocol/agentic-commerce-protocol/blob/main/spec/json-schema/schema.agentic_checkout.json

The basket schema is ~90% compatible with Stripe's Agentic Commerce Protocol:

Compatible elements:

  • Item identification (id field)
  • Product naming and descriptions
  • String-based amounts (pricebase_amount)
  • Quantity tracking
  • Tax support
  • Metadata extensibility

x402 enhancements:

  • Flat structure (simpler than ACP's nested item object)
  • Built-in discount field (ACP lacks per-item discounts)
  • Direct blockchain optimization

Merchants can easily convert between formats with simple field mapping, enabling interoperability between x402 and ACP-based systems.

Open Questions

  • Should basket validation be strict (fail if totals don't match) or permissive (warn but allow)?
  • Should we include a image_urls array? It would be beneficial for our usecase, but I see Stripe ACP does not have either, so I wonder if there are security reasons I did not consider
  • Should we rename the ID in SKU as ACP?

@cb-heimdall
Copy link

cb-heimdall commented Nov 26, 2025

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

@vercel
Copy link

vercel bot commented Nov 26, 2025

@dennj is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants