Cumulative Pay
The Cumulative Pay capability enables post-paid usage billing — an agent records usage events throughout a billing period, and at the end of the cycle, the accumulated amount is invoiced and charged. This is ideal for token-based, request-based, or time-based pricing models.
Swimlane Diagrams
The following swimlane diagrams trace the full cumulative billing lifecycle across the four parties: Human (Payer), Agent (Buyer), ItPay Protocol, and Channel (Alipay).
1. Usage Recording (Multiple Calls Over Period)
The agent records usage as the human consumes service. Each call accumulates toward the running total for the current billing period.
┌──────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
│ Human │ │ Agent │ │ ItPay │ │ Channel │
│ (Payer) │ │ (Buyer) │ │ Protocol │ │ (Alipay) │
└────┬─────┘ └──────┬───────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ "Summarize │ │ │
│ document #1" │ │ │
│─────────────────>│ │ │
│ │ │ │
│ │ POST /v1/ │ │
│ │ cumulative/ │ │
│ │ record │ │
│ │ {quantity: 1500}│ │
│ │──────────────────> │
│ │ │ │
│ │ 201 Created │ │
│ │ {amount: 1500, │ │
│ │ running_total: │ │
│ │ 1500} │ │
│ │<──────────────────│ │
│ │ │ │
│ "Summary done" │ │ │
│<─────────────────│ │ │
│ │ │ │
│ [Day 2] │ │ │
│ "Summarize │ │ │
│ document #2" │ │ │
│─────────────────>│ │ │
│ │ │ │
│ │ POST /v1/ │ │
│ │ cumulative/ │ │
│ │ record │ │
│ │ {quantity: 2500}│ │
│ │──────────────────> │
│ │ │ │
│ │ 201 Created │ │
│ │ {amount: 2500, │ │
│ │ running_total: │ │
│ │ 4000} │ │
│ │<──────────────────│ │
│ │ │ │
│ "Summary done" │ │ │
│<─────────────────│ │ │
│ │ │ │
│ [Many more │ │ │
│ usage events │ │ │
│ over period...]│ │ │
│ │ │ │
│ "What's my │ │ │
│ running total?"│ │ │
│─────────────────>│ │ │
│ │ │ │
│ │ GET /v1/ │ │
│ │ cumulative/ │ │
│ │ summary │ │
│ │──────────────────> │
│ │ │ │
│ │ 200 OK │ │
│ │ {running_total: │ │
│ │ 45000, │ │
│ │ record_count: │ │
│ │ 30, │ │
│ │ status: │ │
│ │ "recording"} │ │
│ │<──────────────────│ │
│ │ │ │
│ "Running total: │ │ │
│ $450.00" │ │ │
│<─────────────────│ │ │
Interaction Trace — Usage Recording:
// Step 1 — Record first usage event
// REQUEST
POST /v1/cumulative/record
Content-Type: application/json
Authorization: Bearer ***
{
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"service_id": "01J7XYKZ1A2B3C4D5E6F7G8H9I",
"usage": {
"unit": "tokens",
"quantity": 1500
},
"rate": {
"per_unit": 1,
"currency": "USD"
}
}
// RESPONSE
HTTP/1.1 201 Created
Content-Type: application/json
{
"record_id": "rec_01J7Y4C5D6E7F8G9H0I1J2K3L",
"usage": { "unit": "tokens", "quantity": 1500 },
"amount": { "value": 1500, "currency": "USD" },
"running_total": { "value": 1500, "currency": "USD" },
"period": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z"
},
"status": "recording"
}
// Step 2 — Record second usage event (later in period)
// REQUEST
POST /v1/cumulative/record
Content-Type: application/json
Authorization: Bearer ***
{
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"service_id": "01J7XYKZ1A2B3C4D5E6F7G8H9I",
"usage": {
"unit": "tokens",
"quantity": 2500
},
"rate": {
"per_unit": 1,
"currency": "USD"
}
}
// RESPONSE
HTTP/1.1 201 Created
Content-Type: application/json
{
"record_id": "rec_01J7Y5D6E7F8G9H0I1J2K3L4M",
"usage": { "unit": "tokens", "quantity": 2500 },
"amount": { "value": 2500, "currency": "USD" },
"running_total": { "value": 4000, "currency": "USD" },
"period": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z"
},
"status": "recording"
}
// Step 3 — Agent queries the running summary
// REQUEST
GET /v1/cumulative/summary?install_id=inst_01J7Y2A3B4C5D6E7F8G9H0I1J
Authorization: Bearer ***
// RESPONSE
HTTP/1.1 200 OK
Content-Type: application/json
{
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"usage_summary": [
{
"unit": "tokens",
"total_quantity": 45000,
"rate": { "per_unit": 1, "currency": "USD" },
"total_amount": { "value": 45000, "currency": "USD" }
}
],
"running_total": { "value": 45000, "currency": "USD" },
"period": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z"
},
"record_count": 30,
"status": "recording"
}
2. Period End & Invoice Generation
When the billing period ends, ItPay generates an invoice for the accumulated usage and notifies the agent.
┌──────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
│ Human │ │ Agent │ │ ItPay │ │ Channel │
│ (Payer) │ │ (Buyer) │ │ Protocol │ │ (Alipay) │
└────┬─────┘ └──────┬───────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ [Billing period │ │ │
│ ends: │ │ │
│ May 31 23:59] │ │ │
│ │ │ Freeze │
│ │ │ running_total │
│ │ │ ($450.00) │
│ │ │ │
│ │ │ Generate │
│ │ │ invoice │
│ │ │ │
│ │ Webhook: │ │
│ │ cumulative. │ │
│ │ invoiced │ │
│ │<──────────────────│ │
│ │ │ │
│ "Your monthly │ │ │
│ invoice is │ │ │
│ ready: $450.00"│ │ │
│<─────────────────│ │ │
│ │ │ │
│ [Running total │ │ │
│ resets to 0 │ │ │
│ for new period]│ │ │
Interaction Trace — Period End:
// Step 1 — ItPay detects period end (automatic)
// No API call — ItPay's internal scheduler runs at period boundary
// Step 2 — ItPay generates invoice, sends webhook
// WEBHOOK
{
"id": "evt_01J7Z0A1B2C3D4E5F6G7H8I9J",
"type": "cumulative.invoiced",
"data": {
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"service_id": "01J7XYKZ1A2B3C4D5E6F7G8H9I",
"period": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z"
},
"total_amount": { "value": 45000, "currency": "USD" },
"invoice_id": "inv_01J7Z0A1B2C3D4E5F6G7H8I9K",
"due_date": "2026-06-07T23:59:59Z",
"status": "invoiced",
"record_count": 30
},
"created_at": "2026-06-01T00:00:05Z"
}
3. Payment via QR Code
Once invoiced, a QR code is generated for the human to authorize payment.
┌──────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
│ Human │ │ Agent │ │ ItPay │ │ Channel │
│ (Payer) │ │ (Buyer) │ │ Protocol │ │ (Alipay) │
└────┬─────┘ └──────┬───────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ │ PaymentIntent │ │
│ │ created for │ │
│ │ invoice total │ │
│ │ ($450.00) │ │
│ │ │ │
│ │ QRCharge │ │
│ │ generated │ │
│ │ │ │
│ Show QR │ │ │
│ "Scan to pay │ │ │
│ $450.00" │ │ │
│<─────────────────│ │ │
│ │ │ │
│ Scans QR with │ │ │
│ phone & auths │ │ │
│──────────────────────────────────────────────> │
│ │ │ │
│ "Payment sent" │ │ Payment │
│<────────────────────────────────────────────── │
│ │ │ confirmed │
│ │ │<────────────────│
│ │ │ │
│ │ Webhook: │ │
│ │ cumulative. │ │
│ │ paid │ │
│ │<──────────────────│ │
│ │ │ │
│ "Invoice paid: │ │ Status changes │
│ $450.00" │ │ to "paid" │
│<─────────────────│ │ │
│ │ │ │
│ [New period │ │ │
│ usage │ │ │
│ recording │ │ │
│ resumes...] │ │ │
Interaction Trace — Payment:
// Step 1 — Agent fetches or creates QR charge for the invoice
// (ItPay may auto-generate a PaymentIntent tied to the invoice)
// Step 2 — Human scans QR and authorizes in Alipay
// (Human action in Alipay app)
// Step 3 — ItPay confirms payment, sends paid webhook
// WEBHOOK
{
"id": "evt_01J7Z0B2C3D4E5F6G7H8I9J0K",
"type": "cumulative.paid",
"data": {
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"invoice_id": "inv_01J7Z0A1B2C3D4E5F6G7H8I9K",
"payment_intent_id": "pi_01J7Z0B2C3D4E5F6G7H8I9J0L",
"total_amount": { "value": 45000, "currency": "USD" },
"paid_amount": { "value": 45000, "currency": "USD" },
"paid_at": "2026-06-01T09:30:00Z",
"status": "paid",
"period": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z"
}
},
"created_at": "2026-06-01T09:30:05Z"
}
4. Overdue Scenario with Retry
If the invoice isn't paid by the due date, the bill enters overdue status and the agent retries with a new QR code.
┌──────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
│ Human │ │ Agent │ │ ItPay │ │ Channel │
│ (Payer) │ │ (Buyer) │ │ Protocol │ │ (Alipay) │
└────┬─────┘ └──────┬───────┘ └────┬─────┘ └────┬─────┘
│ │ │ │
│ [Invoice due │ │ │
│ date passes │ │ │
│ without │ │ │
│ payment] │ │ │
│ │ │ │
│ │ Webhook: │ │
│ │ cumulative. │ │
│ │ overdue │ │
│ │<──────────────────│ │
│ │ │ │
│ "Payment │ │ │
│ overdue! │ │ │
│ $450.00 due" │ │ │
│<─────────────────│ │ │
│ │ │ │
│ ── Retry ── │ │ │
│ │ │ │
│ Show new QR │ │ │
│ "Please pay │ │ │
│ $450.00" │ │ │
│<─────────────────│ │ │
│ │ │ │
│ Scans QR │ │ │
│──────────────────────────────────────────────> │
│ │ │ │
│ │ │ Payment │
│ │ │ confirmed │
│ │ │<────────────────│
│ │ │ │
│ │ Webhook: │ │
│ │ cumulative. │ │
│ │ paid │ │
│ │<──────────────────│ │
│ │ │ │
│ "Payment │ │ │
│ received! │ │ │
│ $450.00" │ │ │
│<─────────────────│ │ │
│ │ │ │
│ [If payment │ │ │
│ still fails │ │ │
│ after max │ │ │
│ retries: │ │ │
│ install │ │ │
│ suspended] │ │ │
Interaction Trace — Overdue Handling:
// Step 1 — ItPay detects due date passed, sends overdue webhook
// WEBHOOK
{
"id": "evt_01J7Z0C3D4E5F6G7H8I9J0K1L",
"type": "cumulative.overdue",
"data": {
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"invoice_id": "inv_01J7Z0A1B2C3D4E5F6G7H8I9K",
"total_amount": { "value": 45000, "currency": "USD" },
"due_date": "2026-06-07T23:59:59Z",
"overdue_since": "2026-06-08T00:00:00Z",
"retry_count": 0,
"max_retries": 3,
"status": "overdue"
},
"created_at": "2026-06-08T00:00:05Z"
}
// Step 2 — Agent generates a new QR code for the overdue invoice
// (Agent requests a fresh QR charge from the PaymentIntent)
// Step 3 — Human scans QR and completes payment
// Step 4 — ItPay confirms payment, sends paid webhook
// WEBHOOK
{
"id": "evt_01J7Z0D4E5F6G7H8I9J0K1L2M",
"type": "cumulative.paid",
"data": {
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"invoice_id": "inv_01J7Z0A1B2C3D4E5F6G7H8I9K",
"total_amount": { "value": 45000, "currency": "USD" },
"paid_amount": { "value": 45000, "currency": "USD" },
"paid_at": "2026-06-09T14:30:00Z",
"status": "paid",
"note": "Payment received after due date"
},
"created_at": "2026-06-09T14:30:05Z"
}
// Step 5 — If payment still not received after max retries:
// ItPay may suspend the install, halting service until resolved.
Endpoints
| Action | Method | Endpoint | Description |
|---|---|---|---|
| Record Usage | POST | /v1/cumulative/record | Record a usage event against a cumulative billing session |
| Get Summary | GET | /v1/cumulative/summary | Query the running total and period details |
Record Usage: POST /v1/cumulative/record
Record a new usage event. Each event is appended to the running total for the current billing period.
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
install_id | string | yes | The install ID for this service-agent binding |
service_id | string (UUIDv7) | yes | The ServiceManifest id |
usage | object | yes | Usage measurement |
usage.unit | string | yes | Unit of measurement (e.g. tokens, requests, minutes, pages) |
usage.quantity | number | yes | Quantity consumed in this event |
rate | object | yes | Rate applied to convert usage to amount |
rate.per_unit | number | yes | Amount per unit in minor currency units |
rate.currency | string (ISO 4217) | yes | Currency code |
timestamp | string (ISO 8601) | no | When the usage occurred (defaults to server time) |
Request Example
POST /v1/cumulative/record
Content-Type: application/json
Authorization: Bearer sk_inst_a1b2c3d4
{
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"service_id": "01J7XYKZ1A2B3C4D5E6F7G8H9I",
"usage": {
"unit": "tokens",
"quantity": 1500
},
"rate": {
"per_unit": 1,
"currency": "USD"
},
"timestamp": "2026-05-27T09:10:00Z"
}
Response Example
HTTP/1.1 201 Created
Content-Type: application/json
{
"record_id": "rec_01J7Y4C5D6E7F8G9H0I1J2K3L",
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"service_id": "01J7XYKZ1A2B3C4D5E6F7G8H9I",
"usage": {
"unit": "tokens",
"quantity": 1500
},
"rate": {
"per_unit": 1,
"currency": "USD"
},
"amount": {
"value": 1500,
"currency": "USD"
},
"running_total": {
"value": 4500,
"currency": "USD"
},
"period": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z"
},
"timestamp": "2026-05-27T09:10:00Z",
"created_at": "2026-05-27T09:10:05Z"
}
Get Summary: GET /v1/cumulative/summary
Query the current running total and period information for an installation.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
install_id | string | yes | The install ID to query |
service_id | string (UUIDv7) | no | Optional filter by service |
Response Example
HTTP/1.1 200 OK
Content-Type: application/json
{
"install_id": "inst_01J7Y2A3B4C5D6E7F8G9H0I1J",
"usage_summary": [
{
"unit": "tokens",
"total_quantity": 45000,
"rate": { "per_unit": 1, "currency": "USD" },
"total_amount": { "value": 45000, "currency": "USD" }
}
],
"running_total": {
"value": 45000,
"currency": "USD"
},
"period": {
"start": "2026-05-01T00:00:00Z",
"end": "2026-05-31T23:59:59Z"
},
"record_count": 30,
"status": "recording"
}
State Machine
┌─────────────┐
│ recording │
└──────┬──────┘
│ period ends / invoice generated
▼
┌───────────┐
│ invoiced │
└─────┬─────┘
│ payment due
▼
┌─────────────────┐
│ payment_pending │
└────────┬────────┘
┌──────┴──────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ paid │ │ overdue │
└─────────┘ └─────────┘
Transitions
| From | To | Trigger |
|---|---|---|
recording | invoiced | Billing period ends, invoice is generated |
invoiced | payment_pending | Invoice sent to payment channel for processing |
payment_pending | paid | Payment is confirmed on the payment channel |
payment_pending | overdue | Payment not received before the due date |
Key Behaviors
- Per-install billing cycles: Each install has its own billing period based on the service's
pricing.cumulative.billing_cycle(daily, weekly, monthly). - Rate per unit: The
ratefield defines the pricing model. For example,{ per_unit: 1, currency: "USD" }withunit: "tokens"means $0.01 per 1,000 tokens (in minor units: 1 cent per token). - Billing period reset: When a period ends and the invoice is generated, the
running_totalresets to zero for the next period. - Overdue handling: After a configurable grace period, overdue cumulative bills may trigger the install to suspend.
Webhook Events
| Event | Description |
|---|---|
cumulative.invoiced | Invoice generated for the billing period |
cumulative.paid | Cumulative invoice payment confirmed |
cumulative.overdue | Payment due date passed without settlement |
Natural Language Examples
"Record 1,500 tokens used on service Smart Summary for install inst_01J7Y2..."
"What's my running total for Smart Summary this month?"
Next Steps
- Subscribe Pay — Recurring fixed-interval payments
- Request Payment — QR-based one-time payment
- Refund — Refund a cumulative invoice payment