Introduction
Recharge and bill payment ecosystems are the backbone of modern digital banking, handling millions of high-frequency, low-value transactions daily. While seemingly simple, these systems face complex challenges: dynamic operator downtime, varying transaction limits based on customer tiers, real-time fraud detection, and intricate dispute resolution workflows. Traditional monolithic APIs struggle to adapt to these shifting variables without frequent code deployments. This article details an enterprise-grade architecture using LangGraph to orchestrate a multi-agent system for recharge and bill payments. By leveraging Retrieval-Augmented Generation (RAG) for dynamic bank policy enforcement and persistent state management for auditability, we create a system that is not only intelligent but also compliant and resilient. We will move beyond simple chatbots to build a deterministic workflow where specialized agents collaborate to process payments, handle failures, and resolve customer queries in real-time.
Real-Time Use Case: The "Smart Utility" Dispute Resolution
Consider a scenario where a customer attempts to pay their electricity bill during a known outage window for a specific regional provider. Simultaneously, the customer’s account has hit a daily transaction limit due to recent high-value transfers.
In a traditional system, this would result in a generic "Transaction Failed" error. In our multi-agent system:
The Router Agent identifies the intent as "Bill Payment."
The Policy Agent uses RAG to retrieve the current daily limit policy and the specific operator’s maintenance schedule from internal knowledge bases.
The Validator Agent checks the user’s tier against the retrieved limit.
If the limit is exceeded, the Negotiation Agent engages the user, offering to split the payment or use a different funding source, maintaining context throughout the conversation.
If the operator is down, the Scheduler Agent offers to queue the payment for when services resume.
Architecture Overview: Stateful Multi-Agent Orchestration
The core of this solution is a LangGraph directed graph where nodes represent specialized agents and edges represent conditional logic based on the shared state. Unlike linear chains, this graph can loop, branch, and wait for external input (human-in-the-loop).
Router Agent: Classifies incoming requests (Recharge vs. Bill Pay vs. Dispute).
Policy RAG Agent: Queries vector stores for current bank policies, operator SLAs, and regulatory caps.
Execution Agent: Interfaces with payment gateways and utility APIs.
Compliance Supervisor: Reviews high-risk transactions before final execution.

Defining the Financial State Schema
State management is critical for financial applications. We define a rigid Pydantic-based state schema that travels through the graph, ensuring every agent has access to the full transaction context.
from typing import Annotated, Literal, Optional
from pydantic import BaseModel, Field
from langgraph.graph import MessagesState
class TransactionContext(BaseModel):
transaction_id: str = Field(description="Unique UUID for the transaction")
type: Literal["recharge", "bill_payment"]
amount: float = Field(gt=0, description="Transaction amount")
provider_id: str = Field(description="Operator or Utility Provider ID")
customer_tier: str = Field(description="Customer KYC tier e.g., Gold, Silver")
class PaymentState(MessagesState):
"""Extends LangChain's MessagesState to include financial context."""
context: TransactionContext
policy_rules: Optional[str] = Field(None, description="Retrieved bank policy text")
operator_status: Literal["up", "down", "maintenance"] = "up"
risk_score: float = 0.0
approval_status: Literal["pending", "approved", "rejected", "needs_review"] = "pending"
audit_log: list[str] = Field(default_factory=list)
Code Implementation: Agents, RAG, and Graph Logic
Below is the implementation of the core nodes and the graph assembly. Note the use of checkpointer for persistent memory, which is essential for auditing and resuming interrupted sessions.
from langgraph.graph import StateGraph, END
from langchain_core.runnables import RunnableConfig
# 1. RAG Node: Retrieves dynamic policies
def retrieve_policy_node(state: PaymentState) -> dict:
"""Simulates RAG retrieval for bank limits and operator status."""
# In production: Query Azure AI Search with metadata filters for 'active' policies
policy_text = f"Daily limit for {state['context'].customer_tier} tier is $500. Operator {state['context'].provider_id} is currently UP."
return {"policy_rules": policy_text, "audit_log": [f"Retrieved policy for txn {state['context'].transaction_id}"]}
# 2. Validator Node: Deterministic logic based on RAG output
def validate_transaction_node(state: PaymentState) -> dict:
limit = 500 if state['context'].customer_tier == "Gold" else 200
if state['context'].amount > limit:
return {"approval_status": "rejected", "risk_score": 0.8,
"audit_log": [f"Rejected: Amount {state['context'].amount} exceeds limit {limit}"]}
return {"approval_status": "approved", "risk_score": 0.1,
"audit_log": [f"Validated: Amount within limits"]}
# 3. Execution Node: Mocks payment gateway interaction
def execute_payment_node(state: PaymentState) -> dict:
if state['approval_status'] != "approved":
return {"audit_log": ["Execution skipped due to rejection"]}
# Call external Payment Gateway API here
return {"audit_log": [f"Payment executed for txn {state['context'].transaction_id}"]}
# 4. Conditional Edge Logic
def should_execute(state: PaymentState) -> Literal["execute", "end"]:
if state['approval_status'] == "approved":
return "execute"
return "end"
# 5. Build the Graph
workflow = StateGraph(PaymentState)
workflow.add_node("retrieve_policy", retrieve_policy_node)
workflow.add_node("validate", validate_transaction_node)
workflow.add_node("execute", execute_payment_node)
workflow.set_entry_point("retrieve_policy")
workflow.add_edge("retrieve_policy", "validate")
workflow.add_conditional_edges("validate", should_execute, {"execute": "execute", "end": END})
workflow.add_edge("execute", END)
# Compile with PostgreSQL checkpointer for persistent memory/audit
# app = workflow.compile(checkpointer=postgres_saver)
app = workflow.compile()
Integrating Dynamic Bank Policy via RAG
The retrieve_policy_node is the brain of compliance. Instead of hardcoding limits, it queries a vector database containing bank policy documents. We use Hybrid Search to match both semantic intent ("what is my limit?") and keyword specifics ("Section 4.2 Bill Pay Caps").
Crucially, we filter results by effective_date and region. This ensures that if a new regulatory cap is introduced at midnight, the RAG system immediately reflects this change without requiring a redeployment of the application code. The retrieved policy is stored in the PaymentState, creating an immutable record of which rule was applied to which transaction.
Persistent Memory for Audit Trails
Financial regulations require complete traceability. By using LangGraph’s checkpointing mechanism (e.g., with PostgreSQL), every state transition is saved. This allows us to:
Resume Sessions: If a user drops off during a verification step, they can resume exactly where they left off.
Audit Logs: The
audit_logfield in our state accumulates decisions from each node. This provides a clear, step-by-step explanation of why a transaction was approved or rejected, which is vital for regulatory compliance and customer support disputes.
Conclusion
Building an enterprise recharge and bill payment system requires more than just API integration; it demands intelligent orchestration that respects dynamic policies and maintains strict auditability. By leveraging LangGraph’s multi-agent architecture, we achieve a separation of concerns: RAG handles dynamic policy retrieval, validators enforce deterministic rules, and the graph structure manages complex flows like retries and human-in-the-loop approvals.
This approach transforms a static payment pipeline into a responsive, policy-aware financial service. For architects and engineers, the key takeaway is the importance of structured state and persistent memory. These elements ensure that as AI becomes more prevalent in fintech, it remains transparent, compliant, and trustworthy. As you prepare for senior roles or train teams, emphasize that in finance, AI must not only be smart but also explainable and auditable.

Join the conversation! Your thoughts help the community grow.