How to Integrate LlamaIndex for payments with Supabase for multi-agent systems

By Cyprian AaronsUpdated 2026-04-22
llamaindex-for-paymentssupabasemulti-agent-systems

Why this integration matters

If you’re building multi-agent systems for payments, you need two things working together: a reliable way to reason over payment workflows and a persistent store for shared agent state. LlamaIndex gives you the orchestration layer for tool use and retrieval, while Supabase gives you Postgres-backed persistence, auth, and realtime state for agents.

The practical win is simple: one agent can classify a payment issue, another can fetch transaction history, and both can coordinate through Supabase without losing context between turns.

Prerequisites

  • Python 3.10+
  • A Supabase project with:
    • Project URL
    • Service role key
    • A table for agent state, such as agent_sessions
  • LlamaIndex installed with the packages you need for your workflow
  • API keys configured in environment variables
  • A payments backend or mock API your LlamaIndex tool can call
  • Basic familiarity with async Python if you plan to run multiple agents concurrently

Install the core dependencies:

pip install llama-index supabase python-dotenv

Set your environment variables:

export SUPABASE_URL="https://your-project.supabase.co"
export SUPABASE_SERVICE_ROLE_KEY="your-service-role-key"
export OPENAI_API_KEY="your-openai-key"

Integration Steps

1) Connect to Supabase and create a shared agent state table

Start by creating a simple table to store session state across agents. This is what keeps your payment investigator, fraud checker, and customer support agent aligned.

from supabase import create_client, Client
import os

supabase: Client = create_client(
    os.environ["SUPABASE_URL"],
    os.environ["SUPABASE_SERVICE_ROLE_KEY"]
)

# Example schema you should create in Supabase SQL editor:
# create table if not exists agent_sessions (
#   id uuid primary key default gen_random_uuid(),
#   session_id text unique not null,
#   agent_name text not null,
#   state jsonb not null default '{}'::jsonb,
#   updated_at timestamptz not null default now()
# );

Use one row per session or one row per agent-session pair depending on how much isolation you need. For payments workflows, I prefer one session record per customer case.

2) Define a Supabase persistence helper for multi-agent state

Keep the storage logic small and explicit. Don’t hide database writes behind a giant framework abstraction.

from typing import Any, Dict

def upsert_agent_state(session_id: str, agent_name: str, state: Dict[str, Any]):
    payload = {
        "session_id": session_id,
        "agent_name": agent_name,
        "state": state,
    }
    result = supabase.table("agent_sessions").upsert(payload).execute()
    return result.data

def get_agent_state(session_id: str):
    result = (
        supabase.table("agent_sessions")
        .select("*")
        .eq("session_id", session_id)
        .execute()
    )
    return result.data

This gives every agent a durable place to write intermediate results like payment_status, risk_score, or next_action.

3) Create a LlamaIndex tool that calls your payments service

LlamaIndex works well when you wrap external APIs as tools. For payments systems, keep the tool narrow: fetch transaction status, initiate refund checks, or validate invoice references.

import os
import requests
from llama_index.core.tools import FunctionTool

PAYMENTS_API_BASE = os.environ["PAYMENTS_API_BASE"]

def get_payment_status(payment_id: str) -> dict:
    response = requests.get(
        f"{PAYMENTS_API_BASE}/payments/{payment_id}",
        headers={"Authorization": f"Bearer {os.environ['PAYMENTS_API_KEY']}"}
    )
    response.raise_for_status()
    return response.json()

payment_status_tool = FunctionTool.from_defaults(
    fn=get_payment_status,
    name="get_payment_status",
    description="Fetch the current status of a payment by payment ID."
)

That tool becomes available to any agent built with LlamaIndex. In production, keep tool outputs structured so downstream agents can reason over them reliably.

4) Build an agent that reads from Supabase and uses the payment tool

Now wire the two sides together. The agent reads shared context from Supabase, calls the payments tool when needed, then writes back its conclusion.

from llama_index.core.agent.workflow import AgentWorkflow
from llama_index.llms.openai import OpenAI

llm = OpenAI(model="gpt-4o-mini")

payment_agent = AgentWorkflow.from_tools_or_functions(
    tools=[payment_status_tool],
    llm=llm,
    system_prompt=(
        "You are a payments operations agent. "
        "Use the payment status tool when needed. "
        "Return concise JSON with fields: decision, evidence, next_step."
    )
)

def run_payment_case(session_id: str, payment_id: str):
    prior_state = get_agent_state(session_id)

    prompt = f"""
Session context: {prior_state}
Investigate payment ID {payment_id} and decide whether it is settled, pending, or failed.
"""

    result = payment_agent.run(prompt)
    upsert_agent_state(
        session_id=session_id,
        agent_name="payment_agent",
        state={
            "payment_id": payment_id,
            "result": str(result),
        }
    )
    return result

If you’re coordinating multiple agents, this pattern lets each one operate independently while still sharing durable context through Supabase.

5) Add a second agent that consumes the first agent’s output

This is where multi-agent systems start paying off. One agent handles payment verification; another handles customer communication or escalation.

support_agent = AgentWorkflow.from_tools_or_functions(
    tools=[],
    llm=llm,
    system_prompt=(
        "You are a customer support routing agent. "
        "Read shared case context and produce the best next action."
    )
)

def route_case(session_id: str):
    states = get_agent_state(session_id)
    prompt = f"""
Shared case state:
{states}

Decide whether to escalate to disputes, notify customer success, or close the case.
"""
    result = support_agent.run(prompt)
    upsert_agent_state(
        session_id=session_id,
        agent_name="support_agent",
        state={"routing_decision": str(result)}
    )
    return result

The key point here is separation of concerns:

  • LlamaIndex handles reasoning and tool use
  • Supabase handles persistence and cross-agent memory

Testing the Integration

Run one end-to-end check with a known payment ID and confirm both database writes and model output work.

if __name__ == "__main__":
    session_id = "case_12345"
    payment_id = "pay_98765"

    payment_result = run_payment_case(session_id, payment_id)
    route_result = route_case(session_id)

    print("Payment Agent Result:", payment_result)
    print("Support Agent Result:", route_result)

Expected output should look like this:

Payment Agent Result: {"decision":"pending","evidence":"Payment API returned status pending","next_step":"wait_and_recheck"}
Support Agent Result: {"routing_decision":"monitor_case"}

Also verify the rows exist in Supabase:

rows = get_agent_state("case_12345")
print(rows)

You should see at least two records or one consolidated record depending on your schema.

Real-World Use Cases

  • Payment dispute triage

    • One agent checks transaction status.
    • Another pulls customer history from Supabase.
    • A third drafts the escalation summary for operations.
  • Refund orchestration

    • An investigation agent validates whether refund conditions are met.
    • A workflow agent stores approval state in Supabase.
    • A fulfillment agent triggers the refund API only after policy checks pass.
  • Collections and dunning assistants

    • Agents track overdue invoices in Supabase.
    • LlamaIndex tools query billing services for account status.
    • The system decides whether to retry payment, notify the customer, or escalate internally.

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides