For the complete documentation index, see llms.txt. This page is also available as Markdown.

Pay an Invoice Safely

Create a PaymentIntent, route it through approval when needed, then execute it.

This page is optional for headless integrations.

Goal: create a payment intent, respect the tenant policy decision, and execute only an approved intent through the section 6 gate.

Create an Invoice Payment

const intent = await brain.payments.create({
  type: "pay_invoice",
  invoice_id: "inv_8231",
  idempotencyKey: "example-idempotency-key-1",
});

console.log(intent.id, intent.status, intent.policy_decision_id);

The API derives the tenant from the credential. The idempotency key is sent as the Idempotency-Key header.

Handle the Policy Result

if (intent.status === "approved" && intent.id) {
  const execution = await brain.payments.execute(intent.id);
  console.log(execution.paymentIntentId, execution.outboxId, execution.status);
} else if (intent.status === "pending_approval" && intent.id) {
  console.log("waiting for a member approval", intent.id);
} else if (intent.status === "rejected") {
  console.log("policy rejected the payment", intent.policy_decision_id);
}

Use brain.payments.create(params) for explicit control over the intent lifecycle. It returns the policy result so the integration can decide whether to wait for approval, show the policy decision, or execute an already approved intent.

Approve, Then Execute

Approval and execution are separate calls. A second distinct approver may be required before the intent becomes approved.

Create a Standard Payment

Get a Verifiable Proof

The proof contains the Merkle root and proof, any rail receipt, and the Base Sepolia chain anchor when one is available.

Receive Lifecycle Webhooks

Event
Meaning

payment_intent.created

The intent was created

payment_intent.approved

Required human approvals completed

payment_intent.rejected

Policy or an approver rejected the intent

payment_intent.execute.after

The section 6 gate evaluated before dispatch

payment_intent.executed

The rail completed the payment

payment_intent.failed

The rail failed deterministically

Handle a Failure

Payment and gate failures use lowercase snake-case error codes, returned in the standard error envelope:

What's Next

Last updated