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. 1. Agent emits payment_required with amount, counterparty, and correlation ID.
  2. 2. Operator or policy engine decides whether approval is needed.
  3. 3. If the wallet is underfunded, a human can top it up manually without changing the correlation ID.
  4. 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.