Describe a job in plain English, pay 0.50 USDT on X Layer, and get back a structured invoice plus a ready-to-send PDF. No account, no subscription.
InvoiceCraft is an Agent Service Provider for OKX.AI. It turns a one-sentence job description into a formatted invoice with line items, quantities, tax, and totals, then returns a downloadable PDF. Billing is pay-per-call: each invoice costs 0.50 USDT, settled on X Layer through the x402 protocol. Send zero invoices, pay zero.
- Natural-language input: parse a plain description into structured line items with quantities and rates.
- Pay-per-invoice: 0.50 USDT per call via x402, no subscription.
- On-chain settlement: payments settle in USDT on X Layer (
eip155:196). - Wallet payment in the UI: connect OKX Wallet or MetaMask and pay directly from the demo dashboard.
- PDF output: professional invoice rendered with ReportLab, returned as base64.
- Replay-safe challenges: each payment challenge is single-use and expires after 15 minutes.
- Stateless by design: no accounts, no login. SQLite holds only challenges and the invoice counter.
git clone <repo> && cd InvoiceCraft
pip install -r requirements.txt
export ASP_WALLET=0xYourWallet
python3 -m uvicorn app.main:app --reloadOpen http://localhost:8000/ for the demo dashboard (the app serves it on the same origin as the API). Or POST directly to /api/v1/invoice.
By default the service runs in demo mode: payment verification is mocked and parsing uses the built-in heuristic. See Configuration to enable real on-chain verification and LLM parsing.
Payment is handled by the official OKX Onchain OS Payment SDK (okxweb3-app-x402), which gates POST /api/v1/invoice:
- POST a job description to
/api/v1/invoice. The SDK responds with402 Payment Requiredand aPAYMENT-REQUIREDheader carrying the base64-encoded x402 requirements (schemeexact, networkeip155:196, asset USD₮0, amount in base units,payTo). - Pay 0.50 USDT on X Layer. The OKX Agentic Wallet does this automatically and retries the request with a
PAYMENT-SIGheader. - The SDK verifies and settles the payment through the OKX facilitator, then the service returns the invoice JSON, a base64-encoded PDF, and a
PAYMENT-RESPONSEproof header.
When the OKX credentials are absent (local dev, tests, demo), the service falls back to its own x402 challenge: re-POST with description, payment_tx_hash, and challenge_id and it verifies the USDT transfer directly via web3.
Request (first call, no payment):
{ "description": "Website redesign for FinFlow, 40 hours at 75/hr, plus hosting setup 200" }402 response (payment required). The requirements travel base64-encoded in the PAYMENT-REQUIRED header; decoded, they are:
{
"x402Version": 2,
"error": "Payment required",
"resource": {
"url": "https://invoicecraft-e7yg.onrender.com/api/v1/invoice",
"description": "InvoiceCraft AI invoice generation",
"mimeType": "application/json"
},
"accepts": [
{
"scheme": "exact",
"network": "eip155:196",
"asset": "0x779ded0c9e1022225f8e0630b35a9b54be713736",
"amount": "500000",
"payTo": "0x...",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD₮0", "version": "1" }
}
]
}An x402 client pays and retries the same request with a PAYMENT-SIGNATURE header; no second body shape is needed. The demo dashboard ships one in dashboard/x402-client.js: it decodes the requirements, signs an EIP-3009 TransferWithAuthorization with the connected wallet (eth_signTypedData_v4, so the payer spends no gas), and replays the request with the header. The OKX Agentic Wallet does the same thing automatically.
The fields below describe the fallback flow used when OKX credentials are not configured.
Request (second call, after payment):
{
"description": "Website redesign for FinFlow, 40 hours at 75/hr, plus hosting setup 200",
"payment_tx_hash": "0x...",
"challenge_id": "abc123..."
}200 response:
{
"invoice": {
"issuer": { "name": "...", "address": "0x...", "email": "..." },
"client": { "name": "...", "email": "..." },
"line_items": [
{ "description": "Website redesign for FinFlow", "quantity": 40, "unit_price": "75.00", "amount": "3000.00" },
{ "description": "hosting setup", "quantity": 1, "unit_price": "200.00", "amount": "200.00" }
],
"invoice_number": "INV-20260726-001",
"subtotal": "3200.00",
"tax_rate": "0.08",
"tax_amount": "256.00",
"total": "3456.00",
"currency": "USD",
"due_date": "2026-08-25",
"status": "paid",
"notes": "Payment: 0x... on X Layer"
},
"pdf": "<base64>"
}Validation: description must be 10 to 2000 characters. challenge_id is required when payment_tx_hash is provided.
GET /health reports the active payment_mode and whether AI parsing is enabled.
| Variable | Default | Purpose |
|---|---|---|
ASP_WALLET |
(required) | Receiver address for payments (payTo) |
OKX_API_KEY |
(unset) | OKX Onchain OS dev-portal API key. With the two below, enables the official Payment SDK |
OKX_SECRET_KEY |
(unset) | Secret key used for the facilitator's HMAC-SHA256 signing |
OKX_PASSPHRASE |
(unset) | Dev-portal passphrase |
OKX_BASE_URL |
https://web3.okx.com |
Facilitator base URL |
INVOICE_PRICE_USDT |
0.50 |
Price per invoice, advertised in the 402 |
PAYMENT_CHAIN |
eip155:196 |
CAIP-2 network for payment (X Layer mainnet; testnet is eip155:1952) |
PAYMENT_VERIFY_MODE |
mock |
mock accepts any well-formed tx hash (demo/dev). onchain verifies a real USDT transfer on X Layer |
XLAYER_RPC |
(unset) | X Layer RPC URL, required for onchain mode |
USDT_CONTRACT |
(unset) | USDT token address on X Layer, required for onchain mode |
MIN_CONFIRMATIONS |
1 |
Confirmations required in onchain mode |
LLM_API_KEY |
(unset) | Anthropic API key. Enables LLM line-item parsing, falls back to the heuristic parser when unset |
LLM_MODEL |
claude-sonnet-5 |
Model used for parsing |
TAX_RATE |
0.08 |
Tax rate as a decimal |
DB_PATH |
temp dir | SQLite path (used when Upstash is not configured) |
UPSTASH_REDIS_REST_URL |
(unset) | Upstash Redis REST URL — enables durable persistence across restarts |
UPSTASH_REDIS_REST_TOKEN |
(unset) | Upstash Redis REST token (required with the URL above) |
LLM_API_STYLE |
anthropic |
anthropic or openai (for DeepSeek/OpenRouter/OpenCode) |
LLM_API_URL |
provider default | Chat/messages endpoint for the chosen style |
LLM_MAX_TOKENS |
4096 |
Token budget (keep high for reasoning models) |
Browser (dashboard) ──POST──> FastAPI app (app/main.py)
│
├─ parse ──> LLM (app/ai_parser.py)
│ or heuristic (app/invoice.py)
├─ verify ─> x402 (app/x402.py)
│ mock, or web3 -> X Layer
├─ render ─> ReportLab (app/pdf_engine.py)
└─ state ──> SQLite (app/store.py)
- FastAPI exposes a single invoice endpoint and serves the demo dashboard from the same origin.
- Parsing uses an LLM when
LLM_API_KEYis set. Without a key, a heuristic parser handles hourly rates and flat amounts. - x402 verification issues single-use challenges. In
onchainmode it confirms a USDT transfer to the receiver via web3. - ReportLab renders the invoice PDF.
- SQLite persists challenges and the daily invoice counter, so state survives restarts and stays consistent across workers.
| File | Role |
|---|---|
app/main.py |
FastAPI app, routes, static dashboard mount |
app/invoice.py |
Description parsing, invoice creation, numbering |
app/ai_parser.py |
LLM-based line-item extraction |
app/pdf_engine.py |
ReportLab PDF layout and rendering |
app/okx_payments.py |
Official OKX Payment SDK middleware (402 / PAYMENT-SIG / settlement) |
app/x402.py |
Fallback payment challenge generation and verification |
app/store.py |
SQLite persistence for challenges and counter |
app/tax.py |
Configurable tax rate |
app/models.py |
Pydantic request/response models |
- OKX.AI: InvoiceCraft is built as an Agent Service Provider, listed on the OKX.AI marketplace.
- x402 via the official OKX Payment SDK (
okxweb3-app-x402): pay-per-call billing. Each invoice costs 0.50 USDT, verified and settled through the OKX facilitator before the PDF is generated. - X Layer (
eip155:196): payments settle in USDT on X Layer. On-chain mode verifies the transfer directly via web3. - OKX Agentic Wallet: users pay from the dashboard by connecting a wallet, or from any wallet that supports X Layer USDT transfers.
python3 -m pytest -q40 tests cover description parsing, tax and totals, PDF generation, the x402 challenge lifecycle, the OKX Payment SDK middleware, the browser x402 client's EIP-712 payload, and the full request/response flow. Requires Python 3.11+ (an OKX Payment SDK constraint).
InvoiceCraft/
├── app/ # FastAPI application
│ ├── main.py # Routes + dashboard mount
│ ├── invoice.py # Parsing + invoice assembly
│ ├── ai_parser.py # LLM line-item extraction
│ ├── okx_payments.py # Official OKX Payment SDK middleware
│ ├── x402.py # Fallback payment challenges + verification
│ ├── pdf_engine.py# PDF rendering
│ ├── store.py # SQLite persistence
│ ├── tax.py # Tax rate
│ └── models.py # Pydantic models
├── dashboard/ # Demo UI (served at /)
├── tests/ # pytest suite
├── docs/images/ # Screenshots
├── Dockerfile # Production container
├── render.yaml # Render deploy config
└── requirements.txt
MIT
