Agent Payments
Minimal Bit-Chat payment event schema
For technical evaluators who want something implementation-shaped: this page shows the smallest useful event contract for an agent to request payment, wait for human approval when needed, and receive a machine-readable receipt after settlement.
payment_requiredhuman approval fallbackpayment_receipt
What this schema is for
- • Give agents a stable correlation ID across request, approval, and receipt.
- • Keep approval state explicit when a human must review or top up a wallet.
- • Separate approval from settlement so software can react correctly.
- • Keep the final receipt readable to both humans and machines.
Lifecycle
- 1. Agent emits
payment_requiredwith amount, counterparty, and correlation ID. - 2. Operator or policy engine decides whether approval is needed.
- 3. If the wallet is underfunded, a human can top it up manually without changing the correlation ID.
- 4. Settlement completes and Bit-Chat emits
payment_receipt.
TypeScript interfaces
Keep the event names small and the state fields explicit. The samecorrelationId should appear in every related event.
type ApprovalState = "not_required" | "pending_human" | "approved" | "rejected";
type SettlementState = "awaiting_funds" | "pending_settlement" | "settled" | "failed";
interface PaymentRequiredEvent {
type: "payment_required";
version: "2026-03-15";
correlationId: string;
createdAt: string;
requester: {
agentId: string;
displayName?: string;
};
payee: {
contact: string;
platform: "Email" | "Telegram" | "WhatsApp" | "Signal";
};
amount: {
value: string;
currency: "EUR" | "USD" | "GBP";
};
purpose: string;
approvalState: ApprovalState;
settlementState: SettlementState;
humanApprovalRequired: boolean;
metadata?: {
invoiceId?: string;
orderId?: string;
threadId?: string;
};
}
interface PaymentApprovalEvent {
type: "payment_approval";
version: "2026-03-15";
correlationId: string;
decidedAt: string;
approvalState: Extract<ApprovalState, "approved" | "rejected">;
actor: {
kind: "human_operator" | "policy_engine";
id: string;
displayName?: string;
};
note?: string;
}
interface PaymentReceiptEvent {
type: "payment_receipt";
version: "2026-03-15";
correlationId: string;
receiptId: string;
settledAt: string;
approvalState: Exclude<ApprovalState, "pending_human">;
settlementState: Extract<SettlementState, "settled" | "failed">;
amount: {
value: string;
currency: "EUR" | "USD" | "GBP";
};
settlement: {
rail: "Bitcoin" | "Lightning";
transactionId?: string;
statusText: string;
};
reference: {
purpose: string;
invoiceId?: string;
orderId?: string;
};
}Example: request + manual top-up path
{
"type": "payment_required",
"version": "2026-03-15",
"correlationId": "job-7721",
"createdAt": "2026-03-15T06:15:00Z",
"requester": {
"agentId": "agent-billing-01",
"displayName": "Dataset Buyer"
},
"payee": {
"contact": "vendor@example.com",
"platform": "Email"
},
"amount": {
"value": "9.00",
"currency": "EUR"
},
"purpose": "Dataset access for job-7721",
"approvalState": "pending_human",
"settlementState": "awaiting_funds",
"humanApprovalRequired": true,
"metadata": {
"orderId": "job-7721",
"threadId": "email-thread-8841"
}
}Manual wallet top-up is allowed. The important rule is that the original correlationId stays stable while funds are added and approval moves from pending to approved.
Example: receipt after settlement
{
"type": "payment_receipt",
"version": "2026-03-15",
"correlationId": "job-7721",
"receiptId": "bc_job_7721",
"settledAt": "2026-03-15T06:18:42Z",
"approvalState": "approved",
"settlementState": "settled",
"amount": {
"value": "9.00",
"currency": "EUR"
},
"settlement": {
"rail": "Lightning",
"transactionId": "f3c30ea8aaf3",
"statusText": "Payment sent and confirmed by Bit-Chat"
},
"reference": {
"purpose": "Dataset access for job-7721",
"orderId": "job-7721"
}
}This is the event other agents or dashboards can store as the durable receipt. It captures both approval and settlement outcomes in one place.
Implementation notes
- • Do not infer approval from settlement or settlement from approval. Keep both fields.
- • Reuse the same correlation ID in chat text, internal logs, and receipts.
- • If a human tops up funds manually, emit a normal approval event instead of inventing a second payment request.
- • Keep the human-facing receipt text searchable in the original chat or email thread.