Skip to content

Commit 3ada2b0

Browse files
committed
Proposed spec addition for bill/basket support in v2
1 parent 96f6078 commit 3ada2b0

File tree

3 files changed

+290
-0
lines changed

3 files changed

+290
-0
lines changed

specs/schemes/basket/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Basket Protocol Extension
2+
3+
This directory contains the specification and schema for the `basket` protocol extension in x402 v2.
4+
5+
## Files
6+
7+
- **[scheme_basket.md](scheme_basket.md)**: Full specification with use cases and integration guide
8+
- **[basket.schema.json](basket.schema.json)**: JSON Schema (draft-07) definition
9+
10+
## Overview
11+
12+
The `basket` field enables structured, itemized line items in payment requests, allowing clients to render detailed invoices without custom parsing logic.
13+
14+
### Example
15+
16+
```json
17+
{
18+
"basket": [
19+
{
20+
"name": "Premium Article Access",
21+
"price": "5000000000000000",
22+
"quantity": 1
23+
},
24+
{
25+
"name": "API Credits (100 calls)",
26+
"price": "10000000000000000",
27+
"quantity": 2,
28+
"discount": "1000000000000000"
29+
}
30+
]
31+
}
32+
```
33+
34+
## Schema Fields
35+
36+
Each basket item supports:
37+
- `id` (optional): Unique identifier for the line item (string)
38+
- `name` (required): Human-readable item description
39+
- `price` (required): Amount in smallest asset unit (string)
40+
- `quantity` (optional): Number of units, default 1
41+
- `tax` (optional): Tax amount per item (string)
42+
- `discount` (optional): Discount amount per item (string)
43+
- `metadata` (optional): Extensible object for additional data
44+
45+
## Validation
46+
47+
Use the JSON schema to validate basket data:
48+
49+
```bash
50+
# Example with ajv-cli
51+
ajv validate -s basket.schema.json -d example-basket.json
52+
```
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"$id": "https://x402.org/spec/v2/basket.schema.json",
3+
"$schema": "http://json-schema.org/draft-07/schema#",
4+
"title": "Basket",
5+
"type": "array",
6+
"items": {
7+
"type": "object",
8+
"required": [
9+
"name",
10+
"price"
11+
],
12+
"properties": {
13+
"id": {
14+
"type": "string",
15+
"description": "Optional unique identifier for the line item. Useful for inventory tracking, refunds, and correlation across requests."
16+
},
17+
"name": {
18+
"type": "string"
19+
},
20+
"price": {
21+
"type": "string",
22+
"description": "Amount in the smallest unit of the asset."
23+
},
24+
"quantity": {
25+
"type": "integer",
26+
"minimum": 1,
27+
"default": 1
28+
},
29+
"tax": {
30+
"type": "string"
31+
},
32+
"discount": {
33+
"type": "string"
34+
},
35+
"metadata": {
36+
"type": "object",
37+
"additionalProperties": true
38+
}
39+
},
40+
"additionalProperties": false
41+
}
42+
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Scheme: `basket`
2+
3+
## Summary
4+
5+
The `basket` field is an optional protocol extension that provides a structured, machine-readable representation of itemized line items in a payment request. It enables clients to render detailed invoices, receipts, and shopping carts without custom parsing logic, aligning x402 with modern payment APIs.
6+
7+
Each item in the basket array includes:
8+
- **id**: Optional unique identifier for the line item (for inventory tracking, refunds, correlation)
9+
- **name**: Human-readable item description
10+
- **price**: Amount in the smallest unit of the asset (e.g., wei, satoshis)
11+
- **quantity**: Number of units (default: 1)
12+
- **tax**: Optional tax amount per item
13+
- **discount**: Optional discount amount per item
14+
- **metadata**: Optional extensible object for additional item data
15+
16+
The basket field complements the existing `extra` field and is compatible with x402 v2.
17+
18+
## Use Cases
19+
20+
### E-commerce Checkout
21+
A merchant selling multiple digital or physical products can provide a detailed breakdown:
22+
```json
23+
{
24+
"basket": [
25+
{
26+
"name": "Premium Article Access",
27+
"price": "5000000000000000",
28+
"quantity": 1
29+
},
30+
{
31+
"name": "API Credits (100 calls)",
32+
"price": "10000000000000000",
33+
"quantity": 2,
34+
"discount": "1000000000000000"
35+
}
36+
]
37+
}
38+
```
39+
40+
### SaaS Subscriptions
41+
Service providers can itemize subscription components, add-ons, and usage-based charges:
42+
```json
43+
{
44+
"basket": [
45+
{
46+
"name": "Pro Plan (Monthly)",
47+
"price": "50000000000000000000",
48+
"quantity": 1
49+
},
50+
{
51+
"name": "Additional User Seats",
52+
"price": "10000000000000000000",
53+
"quantity": 3
54+
},
55+
{
56+
"name": "Overage Charges",
57+
"price": "5000000000000000000",
58+
"quantity": 1,
59+
"metadata": {
60+
"billing_period": "2025-10",
61+
"usage_gb": 25.5
62+
}
63+
}
64+
]
65+
}
66+
```
67+
68+
### Tax & Discount Transparency
69+
Financial applications requiring tax and discount breakdowns per item:
70+
```json
71+
{
72+
"basket": [
73+
{
74+
"name": "Software License",
75+
"price": "100000000000000000000",
76+
"quantity": 1,
77+
"tax": "8000000000000000000",
78+
"metadata": {
79+
"tax_rate": "0.08",
80+
"jurisdiction": "CA"
81+
}
82+
}
83+
]
84+
}
85+
```
86+
87+
### Grocery Shopping
88+
On-chain grocery payments with itemized receipts showing quantities, prices, and applicable taxes:
89+
```json
90+
{
91+
"basket": [
92+
{
93+
"id": "item_bananas_001",
94+
"name": "Organic Bananas (lb)",
95+
"price": "1990000",
96+
"quantity": 3,
97+
"metadata": {
98+
"unit": "lb",
99+
"upc": "4011"
100+
}
101+
},
102+
{
103+
"id": "item_milk_002",
104+
"name": "Milk - Whole (1 gal)",
105+
"price": "4990000",
106+
"quantity": 2,
107+
"tax": "350000",
108+
"metadata": {
109+
"upc": "041303001264",
110+
"category": "dairy"
111+
}
112+
},
113+
{
114+
"id": "item_bread_003",
115+
"name": "Bread - Sourdough",
116+
"price": "5490000",
117+
"quantity": 1,
118+
"metadata": {
119+
"upc": "041130563652",
120+
"organic": true
121+
}
122+
},
123+
{
124+
"id": "item_coffee_004",
125+
"name": "Coffee Beans - Ethiopia (12oz)",
126+
"price": "14990000",
127+
"quantity": 1,
128+
"discount": "2000000",
129+
"metadata": {
130+
"upc": "853045006247",
131+
"member_discount": true
132+
}
133+
}
134+
]
135+
}
136+
```
137+
138+
### Agent-to-Agent Payments
139+
LLM agents purchasing tool access or resources can track itemized costs:
140+
```json
141+
{
142+
"basket": [
143+
{
144+
"name": "GPT-4 API Call",
145+
"price": "200000000000000",
146+
"quantity": 15,
147+
"metadata": {
148+
"tokens_used": 4500,
149+
"model": "gpt-4-turbo"
150+
}
151+
}
152+
]
153+
}
154+
```
155+
156+
## Schema Definition
157+
158+
**Schema URI**: `https://x402.org/spec/v2/basket.schema.json`
159+
160+
### Validation Rules
161+
162+
1. **Type**: Array of objects
163+
2. **Required fields per item**: `name`, `price`
164+
3. **Optional fields per item**: `id`, `quantity`, `tax`, `discount`, `metadata`
165+
4. **Price format**: String representation of amount in smallest unit
166+
5. **Quantity**: Integer >= 1 (default: 1)
167+
6. **Item ID**: Optional string for tracking and correlation (follows Stripe pattern)
168+
7. **No additional properties**: Items cannot have fields beyond the defined schema
169+
170+
### Integration with PaymentRequirements
171+
172+
When constructing a `PaymentRequirements` response, include the `basket` field alongside the existing `extra` field:
173+
174+
```typescript
175+
{
176+
"asset": "0x...",
177+
"amount": "25000000000000000",
178+
"extra": "2 items: Premium Article + API Credits",
179+
"basket": [
180+
{
181+
"name": "Premium Article Access",
182+
"price": "5000000000000000",
183+
"quantity": 1
184+
},
185+
{
186+
"name": "API Credits (100 calls)",
187+
"price": "10000000000000000",
188+
"quantity": 2
189+
}
190+
]
191+
}
192+
```
193+
194+
### Implementation Notes
195+
- Sum of `(price + tax - discount) * quantity` for all items should equal the total `amount`
196+
- Servers should validate basket totals match the requested amount before returning payment requirements

0 commit comments

Comments
 (0)