Skip to main content

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

FieldTypeDescription
idstring (UUIDv7)Globally unique payment intent identifier
service_idstringThe ServiceManifest id this intent is paying for
typestringPayment type — "one_time", "cumulative", or "subscription"
amountMoneyAmount to charge in the payer's local currency
settlementSettlementInfoAmount and currency the payee receives after conversion
descriptionstringHuman-readable description of what this payment is for
payerPartyIdentity of the paying agent / human
payeePayeeIdentity and merchant account of the receiving party
channelstringPayment channel used (e.g. "alipay", "wechat")
qrQRReferenceReference to the associated QRCharge (if any)
statusStatusCurrent state in the payment lifecycle
metadataobjectArbitrary key-value data (max 4 KB)
created_atstring (ISO 8601)Timestamp of intent creation
expires_atstring (ISO 8601)Deadline before the intent auto-expires

Money

FieldTypeDescription
currencystring (ISO 4217)Currency code
valuenumberAmount in minor currency units (e.g. cents)

SettlementInfo

FieldTypeDescription
currencystring (ISO 4217)Settlement currency
valuenumberAmount in settlement currency minor units
ratenumberExchange rate applied at intent creation

Party

FieldTypeDescription
agent_idstringUnique ID of the agent (MCP client ID or similar)
human_idstringOptional — ID of the human user on whose behalf the agent is acting

Payee

FieldTypeDescription
agent_idstringUnique ID of the receiving agent
merchant_accountstringMerchant account identifier on the payment channel

QRReference

FieldTypeDescription
charge_idstringID of the associated QRCharge
scan_urlstring (URL)URL the payer uses to display or redirect the QR

Status

The PaymentIntent status is an enumerated string:

StatusDescription
pendingIntent created, awaiting QR generation
qr_generatedQR code has been rendered, waiting for payer scan
scanningQR code has been scanned, waiting for authorization
authorizedPayer has authorized the payment (funds held)
capturedFunds have been captured by the payee
succeededPayment completed successfully
expiredThe intent expired before completion
cancelledThe 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

FromToTrigger
pendingqr_generatedQR code has been rendered by the payment channel
qr_generatedscanningPayer's wallet app has scanned the QR code
scanningauthorizedPayer has confirmed the payment in their wallet
authorizedcapturedPayee captures the authorized funds
capturedsucceededSettlement is confirmed on the payment channel
anyexpiredexpires_at timestamp is reached
anycancelledPayee or protocol cancels the intent

Key Behaviors

  • Idempotency: Creating a PaymentIntent with the same id is 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 cancelled terminal 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_generated is reached, the QR data is fixed.
  • Metadata: Use metadata to attach internal identifiers (session IDs, file hashes, order numbers) for reconciliation on the payee side.