Sell Digital Products via AI Chatbot Without Holding Funds

2026-09-19 · AgentPay VN

pythonai-agentspaymentsvietqrmcp

The Problem: Your AI Chatbot Can't Sell Anything

You've trained an AI chatbot to answer questions, close leads, and guide customers through your digital product catalog. It's sharp. It converts. But the moment someone says "I want to buy," the bot hits a dead end.

The painful reality: most AI frameworks have zero integration with payment processors. You either:

  1. Redirect to a third-party checkout (losing context, breaking flow, watching abandonment spike)
  2. Build custom payment code (complexity, security risk, maintenance burden)
  3. Abandon the sale (losing revenue)

Even if you integrate Stripe or PayPal, you're swimming in PCI compliance, webhook debugging, and fund management. For merchants in Vietnam who need VietQR, the situation is worse—no native support in popular frameworks.

What if your bot could collect payment directly into your bank account, no middleman, no funds held, in three lines of code?


Introducing AgentPay VN: Payment Requests for AI Agents

AgentPay VN is a lightweight, open-source (MIT licensed) Python SDK + MCP server designed for one job: let your AI agent request payments and confirm they landed in your merchant account.

Core principle: You never hold the money. The QR code points straight at your bank. A bank feed confirms settlement. Your agent stays in control of the conversation while payment flows directly to you.

It's built in Python, integrates with Claude via MCP (Model Context Protocol), and requires zero merchant account setup beyond your existing bank.


How AgentPay VN Actually Works: The 3-Line Flow

Every payment request follows the same pattern:

1. create_payment_request()  → generates checkout_url
2. send checkout_url         → user scans VietQR
3. await_settlement()        → confirm payment in your bank

That's it. No webhooks to configure, no payment gateway accounts to open, no fund reconciliation.


Step-by-Step: Install and Configure

Installation

Start with pip:

pip install agentpay-vn

If you're running the MCP server (for Claude integration):

pip install agentpay-mcp

Configure Your Bank Details

AgentPay reads your merchant bank account from environment variables. Set these once:

export AGENTPAY_MERCHANT_ACCOUNT="1234567890"
export AGENTPAY_MERCHANT_NAME="Acme Digital Products"
export AGENTPAY_BANK_CODE="MB"  # Techcombank = MB, VietcomBank = VCB, etc.
export AGENTPAY_BANK_WEBHOOK_URL="https://your-domain.com/webhook"  # Optional

That's all. No API keys, no third-party accounts. Your bank, your account.


Building Your First Payment-Collecting Chatbot

Real-World Scenario: A Python Course Bot

Imagine you sell a Python certification course for 499,000 VND. A student chats with your bot:

Student: "I want to enroll in the advanced Python course."

Bot: "Perfect! That's 499,000 VND. Let me generate your payment link."

Bot sends QR → Student scans → Money arrives in your account → Bot confirms enrollment.

Here's the code:

from agentpay_vn import AgentPay

# Initialize
pay = AgentPay(
    merchant_account="1234567890",
    merchant_name="Python Academy VN",
    bank_code="MB"
)

# Student wants to enroll
student_id = "student_12345"
course_price_vnd = 499000
course_name = "Advanced Python Fundamentals"

# Step 1: Create payment request
payment_req = pay.create_payment_request(
    amount=course_price_vnd,
    order_id=f"course_{student_id}_{int(time.time())}",
    description=f"Enrollment: {course_name}",
    metadata={"student_id": student_id, "course": course_name}
)

# Step 2: Share checkout URL with student
checkout_url = payment_req.checkout_url
print(f"Student, scan this QR or visit: {checkout_url}")

# Step 3: Wait for settlement confirmation
settlement = pay.await_settlement(
    order_id=payment_req.order_id,
    timeout_seconds=300  # Wait up to 5 minutes
)

if settlement.confirmed:
    print(f"✓ Payment received! Enrolling student {student_id}...")
    # Trigger your enrollment logic
    enroll_student(student_id, course_name)
else:
    print(f"✗ Payment not received within timeout.")

Line-by-line breakdown:

Handling Async Workflows

In production, you don't want to block the chatbot while waiting for payment. Use async:

import asyncio
from agentpay_vn import AgentPay

pay = AgentPay(
    merchant_account="1234567890",
    merchant_name="Python Academy VN",
    bank_code="MB"
)

async def handle_enrollment(student_id: str, course_name: str, price: int):
    """Non-blocking payment + enrollment flow."""

    # Create payment request
    payment_req = pay.create_payment_request(
        amount=price,
        order_id=f"course_{student_id}_{int(time.time())}",
        description=f"Enrollment: {course_name}"
    )

    print(f"Checkout: {payment_req.checkout_url}")

    # Don't block—store the order ID and check later
    async def verify_and_enroll():
        settlement = await pay.await_settlement_async(
            order_id=payment_req.order_id,
            timeout_seconds=600
        )
        if settlement.confirmed:
            enroll_student(student_id, course_name)
            send_email(student_id, "Enrollment confirmed!")

    # Fire and forget
    asyncio.create_task(verify_and_enroll())
    return {"status": "checkout_sent", "url": payment_req.checkout_url}

# Usage
asyncio.run(handle_enrollment("student_12345", "Advanced Python", 499000))

Now your chatbot immediately returns the checkout URL and doesn't stall. Payment verification happens in the background.


Integrate AgentPay with Claude via MCP

If you're running Claude as your AI backbone, use the MCP server for seamless integration.

MCP Server Configuration

Start the MCP server:

agentpay-mcp --port 8765

Then configure Claude's claude_desktop_config.json:

{
  "mcpServers": {
    "agentpay": {
      "command": "agentpay-mcp",
      "args": ["--port", "8765"],
      "env": {
        "AGENTPAY_MERCHANT_ACCOUNT": "1234567890",
        "AGENTPAY_MERCHANT_NAME": "Python Academy VN",
        "AGENTPAY_BANK_CODE": "MB"
      }
    }
  }
}

Now in your Claude prompt, you can directly call:

User: "I want to buy the advanced course."

Claude (with MCP): I'll create a payment request for you.
[Uses agentpay.create_payment_request(amount=499000, ...)]  
Scan this QR code: [checkout_url]

[Waits for settlement via agentpay.await_settlement()]

✓ Payment confirmed! Sending your course access...

The MCP server exposes three core functions: - create_payment_request(amount, order_id, description, metadata) - get_payment_status(order_id) - await_settlement(order_id, timeout_seconds)

Claude can call them naturally, no custom glue code needed.


Real-World Walkthrough: An Online Course Store Bot

Let's trace a complete flow: a customer discovers your bot, browses courses, and buys.

Step 1: Bot Greets & Lists Courses

Bot: "Welcome! I sell 3 courses:
1. Python Basics (149K VND)
2. Advanced Python (499K VND)  
3. Machine Learning Mastery (899K VND)

Which interests you?"

Step 2: Customer Chooses

Customer: "I want Advanced Python."
Bot: "Great choice! Let me create your checkout."

Step 3: Bot Creates Payment Request

Backend calls create_payment_request(amount=499000, ...). Returns checkout URL.

Step 4: Bot Shows QR

Bot: "Scan this QR with your banking app:
[QR image: https://vietqr.io/...]

Or visit: https://checkout.agentpay.vn/..."

Step 5: Customer Scans & Pays

Customer opens their VietcomBank app, scans QR, confirms 499K VND transfer to your account. Takes 10 seconds.

Step 6: Bot Detects Settlement

await_settlement() polls your bank feed (via webhook or API). Within 30 seconds, it confirms the 499K arrived.

Step 7: Bot Grants Access

Bot: "✓ Payment received! 
Your course access is active: [link]
Login: yourname@example.com
Password: [generated]

Start lesson 1 now?"

Step 8: Post-Sale

Your webhook/background task triggers: - Send welcome email with course materials - Update your database (user enrolled) - Log the transaction - No manual reconciliation needed


Do's and Don'ts with AgentPay

Do Don't
Use unique order_id per request (append timestamp) Reuse order_id across multiple payments
Set realistic timeout_seconds (300–600 for most cases) Wait forever with timeout_seconds=999999
Store order_id in your DB for auditing Lose track of orders—you won't match payments to customers
Use metadata to tag orders (student_id, course, etc.) Ignore metadata—you'll regret it during debugging
Test in dev first with small amounts Go live without testing the settlement flow
Validate amount > 0 before calling create_payment_request Accept negative or zero amounts
Handle async settlement in production Block your chatbot waiting for payment

Troubleshooting & Advanced Tips

Issue: Settlement Never Confirms

Root cause: Bank feed isn't connected, or webhook URL is wrong.

Fix:

# Verify your bank details
print(pay.merchant_account)  # Should match your actual account
print(pay.bank_code)         # Correct bank code?

# Check webhook
print(pay.webhook_url)  # Is it publicly accessible? HTTPS?

Issue: Customer Scans QR but Nothing Happens

Root cause: Customer's banking app doesn't support VietQR, or the QR is malformed.

Fix:

# Always offer a fallback text/link
print(f"QR: {payment_req.checkout_url}")
print(f"or visit: {payment_req.fallback_url}")

Batch Enrollments for Bulk Buyers

If one customer buys 10 course licenses for a team:

team_size = 10
total_price = 499000 * team_size

payment_req = pay.create_payment_request(
    amount=total_price,
    order_id=f"bulk_order_{company_id}_{int(time.time())}",
    description=f"Bulk license: {team_size}x Advanced Python",
    metadata={
        "company_id": company_id,
        "team_size": team_size,
        "licenses": team_size
    }
)

# After settlement confirms:
for i in range(team_size):
    enroll_student(f"{company_id}_user_{i}", "Advanced Python")

FAQ

Q: Does AgentPay hold my money?

A: Never. The VietQR points directly to your merchant bank account. AgentPay only facilitates the request and confirms settlement—it's a bridge, not an escrow.

Q: What if my internet goes down mid-payment?

A: The payment still reaches your bank. When your internet returns, await_settlement() will detect it. Your bank is the source of truth, not AgentPay.

Q: Is AgentPay PCI-compliant?

A: AgentPay never handles card data—VietQR is bank-to-bank transfer. Your customer's banking app handles authentication. No PCI scope for you.

Q: Can I use AgentPay with other banks besides Techcombank?

A: Yes. AgentPay supports all Vietnamese banks via VietQR. Set bank_code to your bank's code ("VCB" for VietcomBank, "ACB" for ACB, etc.).


Key Takeaways


Getting Started Now

Ready to let your AI agent sell? Here's your next step:

# 1. Install
pip install agentpay-vn

# 2. Set env vars with your bank account
export AGENTPAY_MERCHANT_ACCOUNT="your_account_number"
export AGENTPAY_MERCHANT_NAME="Your Business"
export AGENTPAY_BANK_CODE="MB"

# 3. Copy the course bot code from above
# 4. Run it
python your_bot.py

Full documentation, code examples, and the MCP server config live at https://agentpay.servicesai.vn/v1/docs.

GitHub repository for issues, PRs, and community support: https://github.com/phuocdu/agentpay-vn.

Your chatbot is ready to collect real revenue. Start with one course. Scale to many.

Get started →

← All posts