VietQR Payment Automation for AI Agents

2026-08-02 · AgentPay VN

vietqrai-agentspayment-automationpythonvietnam

The Problem: AI Agents Need Direct Bank Payments in Vietnam

You've built an AI agent that sells courses, processes café orders, or handles micro-transactions. It works flawlessly in the US, where Stripe handles everything. But when your Vietnamese users try to pay, they hit a wall: Stripe doesn't accept VietQR—the national QR standard that 99% of Vietnamese banks support. Your agent sits idle, unable to collect payment.

You're not alone. Every AI builder targeting Vietnam faces the same choice: integrate a fragmented patchwork of local payment gateways, or abandon the market entirely. There's been no standard way for autonomous systems to request and verify VietQR payments until now.

Enter AgentPay VN: an MIT-licensed Python SDK that lets AI agents request VietQR payments directly, pointing straight to your merchant bank account—no middleman holding your money.


Why AgentPay VN, Not Stripe or Local Gateways?

The Hidden Costs of Alternatives

Stripe in Vietnam: - ❌ Does not support VietQR (the payment method 95%+ of Vietnamese users prefer) - ❌ Requires complex pre-approval for Vietnam operations - ❌ Higher fees for cross-border settlement (2–3% + FX margin) - ❌ Integrations take 2–4 weeks of back-and-forth

Local Vietnamese Payment Gateways (Zalopay, Momo, etc.): - ❌ Each requires separate API documentation and contract - ❌ Fragmented wallets (users must install multiple apps) - ❌ Less suitable for AI agents (built for web checkout, not autonomous systems) - ❌ Slower settlement (T+2 or later)

AgentPay VN: - ✅ Native VietQR support—use the payment method users already have - ✅ Open-source (MIT), so you own the integration - ✅ Zero money custody—QR points directly to your bank account - ✅ Instant bank feed confirmation of payment - ✅ Built specifically for AI agents and autonomous systems - ✅ One-line install: pip install agentpay-vn


How AgentPay VN Works: The 3-Step Flow

Unlike traditional payment gateways that hold funds and manage reconciliation, AgentPay VN is deliberately simple:

  1. Your AI agent creates a payment request (amount, description, metadata)
  2. AgentPay generates a VietQR code and checkout URL pointing to your merchant account
  3. Your agent awaits a bank settlement confirmation via real-time bank feed

That's it. No intermediate accounts. No settlement delays. No surprise disputes.


Installation & Setup (5 Minutes)

Step 1: Install the SDK

pip install agentpay-vn

Step 2: Configure Your Merchant Bank Account

You'll need: - A Vietnamese bank account (most major banks supported: Vietcombank, Techcombank, VPBank, etc.) - Bank account holder name - Bank account number - Bank code (e.g., 970010 for Vietcombank)

Store these securely in environment variables:

export AGENTPAY_MERCHANT_NAME="Your Business Name"
export AGENTPAY_BANK_ACCOUNT="1234567890"
export AGENTPAY_BANK_CODE="970010"  # Vietcombank

Step 3: Verify Your Setup

from agentpay_vn import AgentPayClient

client = AgentPayClient()
status = client.verify_merchant()
print(f"Merchant verified: {status.is_active}")

Building Your First AI Agent Payment Flow

Real-World Scenario: AI Tutoring Bot

Imagine an AI tutoring chatbot that helps Vietnamese students practice English. A student asks to unlock premium lessons (₫50,000 = ~$2 USD). The agent should:

  1. Generate a unique payment request
  2. Show the user a VietQR code to scan
  3. Wait for bank confirmation
  4. Unlock the content

Here's how your agent does it:

from agentpay_vn import AgentPayClient, PaymentRequest
import uuid
import time
from datetime import datetime

# Initialize the client (reads env variables automatically)
client = AgentPayClient()

def create_premium_unlock(student_id: str, course_title: str) -> dict:
    """
    AI agent function to request payment for course unlock.
    """
    # Step 1: Create a unique payment request
    request_id = f"course_{student_id}_{uuid.uuid4().hex[:8]}"

    payment = PaymentRequest(
        request_id=request_id,
        amount_vnd=50000,  # ₫50,000
        description=f"Premium access: {course_title}",
        merchant_reference=student_id,  # Link to student DB
        metadata={
            "course_id": course_title,
            "student_email": "student@example.com",
            "timestamp": datetime.utcnow().isoformat()
        },
        expires_in_seconds=600  # QR valid for 10 minutes
    )

    # Step 2: Generate VietQR checkout
    qr_response = client.create_payment_request(payment)

    return {
        "request_id": request_id,
        "qr_code_url": qr_response.qr_image_url,  # PNG or SVG
        "checkout_url": qr_response.checkout_url,  # For mobile web
        "amount": payment.amount_vnd,
        "expires_at": qr_response.expires_at
    }

def wait_for_payment_settlement(request_id: str, timeout_seconds: int = 300) -> bool:
    """
    AI agent polls for payment confirmation.
    In production, use webhooks instead of polling.
    """
    start_time = time.time()

    while time.time() - start_time < timeout_seconds:
        settlement = client.await_settlement(request_id)

        if settlement.is_settled:
            print(f"✅ Payment confirmed! Amount: ₫{settlement.amount_received}")
            print(f"   Bank reference: {settlement.bank_transaction_id}")
            return True

        if settlement.is_expired:
            print("❌ QR code expired. Request new payment.")
            return False

        # Check every 2 seconds
        time.sleep(2)

    print("⏱️ Payment timeout. User may still pay within bank window.")
    return False

# Usage in your agent:
if __name__ == "__main__":
    # Student requests premium access
    payment_info = create_premium_unlock(
        student_id="student_12345",
        course_title="Advanced English Conversation"
    )

    print(f"📱 Ask user to scan QR code: {payment_info['qr_code_url']}")
    print(f"🔗 Or open in mobile: {payment_info['checkout_url']}")
    print(f"⏰ Valid until: {payment_info['expires_at']}")

    # Wait for payment
    if wait_for_payment_settlement(payment_info['request_id']):
        print("🎉 Unlocking premium lessons...")
        # Trigger your course unlock logic here
    else:
        print("💳 Payment failed. Please try again.")

Line-by-line explanation:


Integrating AgentPay with Claude (MCP Server)

If you're using Claude as your AI backbone, use the AgentPay MCP (Model Context Protocol) server to give Claude native payment capabilities.

Configure Claude Desktop

Edit ~/.config/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "agentpay": {
      "command": "python",
      "args": ["-m", "agentpay_mcp"],
      "env": {
        "AGENTPAY_MERCHANT_NAME": "Your Business Name",
        "AGENTPAY_BANK_ACCOUNT": "1234567890",
        "AGENTPAY_BANK_CODE": "970010"
      }
    }
  }
}

Now Claude Can Call Payment Tools Directly

Inside Claude, you can now say:

"Create a payment request for ₫100,000 for a course license, then wait for settlement."

Claude automatically: 1. Calls create_payment_request() via MCP 2. Generates the QR code 3. Shows it to the user 4. Polls await_settlement() until payment arrives


Real-World Walkthrough: AI Course-Selling Bot

Let's build a complete example: an AI bot that sells Vietnamese language courses.

Flow:

  1. User: "I want to buy the advanced Hanoi dialect course."
  2. Bot: "That's ₫150,000. Let me create a payment link for you."
  3. Bot: Generates VietQR, displays checkout URL
  4. User: Scans QR with their banking app, pays
  5. Bot: "Payment confirmed! Here's your course access link."

The Complete Code:

from agentpay_vn import AgentPayClient
from datetime import datetime
import json

class CourseBot:
    COURSES = {
        "hanoi_dialect": {"name": "Advanced Hanoi Dialect", "price": 150000},
        "business_vn": {"name": "Business Vietnamese", "price": 200000},
        "poetry": {"name": "Vietnamese Poetry", "price": 100000}
    }

    def __init__(self):
        self.client = AgentPayClient()

    def sell_course(self, course_key: str, user_id: str) -> dict:
        course = self.COURSES[course_key]

        # Create payment
        qr = self.client.create_payment_request(
            PaymentRequest(
                request_id=f"course_{course_key}_{user_id}_{int(datetime.now().timestamp())}",
                amount_vnd=course["price"],
                description=f"Course: {course['name']}",
                merchant_reference=user_id
            )
        )

        # Return checkout details
        return {
            "course": course["name"],
            "price": f"₫{course['price']:,}",
            "qr_image": qr.qr_image_url,
            "checkout_url": qr.checkout_url,
            "request_id": qr.request_id
        }

    def confirm_purchase(self, request_id: str) -> bool:
        settlement = self.client.await_settlement(request_id, timeout_seconds=300)
        return settlement.is_settled

# Usage
bot = CourseBot()
payment = bot.sell_course("hanoi_dialect", "user_999")
print(f"Checkout ready: {payment['checkout_url']}")

if bot.confirm_purchase(payment["request_id"]):
    print("✅ Course access granted!")

AgentPay vs. Alternatives: Quick Comparison

Feature AgentPay VN Stripe Zalopay MoMo
VietQR Support ✅ Native ❌ No ⚠️ Via QR ⚠️ Via QR
Vietnam Bank Setup ✅ Simple (bank account only) ❌ Complex (approval needed) ⚠️ Moderate ⚠️ Moderate
Settlement Speed ✅ Real-time ⚠️ T+1 to T+2 ⚠️ T+1 ⚠️ T+1
Custody Risk ✅ None (direct to bank) ⚠️ Medium (holds funds) ⚠️ Medium ⚠️ Medium
AI Agent Native ✅ Yes ⚠️ Web-first ❌ Web-only ❌ Web-only
Open Source ✅ MIT ❌ Proprietary ❌ Proprietary ❌ Proprietary
Monthly Fee $0 ⚠️ $29+ ⚠️ ~1.5% ⚠️ ~1.5%
Per-Transaction Fee ~0.5–1.5% 2.9% + $0.30 1.5–2.5% 1.5–2.5%

Do's and Don'ts

✅ DO

❌ DON'T


FAQ

Q: Does AgentPay VN hold my money?

A: No. AgentPay VN never touches your funds. The QR code points directly to your merchant bank account. Your bank confirms the payment, and AgentPay relays that confirmation to your agent. Settlement is instant (within seconds, not hours).

Q: Which Vietnamese banks are supported?

A: All major banks that support VietQR, including Vietcombank (970010), Techcombank (970023), VPBank (970432), MB Bank (970422), Agribank (970405), and 30+ others. Check your bank code at napas.com.vn.

Q: Can I use AgentPay VN outside Vietnam?

A: Currently, AgentPay VN is optimized for Vietnam bank accounts. If you need to accept payments from international cards, combine it with a cross-border provider (e.g., for USD → VND conversion first).

Q: What if a customer scans the QR but doesn't complete payment?

A: The QR code expires (default 10 minutes). Your agent's await_settlement() will return is_expired = True. You can generate a new request and show a fresh QR code.

Q: How do I handle refunds?

A: Since AgentPay VN never holds funds, refunds are direct bank-to-bank transfers using your merchant account. You'd initiate the refund from your bank's API or dashboard (outside AgentPay).


Advanced: Webhook Integration for Production

Polling every 2 seconds works for demos, but in production, subscribe to bank settlement webhooks:

from agentpay_vn import AgentPayClient, WebhookHandler

client = AgentPayClient()

# Register your webhook endpoint
client.register_webhook(
    url="https://your-domain.com/webhooks/agentpay",
    events=["payment.settled", "payment.failed"]
)

# Your webhook handler
def handle_settlement_webhook(event):
    if event["type"] == "payment.settled":
        request_id = event["data"]["request_id"]
        amount = event["data"]["amount"]
        bank_ref = event["data"]["bank_transaction_id"]

        # Unlock course, deliver digital product, etc.
        print(f"Settled: {request_id} for ₫{amount}")

Webhooks eliminate polling latency and are 100x more efficient for high-volume agents.


Key Takeaways


Get Started Now

  1. Install: pip install agentpay-vn
  2. Read the docs: https://agentpay.servicesai.vn/v1/docs
  3. Explore the code: https://github.com/phuocdu/agentpay-vn
  4. Join the community: Star the repo, open issues, share your integrations

Your AI agents are ready to collect Vietnamese payments. Let's build.

Get started →

← All posts