Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions specs/schemes/basket/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Basket Protocol Extension

This directory contains the specification and schema for the `basket` protocol extension in x402 v2.

## Files

- **[scheme_basket.md](scheme_basket.md)**: Full specification with use cases and integration guide
- **[basket.schema.json](basket.schema.json)**: JSON Schema (draft-07) definition

## Overview

The `basket` field enables structured, itemized line items in payment requests, allowing clients to render detailed invoices without custom parsing logic.

### Example

```json
{
"basket": [
{
"name": "Premium Article Access",
"price": "5000000000000000",
"quantity": 1
},
{
"name": "API Credits (100 calls)",
"price": "10000000000000000",
"quantity": 2,
"discount": "1000000000000000"
}
]
}
```

## Schema Fields

Each basket item supports:
- `id` (optional): Unique identifier for the line item (string)
- `name` (required): Human-readable item description
- `price` (required): Amount in smallest asset unit (string)
- `quantity` (optional): Number of units, default 1
- `tax` (optional): Tax amount per item (string)
- `discount` (optional): Discount amount per item (string)
- `metadata` (optional): Extensible object for additional data

## Validation

Use the JSON schema to validate basket data:

```bash
# Example with ajv-cli
ajv validate -s basket.schema.json -d example-basket.json
```
42 changes: 42 additions & 0 deletions specs/schemes/basket/basket.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"$id": "https://x402.org/spec/v2/basket.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Basket",
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"price"
],
"properties": {
"id": {
"type": "string",
"description": "Optional unique identifier for the line item. Useful for inventory tracking, refunds, and correlation across requests."
},
"name": {
"type": "string"
},
"price": {
"type": "string",
"description": "Amount in the smallest unit of the asset."
},
"quantity": {
"type": "integer",
"minimum": 1,
"default": 1
},
"tax": {
"type": "string"
},
"discount": {
"type": "string"
},
"metadata": {
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": false
}
}
196 changes: 196 additions & 0 deletions specs/schemes/basket/scheme_basket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Scheme: `basket`

## Summary

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.

Each item in the basket array includes:
- **id**: Optional unique identifier for the line item (for inventory tracking, refunds, correlation)
- **name**: Human-readable item description
- **price**: Amount in the smallest unit of the asset (e.g., wei, satoshis)
- **quantity**: Number of units (default: 1)
- **tax**: Optional tax amount per item
- **discount**: Optional discount amount per item
- **metadata**: Optional extensible object for additional item data

The basket field complements the existing `extra` field and is compatible with x402 v2.

## Use Cases

### E-commerce Checkout
A merchant selling multiple digital or physical products can provide a detailed breakdown:
```json
{
"basket": [
{
"name": "Premium Article Access",
"price": "5000000000000000",
"quantity": 1
},
{
"name": "API Credits (100 calls)",
"price": "10000000000000000",
"quantity": 2,
"discount": "1000000000000000"
}
]
}
```

### SaaS Subscriptions
Service providers can itemize subscription components, add-ons, and usage-based charges:
```json
{
"basket": [
{
"name": "Pro Plan (Monthly)",
"price": "50000000000000000000",
"quantity": 1
},
{
"name": "Additional User Seats",
"price": "10000000000000000000",
"quantity": 3
},
{
"name": "Overage Charges",
"price": "5000000000000000000",
"quantity": 1,
"metadata": {
"billing_period": "2025-10",
"usage_gb": 25.5
}
}
]
}
```

### Tax & Discount Transparency
Financial applications requiring tax and discount breakdowns per item:
```json
{
"basket": [
{
"name": "Software License",
"price": "100000000000000000000",
"quantity": 1,
"tax": "8000000000000000000",
"metadata": {
"tax_rate": "0.08",
"jurisdiction": "CA"
}
}
]
}
```

### Grocery Shopping
On-chain grocery payments with itemized receipts showing quantities, prices, and applicable taxes:
```json
{
"basket": [
{
"id": "item_bananas_001",
"name": "Organic Bananas (lb)",
"price": "1990000",
"quantity": 3,
"metadata": {
"unit": "lb",
"upc": "4011"
}
},
{
"id": "item_milk_002",
"name": "Milk - Whole (1 gal)",
"price": "4990000",
"quantity": 2,
"tax": "350000",
"metadata": {
"upc": "041303001264",
"category": "dairy"
}
},
{
"id": "item_bread_003",
"name": "Bread - Sourdough",
"price": "5490000",
"quantity": 1,
"metadata": {
"upc": "041130563652",
"organic": true
}
},
{
"id": "item_coffee_004",
"name": "Coffee Beans - Ethiopia (12oz)",
"price": "14990000",
"quantity": 1,
"discount": "2000000",
"metadata": {
"upc": "853045006247",
"member_discount": true
}
}
]
}
```

### Agent-to-Agent Payments
LLM agents purchasing tool access or resources can track itemized costs:
```json
{
"basket": [
{
"name": "GPT-4 API Call",
"price": "200000000000000",
"quantity": 15,
"metadata": {
"tokens_used": 4500,
"model": "gpt-4-turbo"
}
}
]
}
```

## Schema Definition

**Schema URI**: `https://x402.org/spec/v2/basket.schema.json`

### Validation Rules

1. **Type**: Array of objects
2. **Required fields per item**: `name`, `price`
3. **Optional fields per item**: `id`, `quantity`, `tax`, `discount`, `metadata`
4. **Price format**: String representation of amount in smallest unit
5. **Quantity**: Integer >= 1 (default: 1)
6. **Item ID**: Optional string for tracking and correlation (follows Stripe pattern)
7. **No additional properties**: Items cannot have fields beyond the defined schema

### Integration with PaymentRequirements

When constructing a `PaymentRequirements` response, include the `basket` field alongside the existing `extra` field:

```typescript
{
"asset": "0x...",
"amount": "25000000000000000",
"extra": "2 items: Premium Article + API Credits",
"basket": [
{
"name": "Premium Article Access",
"price": "5000000000000000",
"quantity": 1
},
{
"name": "API Credits (100 calls)",
"price": "10000000000000000",
"quantity": 2
}
]
}
```

### Implementation Notes
- Sum of `(price + tax - discount) * quantity` for all items should equal the total `amount`
- Servers should validate basket totals match the requested amount before returning payment requirements