VietQR Payment Automation for AI Agents: Stripe Alternative
The Real Problem: Your AI Agent Needs to Collect Money Right Now
Imagine you've built an AI chatbot that sells online courses in Vietnam. A customer completes their purchase, clicks "Pay Now," and... your bot freezes. Why? Because most payment solutions either don't support Vietnam, require weeks of paperwork, or take a 3-5% cut before your money lands in your bank account.
Standard options like Stripe have limited VietQR support. PayPal doesn't work well for Vietnamese businesses. Local solutions often lack automation APIs suitable for AI agents. Your bot sits helpless, unable to close the sale.
AgentPay VN solves this gap.
It's an open-source Python SDK and MCP server that lets your AI agents collect VietQR payments—those ubiquitous QR codes Vietnamese customers scan with their phones—and route the money directly to your merchant bank account. No middleman holding funds. No complex onboarding. Just: create a payment request, send the checkout URL, wait for settlement confirmation.
In this tutorial, you'll learn how to integrate AgentPay VN into production AI systems, with real code and a complete walkthrough.
Why VietQR + Agents Is a Game-Changer
VietQR is Vietnam's interbank QR standard. Over 95% of Vietnamese bank apps support it. When a customer scans a VietQR code, funds go directly to the merchant's account—no payment processor middle layer needed.
Three concrete advantages:
- Instant settlement: Bank confirms deposit within minutes; no 2-3 day holds.
- Lower friction: Customers already know how to scan QR codes; no new apps or logins.
- API-driven: Unlike manual payment verification, AgentPay VN lets agents programmatically create requests, monitor status, and trigger follow-up actions (e.g., invoice generation, course access grant).
For an AI agent, this means: - You can close a sales loop entirely in code—no manual intervention. - You scale without hiring payment ops staff. - Your margin stays intact (no 2-3% Stripe fee).
How AgentPay VN Works: The Three-Line Flow
Before diving into code, understand the workflow:
Step 1: Create a payment request Your agent defines an amount, order ID, and optional description.
Step 2: Send checkout URL to customer AgentPay generates a shareable URL. Your agent sends it via chat, email, or SMS.
Step 3: Await settlement Your agent polls or listens for confirmation from the bank feed. Once confirmed, it proceeds (sends invoice, activates account, etc.).
The money never touches AgentPay servers. It goes straight from customer's bank → merchant's bank. AgentPay is just the orchestrator.
Installation & Setup in 5 Minutes
Install the SDK
pip install agentpay-vn
Configure Your Merchant Bank Account
You'll need:
- Bank Account Number (your receiving account)
- Bank Code (e.g., MB for MBBank, ACB for ACB, VCB for Vietcombank)
- Merchant ID (provided by your bank or AgentPay partner)
Store these in environment variables:
export AGENTPAY_MERCHANT_ID="your_merchant_id"
export AGENTPAY_BANK_CODE="MB"
export AGENTPAY_ACCOUNT_NUMBER="1234567890"
export AGENTPAY_API_KEY="your_api_key"
Quick Validation
Test your setup:
from agentpay_vn import AgentPayClient
client = AgentPayClient()
status = client.health_check()
print(f"Service online: {status['ok']}")
If you see Service online: True, you're ready to code.
Building Your First Payment-Enabled Agent
Code Example 1: Create & Monitor a Payment Request
import time
from agentpay_vn import AgentPayClient
# Initialize the SDK
client = AgentPayClient()
# Step 1: Create a payment request
# This tells AgentPay: "I want to collect 299,000 VND for order #12345"
payment_request = client.create_payment_request(
amount=299000, # in VND
order_id="ORDER-12345",
description="Online Python Course - 1 Year Access",
return_url="https://yourapp.com/course/enroll?order_id=12345"
)
checkout_url = payment_request['checkout_url']
request_id = payment_request['request_id']
print(f"Customer pays here: {checkout_url}")
print(f"Request ID (for tracking): {request_id}")
# Step 2: Send this URL to the customer (via agent message, email, etc.)
# In a real agent, this might be:
# agent.send_message(f"Please pay here: {checkout_url}")
# Step 3: Await settlement (poll every 5 seconds, timeout after 5 minutes)
start_time = time.time()
timeout = 300 # 5 minutes
while time.time() - start_time < timeout:
settlement = client.await_settlement(
request_id=request_id,
timeout=10 # poll interval in seconds
)
if settlement['status'] == 'settled':
print(f"✅ Payment received! {settlement['amount']} VND")
print(f" Settlement ID: {settlement['settlement_id']}")
print(f" Timestamp: {settlement['timestamp']}")
break
elif settlement['status'] == 'failed':
print(f"❌ Payment failed: {settlement['reason']}")
break
else:
print(f"⏳ Waiting... Status: {settlement['status']}")
time.sleep(5)
else:
print("⏱️ Payment timeout. Customer may retry.")
Line-by-line explanation:
- Lines 1-5: Import SDK and initialize client with credentials from env vars.
- Lines 8-14:
create_payment_request()generates a unique checkout URL. Amount is in VND.order_idlinks this payment to your database record. - Lines 16-17: Extract URL and request ID; the URL is what you show the customer.
- Lines 23-32:
await_settlement()polls the bank feed. Blocks until payment settles, fails, or times out.timeout=10means check every 10 seconds. - Lines 34-37: Once settled, you can trigger downstream logic (grant course access, send confirmation email, etc.).
Code Example 2: Batch Payment Requests in an Agent Loop
from agentpay_vn import AgentPayClient
import asyncio
client = AgentPayClient()
# Simulated list of pending orders from your agent's queue
pending_orders = [
{"order_id": "ORD-001", "amount": 149000, "customer_email": "alice@example.com"},
{"order_id": "ORD-002", "amount": 299000, "customer_email": "bob@example.com"},
{"order_id": "ORD-003", "amount": 99000, "customer_email": "carol@example.com"},
]
results = []
for order in pending_orders:
# Create payment request
payment = client.create_payment_request(
amount=order["amount"],
order_id=order["order_id"],
description=f"Order {order['order_id']}"
)
checkout_url = payment["checkout_url"]
request_id = payment["request_id"]
# In a real agent, send this URL to the customer
# email_service.send(to=order["customer_email"], body=f"Pay here: {checkout_url}")
results.append({
"order_id": order["order_id"],
"checkout_url": checkout_url,
"request_id": request_id,
"created_at": payment["created_at"]
})
print(f"✅ Created payment for {order['order_id']}")
print(f"\nGenerated {len(results)} payment URLs. Agent will monitor these for settlement.")
This pattern is useful for bulk order processing or multi-user agents.
MCP Server Integration: Using AgentPay with Claude
If you're building an AI agent with Claude (via the Model Context Protocol), you can run AgentPay as an MCP server so Claude can invoke payment functions directly.
Installation
pip install agentpay-mcp
MCP Server Configuration (Claude)
Add this to your Claude config file (e.g., ~/.claude/config.json or Claude's settings):
{
"mcpServers": {
"agentpay": {
"command": "python",
"args": ["-m", "agentpay_mcp.server"],
"env": {
"AGENTPAY_MERCHANT_ID": "your_merchant_id",
"AGENTPAY_BANK_CODE": "MB",
"AGENTPAY_ACCOUNT_NUMBER": "1234567890",
"AGENTPAY_API_KEY": "your_api_key"
}
}
}
}
Now Claude can call:
[Claude]: The user wants to buy a course. Let me create a payment request.
→ Tool call: agentpay.create_payment_request(amount=299000, order_id="12345")
← Result: {checkout_url: "https://...", request_id: "req_abc123"}
[Claude]: Here's your payment link: https://...
Real-World Walkthrough: AI-Powered Online Course Bot
Let's build a concrete example: an AI chatbot that sells a Python course.
Scenario: Customer: "I want to buy the Advanced Python course." Bot: "Great! That's 299,000 VND. Here's your payment link: [QR URL]" Customer: Scans QR, pays via their bank app. Bot: "Payment confirmed! Course access granted. Check your email for credentials."
Implementation:
from agentpay_vn import AgentPayClient
import json
client = AgentPayClient()
class CourseBot:
def __init__(self):
self.courses = {
"python-101": {"name": "Python Basics", "price": 99000},
"python-advanced": {"name": "Advanced Python", "price": 299000},
"python-ml": {"name": "Python + ML", "price": 499000},
}
def handle_purchase(self, user_id, course_id):
"""Handle a course purchase request."""
if course_id not in self.courses:
return {"status": "error", "message": "Course not found."}
course = self.courses[course_id]
# Create a payment request
payment = client.create_payment_request(
amount=course["price"],
order_id=f"USER-{user_id}-{course_id}",
description=f"Course: {course['name']}"
)
checkout_url = payment["checkout_url"]
request_id = payment["request_id"]
return {
"status": "pending_payment",
"checkout_url": checkout_url,
"request_id": request_id,
"message": f"Please pay {course['price']:,} VND to access {course['name']}. Click here: {checkout_url}"
}
def confirm_payment(self, request_id):
"""Check if payment has settled."""
settlement = client.await_settlement(request_id, timeout=5)
if settlement['status'] == 'settled':
return {
"status": "paid",
"message": f"✅ Payment of {settlement['amount']:,} VND confirmed. Course access granted. Check your email.",
"settlement_id": settlement["settlement_id"]
}
elif settlement['status'] == 'pending':
return {"status": "pending", "message": "⏳ Payment processing..."}
else:
return {"status": "failed", "message": "❌ Payment failed or timed out."}
# Usage
bot = CourseBot()
# User buys Advanced Python course
result = bot.handle_purchase(user_id="user_12345", course_id="python-advanced")
print(json.dumps(result, indent=2, ensure_ascii=False))
# Later, check payment status
if result["status"] == "pending_payment":
confirmation = bot.confirm_payment(result["request_id"])
print(json.dumps(confirmation, indent=2, ensure_ascii=False))
Output:
{
"status": "pending_payment",
"checkout_url": "https://agentpay.servicesai.vn/checkout/req_xyz789",
"request_id": "req_xyz789",
"message": "Please pay 299,000 VND to access Advanced Python. Click here: https://..."
}
Once the customer pays and the bot confirms, it unlocks course access and sends a confirmation email.
Do's and Don'ts: Best Practices
| ✅ DO | ❌ DON'T |
|---|---|
Store request_id in your database to link payments to orders |
Assume payment settled without checking await_settlement() |
Use unique, descriptive order_id values (e.g., USER-123-ORDER-456) |
Hardcode bank credentials; always use env vars |
| Set a reasonable timeout (300-600s for most use cases) | Retry failed payments immediately; let user retry manually |
| Log settlement IDs for reconciliation | Expose your AGENTPAY_API_KEY in client-side code |
| Test with small amounts first (e.g., 1,000 VND) | Build settlement logic without error handling |
| Monitor payment request status periodically | Create multiple requests for the same order |
Advanced Tips
1. Idempotent Payment Creation
If your agent retries, always pass the same order_id:
payment = client.create_payment_request(
amount=299000,
order_id="ORDER-12345", # Same ID = AgentPay returns existing request, no duplicate
description="Course Purchase"
)
2. Webhook Monitoring (Instead of Polling)
For production, AgentPay supports webhooks. Instead of await_settlement(), set up a webhook endpoint:
# Register your webhook
client.register_webhook(
url="https://yourapp.com/webhooks/agentpay",
events=["payment.settled", "payment.failed"]
)
# Your endpoint receives POST requests like:
# {"event": "payment.settled", "request_id": "req_abc", "amount": 299000, ...}
3. Multi-Agent Payment Coordination
If you have multiple agents handling payments (e.g., sales bot + support bot), use a shared database:
# Agent A creates payment
payment = client.create_payment_request(amount=299000, order_id="12345")
db.payments.insert({"request_id": payment["request_id"], "agent": "sales_bot"})
# Agent B monitors it
db_record = db.payments.find_one({"request_id": "req_xyz"})
settlement = client.await_settlement(request_id=db_record["request_id"])
Comparison: AgentPay VN vs. Alternatives
AgentPay VN: - ✅ VietQR native; instant settlement. - ✅ Open-source (MIT); audit-friendly. - ✅ Zero fees (just bank-to-bank transfer). - ✅ AI agent–optimized API. - ⚠️ Vietnam-only.
Stripe: - ✅ Global; well-documented. - ❌ 2-3% fee + settlement delay. - ❌ Limited VietQR; requires workarounds. - ❌ Overkill for simple Vietnamese payments.
PayPal: - ✅ International coverage. - ❌ Limited Vietnam support; high fees. - ❌ Not designed for high-volume micropayments.
Local Vietnamese Solutions (e.g., Momo, ZaloPay): - ✅ Popular locally. - ❌ Often require manual verification. - ❌ Fragmented APIs; agent integration difficult. - ❌ Fees vary; less transparent.
AgentPay VN is ideal if: You're building Vietnamese AI agents that collect payments without ongoing ops overhead.
FAQ
Q: Where does the money go? Does AgentPay hold it?
A: No. The QR code encodes your bank account details directly. When a customer scans and pays, the money goes straight from their bank to your merchant account. AgentPay just orchestrates the request and monitors the bank feed. We never touch the funds.
Q: How long does settlement take?
A: Most VietQR transfers settle within 5-30 minutes. The await_settlement() function polls the bank feed and confirms as soon as the deposit clears. In practice, you'll see confirmation within 1-2 minutes for same-bank transfers, 30 minutes max for cross-bank.
Q: What if a customer pays the wrong amount or cancels?
A: Each payment request has a unique QR code tied to an exact amount. If the customer pays less, the request remains unsettled and you can retry. If they overpay, the excess lands in your account (you'd need to handle refunds manually or ask the customer to correct). The system doesn't auto-refund.
Q: Can I use AgentPay with my existing Python agent frameworks (LangChain, AutoGen, CrewAI)?
A: Yes. AgentPay VN is framework-agnostic. You call the SDK methods just like any other tool. If you're using MCP servers, agencies like Claude will auto-integrate. For other frameworks, wrap AgentPay in a custom tool function.
Q: Is AgentPay PCI-compliant or certified?
A: AgentPay handles no sensitive card data—VietQR is bank-to-bank via QR code. Your bank's payment gateway handles compliance. AgentPay itself is open-source and auditable; the MIT license allows security reviews.
Key Takeaways
-
AgentPay VN is a lightweight, open-source SDK that automates VietQR payments for AI agents in Vietnam. It's not a payment processor; it's an orchestrator that routes money directly to your bank account.
-
Three-step flow: create payment request → send checkout URL → await settlement. Perfect for AI agents that need to close sales loops programmatically.
-
Zero fees, instant settlement, no middleman. Your agent keeps 100% of revenue and gets confirmation within minutes.
-
MCP integration with Claude and other AI frameworks is built-in. Your agent can invoke payment functions as naturally as any other tool.
-
Best use cases: online course sales, digital goods, SaaS subscriptions, service bookings—anything where an AI agent needs to collect payment from Vietnamese customers.
-
Start with
pip install agentpay-vnand a small test amount. The entire integration takes ~1 hour for most projects.
Next Steps
Ready to integrate VietQR payments into your AI agent?
- Install the SDK:
pip install agentpay-vn - Read the full documentation: https://agentpay.servicesai.vn/v1/docs
- Explore the source code: https://github.com/phuocdu/agentpay-vn
- Join the community: Star the repo and submit issues or PRs.
Your AI agents deserve a payment solution as smart as they are. AgentPay VN is that solution.