VietQR Payment Automation for AI Agents: Stripe Alternative

2026-06-26 · AgentPay VN

vietqrpaymentsai-agentspython-sdkvietnam

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:

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

Getting Started Now

  1. Install the SDK: bash pip install agentpay-vn

  2. Read the full docs: https://agentpay.servicesai.vn/v1/docs

  3. Check the source code (MIT): https://github.com/phuocdu/agentpay-vn

  4. 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.

Get started →

← All posts