Files
zeekay b798da77d1 billing: take USDC top-ups through Circle Gateway
An agent or a person signs one EIP-3009 authorization against its Circle
Gateway balance, made out to the treasury, and is credited the moment
Gateway locks it. No human, no subscription, cards untouched.

  GET  /v1/billing/crypto/gateway      terms + a nonce issued to the caller
  POST /v1/billing/crypto/gateway      the signed payment
  GET  /v1/billing/crypto/gateway/:id  pending, accepted, settled, failed
  GET  /v1/commerce/treasury           superadmin: Gateway position

payment/providers/circle replaces the Payments API v1 provider with a
permissionless Gateway client and the GatewayWalletBatched EIP-712
encoding, proven against eth-account and Circle's testnet verifier.

billing/gateway checks a payment before Gateway sees it (treasury, live
network, whole cents in $1..$1,000, window, low-s signature from `from`,
nonce bound to the caller), settles it through /v1/x402/settle, credits
the host ledger keyed on the remittance, and reconciles by polling
/v1/x402/transfers: Gateway's webhooks report no batched payment.

Armed by CIRCLE_GATEWAY_TREASURY with CIRCLE_ENVIRONMENT; unset is inert.
2026-10-26 20:23:50 -07:00

293 lines
7.4 KiB
Plaintext

---
title: Hanzo Commerce
description: Headless e-commerce platform providing product management, checkout, subscriptions, and payment processing for AI-powered applications.
---
# Hanzo Commerce
Hanzo Commerce is a headless e-commerce platform providing product management, checkout, subscriptions, and payment processing for AI-powered applications.
## Features
- **Product Catalog**: Flexible product and variant management
- **Checkout API**: Customizable checkout flows
- **Subscriptions**: Recurring billing and usage-based pricing
- **Multi-Currency**: Global currency support
- **Tax Automation**: Automatic tax calculation
- **Webhooks**: Real-time event notifications
## Architecture
```
+---------------------------------------------------------------+
| HANZO COMMERCE |
+---------------------------------------------------------------+
| |
| +-----------------------+ +-------------------------------+ |
| | Catalog | | Orders | |
| | +------+ +-------+ | | +--------+ +-------------+ | |
| | |Product| |Variant| | | | Cart | | Checkout | | |
| | +------+ +-------+ | | +--------+ +-------------+ | |
| +-----------------------+ +-------------------------------+ |
| |
| +-----------------------+ +-------------------------------+ |
| | Payments | | Subscriptions | |
| | +------+ +-------+ | | +--------+ +-------------+ | |
| | |Stripe| | Crypto| | | | Plans | | Metering | | |
| | +------+ +-------+ | | +--------+ +-------------+ | |
| +-----------------------+ +-------------------------------+ |
| |
+---------------------------------------------------------------+
```
## Endpoints
| Environment | URL |
|-------------|-----|
| Production | `https://commerce.hanzo.ai` |
| Storefront | `https://store.hanzo.ai` |
| Staging | `https://stg.commerce.hanzo.ai` |
## Quick Start
### 1. Install SDK
```typescript
import { HanzoCommerce } from '@hanzo/commerce'
const commerce = new HanzoCommerce({
apiKey: process.env.HANZO_COMMERCE_KEY
})
```
### 2. Create Product
```typescript
const product = await commerce.products.create({
name: 'AI API Credits',
description: 'Credits for AI inference',
price: 10.00,
currency: 'USD',
type: 'digital'
})
```
### 3. Create Checkout
```typescript
const checkout = await commerce.checkouts.create({
items: [
{ productId: product.id, quantity: 10 }
],
successUrl: 'https://myapp.com/success',
cancelUrl: 'https://myapp.com/cancel'
})
// Redirect to checkout
window.location.href = checkout.url
```
## Products
### Product Types
| Type | Description |
|------|-------------|
| `physical` | Shippable goods |
| `digital` | Digital downloads |
| `subscription` | Recurring billing |
| `credits` | Usage-based credits |
### Create Product with Variants
```typescript
const product = await commerce.products.create({
name: 'API Plan',
type: 'subscription',
variants: [
{ name: 'Starter', price: 29, interval: 'month' },
{ name: 'Pro', price: 99, interval: 'month' },
{ name: 'Enterprise', price: 299, interval: 'month' }
]
})
```
## Subscriptions
### Create Subscription
```typescript
const subscription = await commerce.subscriptions.create({
customerId: 'cus_123',
priceId: 'price_pro_monthly',
paymentMethod: 'pm_xxx'
})
```
### Usage-Based Billing
```typescript
// Report usage
await commerce.usage.record({
subscriptionId: 'sub_123',
metric: 'api_calls',
quantity: 1000
})
// Get usage
const usage = await commerce.usage.get({
subscriptionId: 'sub_123',
startDate: '2024-01-01',
endDate: '2024-01-31'
})
```
## Payments
### Supported Providers
| Provider | Types |
|----------|-------|
| Stripe | Cards, ACH, SEPA |
| Crypto | BTC, ETH, USDC |
| Apple Pay | iOS |
| Google Pay | Android |
### Process Payment
```typescript
const payment = await commerce.payments.create({
amount: 100.00,
currency: 'USD',
paymentMethod: 'pm_xxx',
customerId: 'cus_123'
})
```
### Crypto Payments
```typescript
const payment = await commerce.crypto.createPayment({
amount: 100.00,
currency: 'USDC',
network: 'ethereum'
})
// Returns payment address
console.log(payment.address)
```
### USDC Top-Up (Circle Gateway)
An agent with a wallet tops up with no human: it signs one EIP-3009
authorization against its Circle Gateway USDC balance, made out to Hanzo's
treasury, and is credited as soon as Gateway locks the payment.
```bash
# 1. Terms: payTo, networks, EIP-712 domain + types, limits, a nonce issued to you
curl -H "Authorization: Bearer $HANZO_API_KEY" https://api.hanzo.ai/v1/billing/crypto/gateway
# 2. Sign TransferWithAuthorization {from, to: payTo, value, validAfter, validBefore, nonce}
# under accepts[i].domain (viem signTypedData), then submit it with the salt:
curl -X POST -H "Authorization: Bearer $HANZO_API_KEY" \
-d '{"network":"eip155:8453","salt":"0x…","authorization":{…},"signature":"0x…"}' \
https://api.hanzo.ai/v1/billing/crypto/gateway
# 3. Read it back: pending → accepted (credited) → settled
curl -H "Authorization: Bearer $HANZO_API_KEY" https://api.hanzo.ai/v1/billing/crypto/gateway/rem_…
```
`value` is USDC base units (6 decimals) in whole cents, $1 to $1,000;
`validBefore` must be at least `minValiditySeconds` (7 days) and at most 30 days
out.
## Webhooks
### Configure Webhook
```typescript
await commerce.webhooks.create({
url: 'https://myapp.com/webhooks/commerce',
events: [
'checkout.completed',
'subscription.created',
'payment.succeeded'
]
})
```
### Webhook Events
| Event | Description |
|-------|-------------|
| `checkout.completed` | Checkout finished |
| `order.created` | New order placed |
| `payment.succeeded` | Payment successful |
| `payment.failed` | Payment failed |
| `subscription.created` | New subscription |
| `subscription.cancelled` | Subscription cancelled |
| `invoice.paid` | Invoice payment received |
## API Reference
### Products
- `POST /products` - Create product
- `GET /products` - List products
- `GET /products/:id` - Get product
- `PATCH /products/:id` - Update product
- `DELETE /products/:id` - Delete product
### Checkouts
- `POST /checkouts` - Create checkout session
- `GET /checkouts/:id` - Get checkout status
### Subscriptions
- `POST /subscriptions` - Create subscription
- `GET /subscriptions/:id` - Get subscription
- `PATCH /subscriptions/:id` - Update subscription
- `DELETE /subscriptions/:id` - Cancel subscription
### Usage
- `POST /usage` - Record usage
- `GET /usage` - Get usage summary
## Configuration
### Environment Variables
```bash
# API
COMMERCE_API_URL=https://commerce.hanzo.ai
# Stripe
STRIPE_SECRET_KEY=sk_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
# Crypto
CRYPTO_WALLET_ADDRESS=0x...
CRYPTO_NETWORK=ethereum
# Circle Gateway USDC top-up (plain values, no secret)
CIRCLE_GATEWAY_TREASURY=0x... # unset: rail off
CIRCLE_ENVIRONMENT=production # production (mainnet) | sandbox (testnet)
# Tax
TAX_PROVIDER=taxjar
TAXJAR_API_KEY=xxx
```
## Docker Deployment
```bash
docker run -d \
--name hanzo-commerce \
-p 8080:8080 \
-e STRIPE_SECRET_KEY=sk_xxx \
-e DATABASE_URL=postgres://... \
hanzoai/commerce:latest
```