VietQR Payment Automation for AI Agents: Stripe Alternative

2026-08-16 · AgentPay VN

vietqrai-agentspayment-automationpython-sdkvietnam

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:

  1. Instant settlement: Bank confirms deposit within minutes; no 2-3 day holds.
  2. Lower friction: Customers already know how to scan QR codes; no new apps or logins.
  3. 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:

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

Next Steps

Ready to integrate VietQR payments into your AI agent?

  1. Install the SDK: pip install agentpay-vn
  2. Read the full documentation: https://agentpay.servicesai.vn/v1/docs
  3. Explore the source code: https://github.com/phuocdu/agentpay-vn
  4. 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.

Get started →

← All posts