How to Integrate LangGraph for payments with LangSmith for RAG

By Cyprian AaronsUpdated 2026-04-22
langgraph-for-paymentslangsmithrag

If you’re building an agent that can answer questions from internal docs and also trigger payment flows, you need two things: a control plane for the money movement and a trace layer for the retrieval path. LangGraph gives you the stateful orchestration for payment steps, while LangSmith gives you visibility into the RAG side so you can debug retrieval quality, prompt behavior, and tool usage.

The useful pattern here is simple: use LangGraph to route and validate payment actions, and use LangSmith to instrument the retrieval chain that feeds those decisions. That gives you auditable payment execution plus traceable answer generation in one system.

Prerequisites

  • Python 3.10+
  • langgraph
  • langchain
  • langsmith
  • A vector store or retriever source for RAG
  • API keys configured:
    • LANGSMITH_API_KEY
    • LANGSMITH_TRACING=true
    • OPENAI_API_KEY or another LLM provider key
  • A payments backend or sandbox API you can call from a tool function
  • Basic familiarity with:
    • StateGraph in LangGraph
    • LangChain retrievers
    • LangSmith tracing

Install the core packages:

pip install langgraph langchain langsmith langchain-openai

Integration Steps

  1. Set up LangSmith tracing for your RAG pipeline

    Start by enabling tracing so every retrieval and generation step is visible in LangSmith. This is what lets you inspect which documents were retrieved before the agent decided whether a payment action was needed.

import os

os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "lsv2_your_key_here"
os.environ["LANGCHAIN_PROJECT"] = "payments-rag-agent"

If you build your chain with LangChain components, traces will show up automatically once tracing is enabled.

  1. Build a retriever-backed RAG chain

    Use a retriever to ground the agent in policy docs, invoice rules, or payment approval procedures. In production, this should be pointed at your internal knowledge base.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.documents import Document
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_openai import OpenAIEmbeddings

docs = [
    Document(page_content="Payments above $10,000 require manager approval."),
    Document(page_content="Refunds must reference an original transaction ID."),
]

vectorstore = InMemoryVectorStore.from_documents(docs, OpenAIEmbeddings())
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

prompt = ChatPromptTemplate.from_messages([
    ("system", "Answer using only the provided context."),
    ("human", "Question: {question}\n\nContext:\n{context}")
])

def format_docs(documents):
    return "\n\n".join(d.page_content for d in documents)

def rag_answer(question: str) -> str:
    retrieved_docs = retriever.invoke(question)
    context = format_docs(retrieved_docs)
    messages = prompt.format_messages(question=question, context=context)
    return llm.invoke(messages).content

Once this runs under LangSmith tracing, you’ll see retriever calls and model outputs in the trace UI.

  1. Create a LangGraph workflow for payment decisions

    Now model the payment flow as a graph. The graph should decide whether to approve, reject, or escalate based on retrieved policy context.

from typing import TypedDict, List
from langgraph.graph import StateGraph, END

class PaymentState(TypedDict):
    question: str
    context: str
    decision: str
    result: str

def retrieve_policy(state: PaymentState) -> PaymentState:
    docs = retriever.invoke(state["question"])
    state["context"] = format_docs(docs)
    return state

def decide_payment(state: PaymentState) -> PaymentState:
    prompt_text = f"""
You are a payments policy engine.
Question: {state['question']}
Context: {state['context']}

Return one of: approve, reject, escalate.
"""
    decision = llm.invoke(prompt_text).content.strip().lower()
    state["decision"] = decision
    return state

def execute_payment(state: PaymentState) -> PaymentState:
    if state["decision"] == "approve":
        state["result"] = "Payment approved and queued for execution."
    elif state["decision"] == "reject":
        state["result"] = "Payment rejected due to policy."
    else:
        state["result"] = "Payment escalated for manual review."
    return state

graph = StateGraph(PaymentState)
graph.add_node("retrieve_policy", retrieve_policy)
graph.add_node("decide_payment", decide_payment)
graph.add_node("execute_payment", execute_payment)

graph.set_entry_point("retrieve_policy")
graph.add_edge("retrieve_policy", "decide_payment")
graph.add_edge("decide_payment", "execute_payment")
graph.add_edge("execute_payment", END)

app = graph.compile()

This is the core integration point. LangGraph handles the branching and state transitions; LangSmith captures what happened inside each node if tracing is enabled.

  1. Connect RAG output to payment execution

    Your agent should not send money just because an LLM said so. The safer pattern is to let RAG provide policy evidence, then use deterministic code for execution against your payment provider or internal ledger service.

def process_payment_request(question: str):
    initial_state: PaymentState = {
        "question": question,
        "context": "",
        "decision": "",
        "result": ""
    }
    final_state = app.invoke(initial_state)
    return {
        "decision": final_state["decision"],
        "result": final_state["result"],
        "policy_context": final_state["context"],
    }

response = process_payment_request(
    "Can we approve a $12,500 vendor payment for invoice INV-1042?"
)

print(response)

In a real system, replace execute_payment() with a tool call to Stripe, Adyen, an ERP API, or your bank’s internal settlement service. Keep execution separate from reasoning.

  1. Add explicit LangSmith traces around custom logic

    For custom functions outside standard LCEL chains, wrap them in spans so debugging stays clean. This matters when you need to inspect why a payment was escalated or why retrieval missed a policy doc.

from langsmith import traceable

@traceable(name="payment_request_handler")
def traced_process_payment_request(question: str):
    initial_state: PaymentState = {
        "question": question,
        "context": "",
        "decision": "",
        "result": ""
    }
    final_state = app.invoke(initial_state)
    return final_state

result = traced_process_payment_request(
    "Approve refund for transaction TXN-8831?"
)
print(result["decision"], result["result"])

Testing the Integration

Run one request through the graph and verify that both retrieval and decisioning are visible in LangSmith.

test_question = "Approve a $15,000 supplier payout?"

outcome = process_payment_request(test_question)

print("Decision:", outcome["decision"])
print("Result:", outcome["result"])
print("Context:", outcome["policy_context"])

Expected output:

Decision: escalate
Result: Payment escalated for manual review.
Context: Payments above $10,000 require manager approval.

If tracing is configured correctly, you should also see:

  • A retriever span in LangSmith
  • A model invocation span for policy decisioning
  • A graph execution trace showing node order and final state

Real-World Use Cases

  • Invoice approval agents

    • Retrieve approval thresholds from policy docs with RAG.
    • Use LangGraph to route low-risk invoices automatically and escalate exceptions.
  • Refund assistants

    • Pull refund rules from support documentation.
    • Validate transaction IDs before calling refund APIs through a controlled graph step.
  • Treasury operations copilots

    • Answer questions about disbursement policies.
    • Trigger secure payment workflows only after policy evidence is retrieved and logged.

The production pattern here is not “LLM decides payments.” It’s “RAG explains policy, LangGraph controls execution, and LangSmith proves what happened.” That’s the setup you want when money movement and auditability are both non-negotiable.


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