AI Chatbot Payments: Sell Digital Products Without Holding Funds

2026-07-19 · AgentPay VN

ai-paymentsvietqrpython-sdkchatbot-monetizationfintech

The Silent Killer of AI Chatbot Commerce

Imagine you've just launched a ChatGPT-powered chatbot that sells online courses, design templates, or API credits. A customer arrives, loves your product, and is ready to pay—but then friction appears. Your bot needs to process payment, hold funds temporarily, reconcile bank transfers, and handle refunds. You're now operating a payment processor, not an AI service.

Worse: compliance headaches. Most jurisdictions require licenses to hold customer money. Your scrappy startup suddenly looks like it's breaking regulations.

This is where AgentPay VN changes the game. Instead of your bot holding funds, payments flow directly into your bank account via VietQR—Vietnam's instant bank transfer standard. Your AI agent orchestrates the sale, but the money never touches your infrastructure.


What Makes AgentPay VN Different?

Most payment SDKs force you into a custody model: customer pays → funds sit in your merchant account → you transfer to bank. AgentPay VN inverts this:

The result: a 3-line workflow for your bot—create request, send checkout URL, await settlement. That's it.


The 3-Line Payment Flow

Before diving into code, here's the conceptual flow that makes AgentPay VN so elegant:

  1. create_payment_request – Your bot generates a payment request with amount, description, and merchant details.
  2. send checkout_url – Bot shares a VietQR checkout link with the customer (SMS, email, chat message, etc.).
  3. await_settlement – Bot monitors the bank feed; once it confirms payment landed in your account, bot fulfills the order (sends API key, course link, file download, etc.).

No intermediate wallets. No escrow accounts. No waiting 3–5 business days. Your bank confirms settlement in seconds to minutes.


Getting Started: Installation and Setup

Step 1: Install the SDK

pip install agentpay-vn

That's genuinely it. No API keys to juggle, no complex initialization—AgentPay VN auto-detects your environment and bank details from your bank's VietQR registry.

Step 2: Configure Your Bank Account

You'll need: - A Vietnamese bank account (VietQR-enabled; most major banks support this). - Your account number and bank code (e.g., VCB for Vietcombank).

AgentPay VN uses these to generate QR codes that customers scan to pay you directly.

Step 3: Set Your Webhook or Bank Feed Monitor

You can either: - Run the MCP server (agentpay-mcp) and let Claude fetch settlement status on demand. - Integrate a bank feed service (like your bank's API) to push notifications to your bot.

We'll cover both below.


Real-World Walkthrough: A Course-Selling Chatbot

Let's say you've built CourseBot, a chatbot that sells Python programming courses. A user types: "I want the advanced course."

The Code Flow

import asyncio
from agentpay_vn import PaymentRequest, SettlementMonitor
from datetime import datetime, timedelta

# Initialize payment system
payment_system = PaymentRequest(
    merchant_id="your_bank_account",
    merchant_bank="VCB",  # Vietcombank
    merchant_name="CourseBot"
)

async def sell_course(user_id: str, course_name: str, price_vnd: int):
    """
    Full flow: create payment request → send to user → await settlement → deliver course
    """

    # Step 1: Create payment request
    # This generates a unique QR code for this transaction
    payment_req = payment_system.create_payment_request(
        amount_vnd=price_vnd,
        description=f"Course: {course_name}",
        order_id=f"{user_id}_{course_name}_{datetime.now().timestamp()}",
        expiry_minutes=30  # QR expires in 30 minutes
    )

    # payment_req contains:
    # - qr_code_url: URL to image of VietQR code
    # - checkout_url: Direct link to pay (mobile-friendly)
    # - transaction_id: Unique ID to track settlement

    print(f"Payment created. Send this link to user: {payment_req.checkout_url}")
    # In a real bot, you'd send: "Click here to pay: {checkout_url}"

    # Step 2: Monitor for settlement
    # Create a settlement monitor (polls bank feed every 5 seconds)
    monitor = SettlementMonitor(
        transaction_id=payment_req.transaction_id,
        timeout_seconds=600  # Wait up to 10 minutes
    )

    # Step 3: Await settlement
    # This blocks until payment confirmed OR timeout
    settlement = await monitor.await_settlement()

    if settlement.confirmed:
        print(f"✓ Payment confirmed! {settlement.amount_vnd} VND received.")

        # Deliver the course
        course_link = deliver_course_to_user(user_id, course_name)
        return {
            "status": "success",
            "message": f"Course link: {course_link}",
            "transaction_id": settlement.transaction_id
        }
    else:
        print(f"✗ Payment not confirmed within timeout.")
        return {"status": "timeout", "message": "Please try again."}

# Run it
async def main():
    result = await sell_course(
        user_id="user_123",
        course_name="Python Advanced",
        price_vnd=299000
    )
    print(result)

asyncio.run(main())

Line-by-Line Breakdown


Integrating with Claude via MCP Server

If your bot runs on Claude (via API), use the MCP (Model Context Protocol) server for seamless integration:

MCP Configuration (Claude Settings)

{
  "mcpServers": {
    "agentpay": {
      "command": "agentpay-mcp",
      "args": [
        "--merchant-id", "your_bank_account",
        "--merchant-bank", "VCB",
        "--webhook-secret", "your_secret_key"
      ]
    }
  }
}

Once active, Claude can: - Call create_payment_request(amount, description) → Get a checkout URL instantly. - Call check_settlement_status(transaction_id) → Verify if payment landed. - Call list_recent_settlements() → See all confirmed transactions today.

Example Claude prompt:

User: "I want the Figma template pack. How much?"

Claude (using MCP):
1. Calls create_payment_request(amount=199000, description="Figma template pack")
2. Receives checkout_url
3. Responds: "That's 199,000 VND. Pay here: [link]. Once confirmed, I'll send your templates."
4. Periodically checks settlement status
5. When confirmed, sends download link

The MCP server handles bank-feed polling in the background—Claude doesn't need to worry about async complexity.


Advanced Tips & Best Practices

Tip 1: Handle QR Code Expiry Gracefully

VietQR codes can expire (default 30 minutes). Regenerate if needed:

if payment_req.is_expired():
    new_req = payment_system.create_payment_request(
        amount_vnd=price_vnd,
        description=f"Course: {course_name} (retry)",
        order_id=f"{user_id}_{course_name}_{datetime.now().timestamp()}"
    )
    # Send new checkout URL

Tip 2: Add Idempotency Keys

Prevent duplicate charges if a user accidentally scans twice:

payment_req = payment_system.create_payment_request(
    amount_vnd=299000,
    description="Course",
    order_id="user_123_course_v1",  # Same order_id = same transaction
    idempotency_key="user_123_action_timestamp"  # Prevents double-processing
)

Tip 3: Batch Multiple Orders

If your bot sells bundles, create requests for each item and aggregate settlement:

orders = [
    ("Python Course", 199000),
    ("Design Template", 99000),
    ("API Credits", 50000)
]

transactions = []
for name, price in orders:
    req = payment_system.create_payment_request(
        amount_vnd=price,
        description=name,
        order_id=f"{user_id}_{name}_{now()}"
    )
    transactions.append(req)

# Send all checkout URLs together, monitor in parallel
settlements = await asyncio.gather(*[
    SettlementMonitor(t.transaction_id).await_settlement()
    for t in transactions
])

Tip 4: Retry Failed Settlement Checks

Network hiccups happen. Implement exponential backoff:

async def await_with_retry(transaction_id: str, max_retries=5):
    retry_count = 0
    while retry_count < max_retries:
        try:
            monitor = SettlementMonitor(transaction_id, timeout_seconds=120)
            return await monitor.await_settlement()
        except ConnectionError:
            retry_count += 1
            await asyncio.sleep(2 ** retry_count)  # Exponential backoff
    raise Exception(f"Failed to confirm settlement after {max_retries} retries")

Do's and Don'ts

Do Don't
Use order_id to tie transactions to specific users/orders. Don't reuse transaction_id across multiple payments.
Set reasonable expiry_minutes (15–60 based on use case). Don't set expiry_minutes < 5 (customer won't have time to pay).
Store transaction_id in your database for audit trails. Don't rely solely on polling; use bank webhooks if available.
Test with small amounts (1,000–5,000 VND) first. Don't skip timeout handling; always define max wait times.
Monitor settlement logs to catch edge cases. Don't assume instant settlement (bank processing adds 10–30 sec delay).

FAQ

Q: Does my bank account need special setup for VietQR?

A: Most major Vietnamese banks (VCB, TCB, MB, ACB, etc.) auto-enable VietQR. Check your bank's app—if you can generate a static QR code, you're set. AgentPay VN uses your existing account; no special merchant registration needed.

Q: What if a customer claims they paid but settlement didn't confirm?

A: Check your bank's transaction history first—payments sometimes take 30–60 seconds. If the bank confirms it landed but AgentPay VN didn't detect it, log the transaction_id and reach out to support. Keep records of the customer's proof (screenshot, etc.) for dispute resolution.

Q: Can I use AgentPay VN outside Vietnam?

A: The SDK is designed for Vietnamese banks and VietQR. If your customer is outside Vietnam but has a VietQR-enabled app (Vietcombank app, MB Bank, etc.), they can still pay. For non-Vietnamese customers, consider a multi-gateway approach: AgentPay VN for VN-based users, Stripe/PayPal for international.

Q: How do I handle refunds?

A: Refunds are manual—you initiate a bank transfer to the customer's account using your bank's app/API. AgentPay VN doesn't automate refunds (by design, since it doesn't hold funds). Log the refund reason and original transaction_id for your records.


Key Takeaways


Next Steps

Ready to monetize your AI agent?

  1. Install: pip install agentpay-vn
  2. Explore the docs: https://agentpay.servicesai.vn/v1/docs
  3. Clone examples: https://github.com/phuocdu/agentpay-vn
  4. Test with 1,000 VND to your own account—see how fast settlement happens.
  5. Ship it: Add payment requests to your chatbot and start selling.

Your bot shouldn't need a CFO. AgentPay VN keeps it simple.

Get started →

← All posts