VietQR Payment Automation for AI Agents
The Problem: Your AI Agent Needs Payment Rails in Vietnam
Imagine you've built a chatbot that teaches English to Vietnamese students. It's brilliant—personalized lessons, real-time feedback, fluent conversation practice. But now you need to collect payment. You check Stripe: international merchant account setup takes weeks, fees eat 3.9% + $0.30 per transaction, and half your customers abandon checkout because they don't have a card.
You look at local VietQR solutions. They're scattered across 30+ bank apps. You'd need to manually track QR codes, confirm payments in a bank portal, and somehow wire that into your bot logic. The friction is real.
This is where AgentPay VN changes the game. It's an open-source Python SDK + MCP server that lets your AI agents automatically request, track, and confirm VietQR payments—all flowing directly to your merchant bank account, with zero fund-holding middleman overhead.
What Is AgentPay VN?
AgentPay VN is a lightweight, MIT-licensed toolkit built for developers who want to embed payment collection into AI agents without platform complexity. Here's what it does:
- Creates VietQR payment requests with customizable amounts and descriptions
- Generates checkout URLs that customers scan and pay through their own bank apps
- Monitors bank feeds to confirm settlement in real-time
- Runs as an MCP server, making it accessible to Claude and other LLM agents
- Never touches merchant funds—money goes straight to your bank account
Think of it as a payment bridge: your agent asks for money, AgentPay generates the QR and listens for confirmation, then your agent continues the conversation. No API keys to rotate, no dashboard logins, no settlement delays.
Why VietQR for AI Agents?
VietQR is Vietnam's national instant payment standard. Over 95% of Vietnamese bank accounts support it. For your AI agent, this means:
Instant verification: Bank feeds confirm payments within seconds, not days. Your agent can immediately unlock premium features, deliver digital goods, or upgrade a subscription.
User familiarity: Customers pay through their own bank app—the interface they trust daily. No new accounts, no card data, no friction.
Lower costs: Typically 0.5–1% per transaction (vs. 3.9% on Stripe), putting more revenue in your pocket.
Direct settlement: Your bank account, your control. No third party holding reserves or freezing funds.
For AI workflows, this is crucial. Your agent needs to make fast decisions about user access—"Did they pay? Unlock the feature." VietQR's real-time confirmation lets that happen instantly.
Installation and Setup (30 seconds)
Get the SDK running in your project:
pip install agentpay-vn
That's it. No config files, no secrets to manage (initially). You're ready to start building.
Optional: Run the MCP Server
If you want Claude or another LLM to call payment functions directly:
agentpay-mcp
This starts a local MCP server. Connect it in your Claude config (more on that below).
The Three-Line Payment Flow
AgentPay VN distills payment collection into three steps:
- Create a payment request
- Send the checkout URL to the customer
- Await settlement confirmation
Let's walk through each with real code.
Step 1: Create a Payment Request
from agentpay_vn import PaymentClient
# Initialize the client (reads bank config from environment)
client = PaymentClient()
# Create a payment request for a course purchase
payment = client.create_payment_request(
amount=250000, # 250,000 VND
description="English Conversation Course - Advanced Level",
customer_id="user_42", # Tie payment to this customer
metadata={"course_id": "advanced_english_2024"}
)
print(f"Payment request created: {payment.request_id}")
print(f"Checkout URL: {payment.checkout_url}")
Line-by-line explanation:
- PaymentClient() initializes with your merchant bank details (sourced from env variables like AGENTPAY_BANK_ACCOUNT)
- create_payment_request() generates a unique payment request on VietQR rails
- amount is in VND (Vietnamese Dong). 250,000 VND ≈ $10 USD.
- description appears in the customer's bank app—be clear ("Course purchase" not "Payment")
- customer_id and metadata let you track the request later and connect it to your system
- The function returns a Payment object with a checkout_url—this is what you send to the customer
Step 2: Send the Checkout URL
In your AI agent conversation:
# Inside your chatbot's payment handler
def handle_course_purchase(user_id, course_name, price_vnd):
payment = client.create_payment_request(
amount=price_vnd,
description=f"Purchase: {course_name}",
customer_id=user_id
)
# Format a message for the user
message = f"""
Great! To unlock '{course_name}', please scan this QR code:
{payment.checkout_url}
Pay {price_vnd:,} VND through your bank app and I'll grant you access immediately.
"""
return message, payment.request_id
Your agent returns the checkout URL (either as text + QR image, or direct link). The customer scans, pays in their bank app, done.
Step 3: Await Settlement
import asyncio
import time
async def wait_for_payment(request_id, timeout_seconds=600):
"""
Poll the bank feed for settlement confirmation.
Returns True when money lands in your account.
"""
start = time.time()
while time.time() - start < timeout_seconds:
status = client.get_payment_status(request_id)
if status.state == "settled":
print(f"✓ Payment {request_id} confirmed! Amount: {status.amount} VND")
return True
if status.state == "failed":
print(f"✗ Payment {request_id} failed or expired.")
return False
# Not settled yet—check again in 2 seconds
await asyncio.sleep(2)
print(f"⏱ Payment {request_id} timed out (no settlement in {timeout_seconds}s).")
return False
# In your agent flow:
payment_request_id = ... # from Step 1
if await wait_for_payment(payment_request_id):
# Money arrived! Unlock the course.
user.grant_access("advanced_english_2024")
agent.say("Payment confirmed! Your course is ready. Let's begin lesson 1.")
else:
agent.say("Payment not received. Please try again or contact support.")
Key points:
- get_payment_status() queries your bank feed for confirmation
- Settlement typically happens in 5–30 seconds (faster than any payment gateway)
- The polling loop exits on settled (success), failed (declined), or timeout
- Once confirmed, your agent logic can proceed—unlock premium features, deliver digital goods, update subscriptions, etc.
Real-World Walkthrough: AI Tutoring Bot
Let's build a complete micro-flow: a Vietnamese student chats with a tutoring bot, decides to buy a lesson pack, and AgentPay confirms the payment mid-conversation.
from agentpay_vn import PaymentClient
from datetime import datetime
class TutoringAgent:
def __init__(self):
self.payment_client = PaymentClient()
self.user_courses = {} # Track user access
def process_user_message(self, user_id, message):
"""Simulated agent response (simplified)."""
if "buy lesson pack" in message.lower():
return self.initiate_purchase(user_id)
return "How can I help you today?"
def initiate_purchase(self, user_id):
# Step 1: Create payment request
payment = self.payment_client.create_payment_request(
amount=500000, # 500,000 VND for 10 lessons
description="Tutoring: 10-Lesson Advanced Package",
customer_id=user_id,
metadata={
"lesson_count": 10,
"level": "advanced",
"created_at": datetime.now().isoformat()
}
)
# Step 2: Send checkout link
checkout_msg = f"""
Perfect! Your 10-lesson Advanced Package costs 500,000 VND.
Scan this to pay:
{payment.checkout_url}
Or use this QR code: [IMAGE]
I'll unlock your lessons as soon as payment confirms (usually within 30 seconds).
"""
# Step 3: Wait for settlement (non-blocking in production, use a queue)
# For demo, we'll do it synchronously:
import time
for attempt in range(60): # Try for 2 minutes
status = self.payment_client.get_payment_status(payment.request_id)
if status.state == "settled":
self.user_courses[user_id] = {
"lessons_remaining": 10,
"level": "advanced",
"purchased_at": datetime.now()
}
return f"""
{checkout_msg}
✓ **Payment confirmed!**
Your 10 lessons are now unlocked. Let's start Lesson 1.
Today's topic: Vietnamese subjunctive mood. Ready?
"""
time.sleep(2) # Check every 2 seconds
return f"{checkout_msg}\n\n⏱ Waiting for payment... (will update you when confirmed)"
# Usage
agent = TutoringAgent()
response = agent.process_user_message("student_001", "I want to buy the lesson pack")
print(response)
In production, you'd use a task queue (Celery, etc.) instead of blocking waits, but the logic is identical: request → checkout → confirm → grant access.
Using AgentPay VN with Claude via MCP
Want Claude itself to manage payments? Use the MCP server.
1. Start the MCP Server
agentpay-mcp
By default, it listens on localhost:3000 and exposes payment functions.
2. Configure Claude to Use It
Add to your Claude client config (e.g., ~/.codebase/claude-config.json):
{
"mcpServers": {
"agentpay": {
"command": "python",
"args": ["-m", "agentpay_vn.mcp_server"],
"env": {
"AGENTPAY_BANK_ACCOUNT": "1234567890",
"AGENTPAY_BANK_CODE": "970425",
"AGENTPAY_MERCHANT_NAME": "My Course Shop"
}
}
}
}
3. Call Payment Functions from Claude
Now Claude can call create_payment_request, get_payment_status, etc. directly:
User: "I want to buy your premium course."
Claude: I'll set up a payment for you. [calls agentpay MCP]
The course costs 1,000,000 VND. Please scan this QR code:
vietqr://...
[awaits settlement via MCP poll]
Great! Payment confirmed. Your access is now active.
This eliminates the need for you to write agent-payment glue code. Claude handles it natively.
Comparison: AgentPay VN vs. Stripe (for Vietnam)
| Aspect | AgentPay VN | Stripe in Vietnam |
|---|---|---|
| Transaction Fee | 0.5–1% | 3.9% + $0.30 |
| Settlement Time | 5–30 sec (real-time) | 1–3 days |
| Customer Friction | Scan QR, pay in bank app | New account / card entry |
| Fund Holding | Never—direct to merchant bank | 7-day reserve typical |
| Local Support | Native VietQR (95%+ adoption) | International only |
| Setup Complexity | pip install + env vars |
Weeks of documentation |
| AI Agent Integration | MCP server included | Custom API wrapping |
| Open Source | MIT license ✓ | Proprietary ✗ |
Best for AgentPay VN: Vietnamese merchants, AI agents, real-time payment confirmation, cost-sensitive SaaS.
Best for Stripe: International customers, complex billing, legacy infrastructure ties.
Do's and Don'ts
✅ Do
- Use meaningful payment descriptions (customers see them in their bank app)
- Store
request_idin your database to track payments across restarts - Set appropriate timeouts (don't wait forever for settlement)
- Log payment status changes for debugging
- Use metadata to link payments to your internal entities (user, product, order)
❌ Don't
- Hardcode bank credentials; always use environment variables
- Trust payment confirmation without querying
get_payment_status()multiple times - Block user operations during payment polling (use async/queues instead)
- Assume QR codes are scan-once; customers may mis-scan, and you need idempotency
- Forget to handle timeouts gracefully (don't crash, just ask user to retry)
Frequently Asked Questions
Q: Does AgentPay VN hold my money? No. The QR code points directly at your merchant bank account. Money lands in your bank—you retain full control. AgentPay only reads your bank feed to confirm settlement.
Q: How do I get a merchant bank account for VietQR? Most Vietnamese banks support VietQR. Check with your primary bank (VPBank, Vietcombank, Techcombank, etc.). Typically requires business registration and minimal paperwork (faster than Stripe).
Q: Can I use AgentPay VN outside Vietnam? Not currently. VietQR is Vietnam-specific. However, the SDK is open-source—you can fork and adapt for other QR payment standards (Thailand PromptPay, Singapore SGQR, etc.).
Q: What if a customer scans the QR multiple times?
Each QR code is tied to a unique request_id. Scanning twice generates two separate payment requests. You should invalidate old requests after the first payment settles to avoid double-charging.
Key Takeaways
- AgentPay VN eliminates payment friction for Vietnamese AI agents. Three lines: create → send → confirm.
- Real-time settlement (5–30 seconds) means your agent can respond instantly to payments.
- Direct bank account settlement keeps fees and control in your hands (0.5–1% vs. Stripe's 3.9%).
- Open-source + MCP server make it ideal for AI agents; Claude can call payment functions natively.
- Installation is trivial (
pip install agentpay-vn), and setup requires only bank credentials as env vars. - Works for any payment scenario: SaaS subscriptions, course sales, digital goods, tipping bots, marketplace payouts.
Get Started Now
Ready to add VietQR payments to your AI agent?
-
Install the SDK:
bash pip install agentpay-vn -
Read the full docs at https://agentpay.servicesai.vn/v1/docs
-
Explore the code on GitHub: https://github.com/phuocdu/agentpay-vn
-
Start your first payment request in under 5 minutes using the code examples above.
Your Vietnamese customers are ready to pay via VietQR. Now your AI agent is, too.