VietQR Payment Automation for AI Agents: Stripe Alternative
The Problem: Why Vietnam's Payment Landscape Needs AI-Native Solutions
You've built an AI agent that helps Vietnamese small businesses collect payments—maybe a chatbot selling online courses, or an autonomous system managing café orders. But you hit a wall: Stripe doesn't support VietQR, international payment gateways charge 3–5% fees, and manual bank transfer confirmations eat up 30 minutes per transaction.
This is the reality for thousands of Vietnamese developers. While global SaaS reaches for Stripe, Vietnam's 20+ million VietQR users have no native, AI-friendly payment layer. AgentPay VN changes that.
What Is AgentPay VN?
AgentPay VN is an open-source (MIT) Python SDK + MCP server that lets AI agents collect payments directly via VietQR—Vietnam's national interbank QR standard. Here's what makes it different:
- Zero Intermediary Risk: The QR code points directly at the merchant's bank account. AgentPay never holds money.
- Instant Settlement Confirmation: Bank feeds auto-confirm when funds land in the merchant's account (typically within seconds to 1 minute).
- AI-Native Design: Built for LLM agents and autonomous systems. The 3-line payment flow integrates seamlessly with Claude, ChatGPT, or custom agent frameworks.
- MIT Licensed: Full transparency, no vendor lock-in.
How It Works: The 3-Step Payment Flow
AgentPay VN abstracts the complexity of VietQR into three core operations:
1. create_payment_request
Your agent defines payment details (amount, description, merchant bank info). AgentPay generates a unique VietQR code and checkout URL.
2. send_checkout_url
The agent shares the URL or QR code with the customer (via SMS, email, Telegram bot, etc.).
3. await_settlement
Your agent polls the bank feed or listens for a webhook. When the customer's bank confirms the transfer, AgentPay triggers your success callback.
No dashboard clicking. No manual reconciliation. Pure automation.
Getting Started: Installation & First Payment
Install the SDK
pip install agentpay-vn
For MCP server support (if using Claude or compatible agents):
pip install agentpay-mcp
Your First Payment Request
Let's walk through a concrete example: a small online shop owner wants to collect payment for a ₫500,000 VietQR transfer.
from agentpay_vn import AgentPayClient, PaymentRequest
import asyncio
# Initialize the client with your merchant bank credentials
client = AgentPayClient(
bank_code="970", # Vietcombank code
account_number="1234567890",
account_holder="Nguyen Van A",
api_key="your_api_key_here" # Get from https://agentpay.servicesai.vn/v1/docs
)
# Step 1: Create a payment request
payment_req = PaymentRequest(
amount=500000, # VND
description="Purchase Order #12345 - Online Course",
merchant_name="Tech Academy VN",
order_id="order_20250115_001"
)
# This returns a response with the VietQR code and checkout URL
payment_response = await client.create_payment_request(payment_req)
print(f"VietQR Code: {payment_response.qr_code_url}")
print(f"Checkout URL: {payment_response.checkout_url}")
# Output example:
# VietQR Code: https://qr.vietqr.io/...
# Checkout URL: https://agentpay.servicesai.vn/checkout/pay_xyz123
Line-by-line breakdown:
- Lines 1–2: Import the SDK and asyncio for async operations.
- Lines 5–10: Initialize the client with your merchant bank details. Bank code 970 is Vietcombank; check docs for other banks (ACB=970, Techcombank=970, etc.).
- Lines 12–18: Define the payment request with amount in VND, a human-readable description, and a unique order ID (your agent will track this).
- Line 20: Call create_payment_request() to generate the QR and checkout URL.
- Lines 22–24: Print URLs ready to send to your customer.
Step 2: Send the Checkout URL to Your Customer
# Your agent framework (e.g., Claude via MCP, or a simple Telegram bot)
async def send_payment_to_customer(customer_id, checkout_url):
# Example: send via Telegram
message = f"Please scan or tap to pay: {checkout_url}"
await telegram_bot.send_message(customer_id, message)
# Or send via email, SMS, etc.
return {"status": "sent", "customer_id": customer_id}
# Trigger the send
await send_payment_to_customer("customer_123", payment_response.checkout_url)
Step 3: Await Settlement Confirmation
# Step 3: Wait for the payment to settle
# This polls the bank feed every 2 seconds for up to 5 minutes
settlement = await client.await_settlement(
payment_id=payment_response.payment_id,
timeout_seconds=300,
poll_interval_seconds=2
)
if settlement.confirmed:
print(f"✅ Payment confirmed! Amount: {settlement.amount} VND")
print(f" Transaction ID: {settlement.transaction_id}")
print(f" Settled at: {settlement.settled_at}")
# Trigger your success logic: update order status, unlock content, etc.
await update_order_status("order_20250115_001", "completed")
else:
print("❌ Payment not confirmed within timeout.")
# Handle timeout or ask customer to retry
Why this matters: The await_settlement() call blocks your agent until the bank confirms the transfer. No webhook setup required (though AgentPay supports webhooks for production). Your agent knows with certainty when money has arrived.
Using AgentPay VN with Claude (MCP Integration)
If you're running Claude (or compatible) agents via MCP (Model Context Protocol), AgentPay VN provides a server that exposes payment operations as tools:
MCP Configuration (Claude Desktop)
Add this to your Claude desktop config (usually ~/.config/Claude/claude_desktop_config.json):
{
"mcpServers": {
"agentpay": {
"command": "agentpay-mcp",
"env": {
"BANK_CODE": "970",
"ACCOUNT_NUMBER": "1234567890",
"ACCOUNT_HOLDER": "Nguyen Van A",
"AGENTPAY_API_KEY": "your_api_key_here"
}
}
}
}
Once configured, Claude can call these tools natively:
- create_payment_request – generate VietQR
- await_settlement – poll for payment confirmation
- check_payment_status – query status of a previous payment
Example Claude prompt:
User: "I sold an online course for 2 million VND. Can you generate a VietQR code and wait for payment?"
Claude: I'll create a payment request and monitor for settlement.
[Uses MCP to call create_payment_request]
[Returns checkout URL to user]
[Uses MCP to call await_settlement]
[Confirms when payment arrives]
Real-World Walkthrough: Autonomous Café Order Bot
Let's build a concrete scenario: An AI chatbot that manages orders and payment collection for a small café.
User Journey: 1. Customer messages the café's Facebook bot: "I want to order 2 iced coffees for pickup tomorrow at 2 PM." 2. Bot confirms order and calculates total: ₫80,000. 3. Bot generates a VietQR code and sends checkout URL via Messenger. 4. Customer scans and pays via their banking app (SCB, ACB, Vietcombank, etc.). 5. Within 2 seconds, bot receives settlement confirmation and replies: "✅ Payment confirmed! Your order is confirmed for tomorrow 2 PM." 6. Café staff receives a dashboard notification (or bot sends it to a group chat) and starts preparing.
Code sketch:
from agentpay_vn import AgentPayClient, PaymentRequest
import asyncio
from datetime import datetime
client = AgentPayClient(
bank_code="970",
account_number="cafe_account_123",
account_holder="Cafe ABC",
api_key="..."
)
async def handle_cafe_order(customer_id, order_items, pickup_time):
# Calculate total
total_amount = sum(item["price"] * item["qty"] for item in order_items)
# Create payment request
payment = await client.create_payment_request(
PaymentRequest(
amount=int(total_amount),
description=f"Café Order - Pickup {pickup_time}",
order_id=f"cafe_{customer_id}_{int(datetime.now().timestamp())}"
)
)
# Send checkout URL to customer (via Messenger API, etc.)
await send_messenger_message(
customer_id,
f"Total: ₫{total_amount:,.0f}\n\nPay here: {payment.checkout_url}"
)
# Wait for settlement
settlement = await client.await_settlement(
payment_id=payment.payment_id,
timeout_seconds=600 # 10 minutes grace period
)
if settlement.confirmed:
await send_messenger_message(
customer_id,
f"✅ Payment received! Your order is confirmed for {pickup_time}."
)
await notify_cafe_staff(f"New order ready to prepare: {order_items}")
return {"status": "success", "transaction_id": settlement.transaction_id}
else:
await send_messenger_message(
customer_id,
"⏱️ Payment not received. Please try again."
)
return {"status": "timeout"}
# Trigger when customer sends order
await handle_cafe_order(
customer_id="user_456",
order_items=[{"name": "Iced Coffee", "price": 35000, "qty": 2}],
pickup_time="2025-01-16 14:00"
)
This is a real payment loop, no manual steps.
AgentPay VN vs. Stripe vs. Manual Bank Transfers
| Criteria | AgentPay VN | Stripe | Manual Bank Transfer |
|---|---|---|---|
| VietQR Support | ✅ Native | ❌ No Vietnam support | ✅ Yes, but manual |
| Fee | ~1.5% (varies by bank) | 3–5% + international fee | 0%, but time-costly |
| Settlement Speed | 1–10 seconds (bank-dependent) | 2–3 days | 30 min–hours (manual) |
| AI Agent Integration | ✅ SDK + MCP | ✅ API, but Vietnam-unfriendly | ❌ Requires scraping/manual |
| Money Held by Service | ❌ No (direct bank) | ✅ Yes (intermediary) | N/A |
| Setup Complexity | 🟢 Low (3 lines) | 🟡 Medium | 🟢 Low but tedious |
| Open Source | ✅ MIT | ❌ Proprietary | N/A |
The key advantage: AgentPay VN is built for Vietnam's payment reality and for AI agents. It's not a "lite" Stripe clone; it's a purpose-built tool.
Best Practices & Advanced Tips
1. Error Handling & Retries
Bank feeds can be flaky. Implement exponential backoff:
import random
async def await_settlement_with_retry(
client, payment_id, max_retries=3
):
for attempt in range(max_retries):
try:
settlement = await client.await_settlement(
payment_id=payment_id,
timeout_seconds=300
)
return settlement
except Exception as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt + random.uniform(0, 1)
print(f"Retry in {wait_time:.1f}s...")
await asyncio.sleep(wait_time)
else:
raise
2. Webhook Support (Production)
Instead of polling, configure a webhook in the AgentPay dashboard:
# Your Flask/FastAPI endpoint
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/webhook/agentpay")
async def handle_payment_webhook(request: Request):
payload = await request.json()
# payload = {"payment_id": "...", "status": "confirmed", "amount": 500000, ...}
if payload["status"] == "confirmed":
await process_order_completion(payload["order_id"])
return {"status": "ok"}
This eliminates polling overhead and gives sub-second confirmation.
3. Multi-Bank Reconciliation
If you operate across multiple merchant accounts, track which bank received what:
PAYMENT_ROUTES = {
"product_sales": {"bank_code": "970", "account": "acc_1"},
"service_fees": {"bank_code": "970", "account": "acc_2"},
}
async def create_multi_bank_payment(category, amount):
route = PAYMENT_ROUTES[category]
client = AgentPayClient(
bank_code=route["bank_code"],
account_number=route["account"],
# ...
)
return await client.create_payment_request(...)
4. Logging & Observability
Track every payment through your system:
import logging
logger = logging.getLogger("agentpay")
async def log_payment_lifecycle(payment_id, event, details):
logger.info(
f"payment_id={payment_id} event={event}",
extra={"payment_details": details}
)
# Push to your logging service (DataDog, CloudWatch, etc.)
FAQ
Q: What if a customer's bank doesn't support VietQR? A: All major Vietnamese banks support VietQR as of 2024 (Vietcombank, ACB, Techcombank, SCB, MB, etc.). Check the list if unsure. For unsupported banks, fall back to manual transfer instructions.
Q: Can I use AgentPay VN outside Vietnam? A: VietQR is Vietnam-specific. However, AgentPay VN's architecture is portable; if your use case extends to other countries, you could fork it for other QR standards (e.g., Thailand's PromptPay). The SDK is MIT-licensed.
Q: Is my money safe? Does AgentPay hold funds? A: No. AgentPay VN never touches the money. The QR code points directly to your merchant bank account. Settlement is confirmed by the bank's own feed, not AgentPay's database. You retain 100% control.
Q: How do I get an API key? A: Register and generate an API key at https://agentpay.servicesai.vn/v1/docs. You'll need your merchant bank account details. Setup takes ~5 minutes.
Q: Can I use AgentPay VN with non-LLM bots (e.g., Telegram, Discord bots)? A: Absolutely. AgentPay VN is a generic Python SDK. Integrate it into any async Python bot framework (Aiogram, Discord.py, FastAPI, etc.).
Key Takeaways
- AgentPay VN is purpose-built for Vietnam's VietQR + AI agents. It fills a gap Stripe and PayPal can't address.
- Three-line payment flow:
create_payment_request()→ send URL →await_settlement(). No complexity, no intermediary. - Zero intermediary risk: Money goes straight to your bank account. AgentPay never holds funds.
- Instant settlement confirmation (1–10 seconds) beats manual bank reconciliation (30 mins) or Stripe's 2–3 day delay.
- MCP integration with Claude means your AI agent can autonomously collect payments from customers.
- Open-source (MIT): Full transparency, no vendor lock-in, and you can extend it for your needs.
- Real-world use cases: Café bots, course platforms, freelance marketplaces, subscription tools—anywhere a Vietnamese business needs to collect payments via AI agents.
Getting Started Now
-
Install the SDK:
bash pip install agentpay-vn -
Read the full docs: https://agentpay.servicesai.vn/v1/docs
-
Check the source code (MIT): https://github.com/phuocdu/agentpay-vn
-
Join the conversation: Open an issue or contribute on GitHub. The Vietnamese developer community is building the payment infrastructure that should've existed years ago.
Your AI agent can collect payments in Vietnam starting today. No Stripe. No waiting. No intermediaries. Just VietQR, settlement confirmation, and pure automation.