Proposed spec addition for bill/basket support in v2
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
idfield for inventory tracking, refunds, and correlation (follows Stripe ACP pattern) - Flexible metadata: Extensible
metadatafield 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
extrafield, 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
uint256representation - Aligns with Stripe ACP's
base_amountformat - Consistent with existing x402
amountfields
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
- [x] I have formatted and linted my code
- [x] All new and existing tests pass
- [x] 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 (
idfield) - Product naming and descriptions
- String-based amounts (
price↔base_amount) - Quantity tracking
- Tax support
- Metadata extensibility
x402 enhancements:
- Flat structure (simpler than ACP's nested
itemobject) - Built-in
discountfield (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?
🟡 Heimdall Review Status
| Requirement | Status | More Info | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Reviews |
🟡
0/1
|
Denominator calculation
|
@dennj is attempting to deploy a commit to the Coinbase Team on Vercel.
A member of the Team first needs to authorize it.