PaymentIntent
A PaymentIntent tracks the lifecycle of a single payment request from creation through settlement. It is the core state machine of the ItPay Protocol — every payment flows through a PaymentIntent, whether it is a one-time charge, a cumulative billing invoice payment, or a subscription renewal.
Fields
| Field | Type | Description |
|---|---|---|
id | string (UUIDv7) | Globally unique payment intent identifier |
service_id | string | The ServiceManifest id this intent is paying for |
type | string | Payment type — "one_time", "cumulative", or "subscription" |
amount | Money | Amount to charge in the payer's local currency |
settlement | SettlementInfo | Amount and currency the payee receives after conversion |
description | string | Human-readable description of what this payment is for |
payer | Party | Identity of the paying agent / human |
payee | Payee | Identity and merchant account of the receiving party |
channel | string | Payment channel used (e.g. "alipay", "wechat") |
qr | QRReference | Reference to the associated QRCharge (if any) |
status | Status | Current state in the payment lifecycle |
metadata | object | Arbitrary key-value data (max 4 KB) |
created_at | string (ISO 8601) | Timestamp of intent creation |
expires_at | string (ISO 8601) | Deadline before the intent auto-expires |
Money
| Field | Type | Description |
|---|---|---|
currency | string (ISO 4217) | Currency code |
value | number | Amount in minor currency units (e.g. cents) |
SettlementInfo
| Field | Type | Description |
|---|---|---|
currency | string (ISO 4217) | Settlement currency |
value | number | Amount in settlement currency minor units |
rate | number | Exchange rate applied at intent creation |
Party
| Field | Type | Description |
|---|---|---|
agent_id | string | Unique ID of the agent (MCP client ID or similar) |
human_id | string | Optional — ID of the human user on whose behalf the agent is acting |
Payee
| Field | Type | Description |
|---|---|---|
agent_id | string | Unique ID of the receiving agent |
merchant_account | string | Merchant account identifier on the payment channel |
QRReference
| Field | Type | Description |
|---|---|---|
charge_id | string | ID of the associated QRCharge |
scan_url | string (URL) | URL the payer uses to display or redirect the QR |
Status
The PaymentIntent status is an enumerated string:
| Status | Description |
|---|---|
pending | Intent created, awaiting QR generation |
qr_generated | QR code has been rendered, waiting for payer scan |
scanning | QR code has been scanned, waiting for authorization |
authorized | Payer has authorized the payment (funds held) |
captured | Funds have been captured by the payee |
succeeded | Payment completed successfully |
expired | The intent expired before completion |
cancelled | The intent was manually cancelled |
JSON Example
{
"id": "pi_01J7XZ1A2B3C4D5E6F7G8H9IK",
"service_id": "01J7XYKZ1A2B3C4D5E6F7G8H9I",
"type": "one_time",
"amount": {
"currency": "CNY",
"value": 699
},
"settlement": {
"currency": "USD",
"value": 99,
"rate": 0.1416
},
"description": "AI document summary (42 pages, PDF)",
"payer": {
"agent_id": "agent_cli_a1b2c3d4",
"human_id": "user_abc_789"
},
"payee": {
"agent_id": "agent_srv_9x8y7z6w",
"merchant_account": "summarybot@alipay"
},
"channel": "alipay",
"qr": {
"charge_id": "qr_01J7XZ2C3D4E5F6G7H8I9J0K",
"scan_url": "https://pay.summarybot.ai/qr/qr_01J7XZ2C3D4E5F6G7H8I9J0K"
},
"status": "pending",
"metadata": {
"session_id": "sess_xyz_456",
"file_hash": "sha256:aabbccddeeff00112233445566778899"
},
"created_at": "2026-05-27T09:00:05Z",
"expires_at": "2026-05-27T09:15:05Z"
}
State Machine
┌─────────────┐
│ pending │
└──────┬──────┘
│ QR generated
▼
┌─────────────────┐
│ qr_generated │
└────────┬────────┘
│ payer scans QR
▼
┌──────────────┐
│ scanning │
└───────┬──────┘
│ payer authorizes
▼
┌──────────────┐
│ authorized │
└───────┬──────┘
│ payee captures
▼
┌──────────────┐
│ captured │
└───────┬──────┘
│ settlement confirmed
▼
┌──────────────┐
│ succeeded │
└──────────────┘
Any state ──expires_at reached──▶ expired
Any state ──manual cancel───────▶ cancelled
Transitions
| From | To | Trigger |
|---|---|---|
pending | qr_generated | QR code has been rendered by the payment channel |
qr_generated | scanning | Payer's wallet app has scanned the QR code |
scanning | authorized | Payer has confirmed the payment in their wallet |
authorized | captured | Payee captures the authorized funds |
captured | succeeded | Settlement is confirmed on the payment channel |
| any | expired | expires_at timestamp is reached |
| any | cancelled | Payee or protocol cancels the intent |
Key Behaviors
- Idempotency: Creating a PaymentIntent with the same
idis idempotent. Always generate a unique UUIDv7 per attempt. - Expiry: Intents are short-lived (typically 5–15 minutes). After
expires_at, the QR code becomes invalid and no further transitions are possible. - Cancellation: A payer-facing cancellation (closing the payment UI) maps to the
cancelledterminal state. The payee can also cancel an intent before it is scanned. - Double-spend protection: Only one QRCharge can be associated with a PaymentIntent. Once
qr_generatedis reached, the QR data is fixed. - Metadata: Use
metadatato attach internal identifiers (session IDs, file hashes, order numbers) for reconciliation on the payee side.