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
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
