Skip to content

Connect NMI to AI Agents: Automate Invoicing and Customer Vaults

Learn how to connect NMI to AI agents using Truto's /tools endpoint. Fetch tools, bind them via LangChain, and automate complex payment and invoicing workflows.

Uday Gajavalli Uday Gajavalli · · 10 min read
Connect NMI to AI Agents: Automate Invoicing and Customer Vaults

You want to connect NMI to an AI agent so your internal systems can independently process payments, automate invoicing, manage customer vaults, and handle subscription lifecycles based on historical context. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to manually code dozens of endpoints or maintain complex payment API wrappers.

Giving a Large Language Model (LLM) read and write access to your NMI instance is an engineering headache. You either spend weeks building, hosting, and maintaining a custom connector that understands the intricacies of payment states, or you use a managed infrastructure layer that handles the boilerplate for you. If your team uses ChatGPT, check out our guide on connecting NMI to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting NMI to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.

This guide breaks down exactly how to fetch AI-ready tools for NMI, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or Vercel AI SDK), and execute complex payment operations workflows. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.

The Engineering Reality of Custom NMI Connectors

Building AI agents is easy. Connecting them to external SaaS and payment APIs is hard. Giving an LLM access to external financial data sounds simple in a prototype. You write a Node.js function that makes a fetch request and wrap it in an @tool decorator. In production, this approach collapses entirely, especially with an ecosystem as sensitive and complex as NMI.

If you decide to integrate NMI yourself, you own the entire API lifecycle. NMI's payment gateway introduces several highly specific integration challenges that break standard LLM assumptions.

The Transaction State Machine Trap

NMI does not operate like a standard CRUD database. Transactions have a strict state machine. An agent cannot simply "update" a transaction. To process a deferred payment, the system must first perform an Authorization, and later perform a Capture referencing that specific Authorization ID. If a user wants to cancel a payment, the agent must know the difference between an unsettled transaction (which requires a Void operation) and a settled transaction (which requires a Refund operation).

If you hand-code this integration, you have to write complex prompts to teach the LLM the exact rules of NMI's transaction lifecycle. When the LLM inevitably hallucinates and tries to call a Refund endpoint on an unsettled authorization, the API will throw an error, and the agent loop will likely crash.

Non-Standard HTTP Status Codes

A common pitfall with legacy payment gateways is their reliance on payload-level status codes rather than HTTP-level status codes. NMI will frequently return a perfectly valid HTTP 200 OK response, but the JSON payload will contain response: 2 (Declined) or response: 3 (Error).

Standard AI agent tools often look at the HTTP status code to determine if the tool call was successful. If an agent executes a sale, receives a 200 OK, and doesn't explicitly parse the nested response field, it will hallucinate that the payment was successful when the card was actually declined for insufficient funds. You have to build custom response parsing into every single tool you expose to the LLM.

Complex Nested Data Models for Vaulting

Creating a customer in the NMI Customer Vault is not a flat JSON object. It requires nested billing addresses, which in turn require nested payment_details that contain either raw card details, ACH banking info, or a Collect.js payment_token. LLMs struggle with deeply nested JSON schemas, frequently inventing fields or placing them at the wrong level of the object hierarchy.

Why a Unified Tool Layer Matters for Agent Safety

Before writing a line of integration code, decide what layer your agent talks to. This choice determines how safe your production system will be.

Direct API tools (one tool per raw NMI endpoint) look convenient but they push provider quirks into the LLM's context. The model has to remember that amounts must be decimal strings (e.g., "10.00" not 10), that customer IDs are referred to as customer_vault_id, and that error codes live inside the response body.

A unified tool layer collapses these complexities behind strict, AI-optimized schemas. Your agent sees nmi_payments_sale, nmi_payments_refund, and create_a_nmi_customer. That gives you concrete safety wins:

  1. Smaller attack surface for hallucination. The LLM only ever chooses from a stable list of function names.
  2. Deterministic input validation. Every tool has a strict JSON schema. Invalid arguments (like sending an integer for an amount instead of a decimal string) are rejected by the framework before they hit the payment gateway, so a broken tool call fails fast instead of executing a malformed financial transaction.
  3. Real-time schema updates. As you customize resource methods in the Truto interface, the /tools endpoint dynamically updates the OpenAPI schemas injected into your LLM's prompt.

The Reality of Rate Limits

It is critical to understand how API limits work when dealing with autonomous agents. Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream NMI API returns an HTTP 429 Too Many Requests, Truto passes that exact error back to the caller.

What Truto does do is normalize the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. Your agent framework or application layer is entirely responsible for reading these headers and executing the appropriate retry or exponential backoff logic. Do not build an autonomous agent assuming the integration layer will magically absorb rate limit spikes.

NMI Hero Tools for AI Agents

Instead of dumping the entire NMI API into your agent's context window - which consumes massive amounts of tokens and degrades model reasoning - you should expose only the high-leverage operations. Here are the hero tools you can fetch dynamically via Truto's /tools endpoint.

nmi_payments_sale

This tool processes a complete sale transaction in NMI, executing an authorization and capture in a single step. It accepts raw card details, an ACH bank account, a Collect.js payment token, or a stored customer via customer_vault_id. Amounts must be passed as decimal strings (e.g., "100.00"). It returns the transaction result including the status and response text.

"Process a $150.00 sale for the customer associated with vault ID 'cust_892374'."

nmi_payments_refund

This tool refunds a previously settled NMI payment back to the customer's payment method. It requires the original payment_id. Because this only works on settled transactions, the agent must ensure the transaction has cleared before executing this tool.

"Issue a full refund for the settled transaction ID 'txn_555981'."

nmi_payments_void

If a payment has been authorized or captured but not yet settled in the daily batch, it cannot be refunded - it must be voided. This tool voids an unsettled NMI payment, effectively canceling the transaction before funds actually move.

"The user canceled their order immediately after checkout. Void the transaction ID 'txn_555990'."

create_a_nmi_invoice

This tool generates a new invoice in NMI and immediately emails it to the customer. It handles the billing contact addressing and itemizes the request body directly into the NMI invoice system.

"Generate an invoice for 5 hours of consulting at $200 per hour and email it to billing@acmecorp.com."

create_a_nmi_customer

This tool stores a customer in the NMI Customer Vault for future billing. It creates the record with billing addresses and securely stores the payment method, returning a customer_vault_id that can be used for subsequent sales or subscription creation without handling raw PCI data.

"Save this new client into the customer vault using the Collect.js token 'tok_abc123' so we can bill them later."

create_a_nmi_subscription

This tool creates a recurring billing subscription in NMI. It can attach the subscription to an existing plan ID or define a custom schedule inline. It requires a payment details variant (usually a vault ID).

"Start a new monthly subscription for vault ID 'cust_892374' on the 'Enterprise SaaS Plan' starting today."

To view the complete inventory of available NMI tools and their precise JSON schemas, visit the NMI integration page.

Workflows in Action

Giving an AI agent access to these tools unlocks highly complex, multi-step revenue operations workflows that would normally require human intervention or brittle Zapier chains.

Scenario 1: Autonomous Subscription Downgrades and Proration

A customer emails support asking to downgrade their software plan and requesting a refund for the unused portion of the current month. The AI agent handles the entire financial operation autonomously.

"Customer at billing@acmecorp.com requested a downgrade from the Pro plan to the Basic plan. Cancel their current subscription, calculate the prorated difference of $45.00, and issue a refund to their original payment method."

Step-by-step execution:

  1. The agent calls list_all_nmi_customers filtering by the provided email to retrieve the customer_vault_id.
  2. The agent calls list_all_nmi_subscriptions to locate the active "Pro plan" subscription attached to that vault ID.
  3. The agent calls delete_a_nmi_subscription_by_id to halt future billing on the expensive plan.
  4. The agent calls create_a_nmi_subscription to start the new "Basic plan" using the stored vault ID.
  5. The agent calls nmi_payments_refund passing the original payment_id of the last charge and specifying the prorated amount of "45.00".

Result: The customer is immediately downgraded, the new billing cycle is established, and the partial refund is pushed to their card - all within seconds of the support ticket being opened.

Scenario 2: Invoice Generation from Project Management

A project manager updates a task to "Completed" in Jira. An AI agent monitoring the project board executes the billing workflow.

"The database migration project for client XYZ is marked complete. Find their billing details in the vault, generate an invoice for $5,000.00, and send it to them."

Step-by-step execution:

  1. The agent calls list_all_nmi_customers to search for "Client XYZ" and retrieves their customer record.
  2. The agent calls create_a_nmi_invoice with the line item for "Database Migration", passing the amount "5000.00" and assigning the invoice to the retrieved customer.
  3. The agent calls nmi_invoices_send to trigger the NMI system to email the newly generated invoice directly to the client's billing contact.

Result: The invoice is generated and dispatched entirely based on the state change of a project management ticket, bridging operational work and financial billing.

Building Multi-Step Workflows

To make this work in a real application, you need to bind these tools to your LLM framework. The following architecture works across any agent framework, including LangChain, LangGraph, CrewAI, and the Vercel AI SDK.

We utilize the truto-langchainjs-toolset to dynamically fetch the tool definitions from Truto's /tools endpoint and bind them to the model.

import { ChatOpenAI } from "@langchain/openai";
import { TrutoToolManager } from "truto-langchainjs-toolset";
import { HumanMessage } from "@langchain/core/messages";
 
async function runNMIAgent() {
  // 1. Initialize the LLM
  const llm = new ChatOpenAI({
    modelName: "gpt-4o",
    temperature: 0,
  });
 
  // 2. Initialize the Truto Tool Manager
  // This automatically fetches your customized NMI tools from Truto
  const toolManager = new TrutoToolManager({
    apiKey: process.env.TRUTO_API_KEY,
    integratedAccountId: process.env.NMI_INTEGRATED_ACCOUNT_ID,
  });
 
  // 3. Fetch the tools and bind them to the LLM
  const tools = await toolManager.getTools();
  const llmWithTools = llm.bindTools(tools);
 
  // 4. Define the prompt
  const messages = [
    new HumanMessage(
      "Find the customer vault record for 'TechCorp' and issue a $50.00 sale against their stored payment method."
    )
  ];
 
  console.log("Agent thinking...");
  
  // 5. Execute the agent loop
  try {
    const response = await llmWithTools.invoke(messages);
    
    // Check if the LLM decided to call a tool
    if (response.tool_calls && response.tool_calls.length > 0) {
        console.log("Executing tool calls:", response.tool_calls);
        // The framework handles the execution of the tool call against the Truto Proxy API
        // In a full LangGraph setup, this would route to a ToolNode.
    }
  } catch (error) {
    // 6. Handle Rate Limits and Errors
    if (error.response && error.response.status === 429) {
        const limit = error.response.headers['ratelimit-limit'];
        const remaining = error.response.headers['ratelimit-remaining'];
        const resetTime = error.response.headers['ratelimit-reset'];
        
        console.error(`Rate limit hit! Limit: ${limit}. Remaining: ${remaining}. Reset at: ${resetTime}`);
        // Implement your exponential backoff logic here based on the ratelimit-reset header.
    } else {
        console.error("API execution failed:", error);
    }
  }
}
 
runNMIAgent();

Visualizing the Agent Architecture

When you use this architecture, the integration layer is fully decoupled from your business logic. The agent reasons about the user's intent, selects the right standard JSON schema, and Truto handles the translation to NMI's specific API format.

sequenceDiagram
    participant User as User Application
    participant Agent as AI Agent (LangChain)
    participant Truto as Truto Tools API
    participant NMI as NMI Gateway API

    User ->> Agent: "Process $50 sale for vault ID cust_123"
    Agent ->> Truto: GET /integrated-account/<id>/tools
    Truto -->> Agent: Returns NMI tool schemas
    Agent ->> Agent: LLM evaluates intent and schemas
    Agent ->> Truto: Call nmi_payments_sale(amount: "50.00")
    Truto ->> NMI: POST transaction request
    NMI -->> Truto: Returns Gateway Response (HTTP 200)
    Truto -->> Agent: Normalizes response text
    Agent -->> User: "Sale processed successfully. Auth code: 99823"

Handling Errors and Rate Limits

Notice the error handling block in the code example. Because Truto acts as a transparent proxy for NMI's underlying constraints, you must build your agent to handle failure states gracefully.

If NMI experiences heavy load and issues a 429 status code, Truto will not absorb it. Your agent loop will catch the error, read the ratelimit-reset header, and ideally pause execution until the window clears before retrying the tool call. This is critical for building resilient AI workflows - agents that blindly retry without respecting headers will quickly get your integrated account IP banned by the gateway.

By leveraging an auto-updating tool layer, you isolate your AI logic from gateway API updates. When NMI adds a new field to their transaction model, you update the schema mapping in the Truto UI once, and every agent instance immediately receives the updated tool definition on its next execution loop.

FAQ

How do AI agents handle NMI's complex transaction states?
Instead of exposing raw endpoints to the LLM, Truto maps NMI operations into distinct, AI-optimized tools (like nmi_payments_sale and nmi_payments_refund). This prevents the agent from confusing unsettled authorizations with settled captures.
Does Truto automatically handle NMI rate limits?
No. Truto passes upstream HTTP 429 errors directly to the caller and normalizes the rate limit data into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). Your agent framework is responsible for implementing retry and backoff logic.
Can I use these NMI tools with frameworks other than LangChain?
Yes. The Truto /tools endpoint returns standard JSON schemas that can be bound to any modern AI framework, including LangGraph, CrewAI, and the Vercel AI SDK.
How do I safely handle raw credit card data when creating NMI customers?
You should use the create_a_nmi_customer tool in conjunction with Collect.js payment tokens (payment_token) or existing vault IDs to create records without exposing raw PCI data to the LLM context window.

More from our Blog