AI Chatbot Payment Processing Without Holding Funds

2026-08-23 · AgentPay VN

ai-agentspayment-processingvietqrpython-sdkfintech

The Problem: Why Most AI Payment Integrations Are a Headache

You've built a smart chatbot that sells digital courses, software licenses, or design templates. Customers love it. But now you face a genuinely uncomfortable question: Where do you hold their money while you confirm delivery?

Every traditional payment gateway—Stripe, PayPal, Square—requires you to: 1. Hold funds in a merchant account (compliance liability). 2. Manage reconciliation between payment platform, your bot's database, and your bank. 3. Handle disputes and refunds yourself (customer service overhead). 4. Comply with local regulations for fund holding in Vietnam (complex).

For indie developers and small teams, this friction kills momentum. You either: - Use payment links (clunky; breaks conversational flow). - Build custom integrations (months of work). - Skip payments entirely (no revenue).

There's a better way. Enter AgentPay VN—a purpose-built solution for AI agents that need payments without the custody headache.


Meet AgentPay VN: Payments for AI Agents That Don't Touch Money

AgentPay VN is an open-source Python SDK + MCP server that lets your AI agents generate VietQR payment requests. Here's the critical difference:

You never hold the money. The QR code points directly to your merchant's bank account. The moment the customer pays, the funds settle there—confirmed by a bank feed. Your bot just orchestrates the flow.

Why This Matters

Installation is one line:

pip install agentpay-vn

The MCP server (agentpay-mcp) integrates with Claude and other AI platforms, turning your agent into a payment-aware system.


The Three-Step Payment Flow (It's Simple)

AgentPay VN abstracts payment handling into three core operations:

1. Create a Payment Request

Your bot generates a unique payment request with an amount, description, and optional metadata.

2. Send the Checkout URL

The customer scans a VietQR code or clicks a link. The QR points to your merchant account—not AgentPay.

3. Await Settlement

Your bot polls a bank feed or webhook to confirm the payment landed. Then it delivers the product (email the PDF, activate the license, etc.).

No escrow. No holding pattern. No risk.


Step-by-Step: Building Your First AI Payment Agent

Prerequisites

Step 1: Install AgentPay VN

pip install agentpay-vn

Step 2: Set Up Your Environment

Create a .env file with your bank credentials:

MERCHANT_ACCOUNT=0123456789  # Your VietQR-enabled account
BANK_CODE=VCB               # Your bank's code
API_KEY=your_bank_api_key   # From your bank's developer portal

Step 3: Build the Payment Agent (Full Example)

Here's a real Python script that creates a payment request and waits for settlement:

from agentpay_vn import PaymentManager, BankFeed
from datetime import datetime
import os
import time

# Initialize the payment manager with your credentials
payment_manager = PaymentManager(
    merchant_account=os.getenv("MERCHANT_ACCOUNT"),
    bank_code=os.getenv("BANK_CODE"),
    api_key=os.getenv("API_KEY")
)

def sell_digital_product(customer_email, product_id, price_vnd):
    """
    Main function: Create a payment request and deliver the product after settlement.

    Args:
        customer_email (str): Customer's email for delivery.
        product_id (str): The product being sold (e.g., "course_python_101").
        price_vnd (int): Price in Vietnamese Dong.

    Returns:
        dict: Settlement confirmation with transaction ID.
    """

    # Step 1: Create a payment request
    # This generates a unique payment ID tied to your merchant account.
    payment_request = payment_manager.create_payment_request(
        amount=price_vnd,
        description=f"Digital Product: {product_id}",
        metadata={
            "customer_email": customer_email,
            "product_id": product_id,
            "created_at": datetime.now().isoformat()
        }
    )

    # payment_request contains:
    # - payment_id: Unique identifier (e.g., "PAY_1234567890")
    # - checkout_url: The link customer clicks/scans
    # - qr_code: Raw QR data for embedding in your UI
    # - expires_at: When this payment request expires (usually 15 mins)

    print(f"🔗 Send this to the customer: {payment_request['checkout_url']}")
    print(f"Payment ID: {payment_request['payment_id']}")

    # Step 2: Wait for settlement (with a 10-minute timeout)
    # In production, use webhooks instead of polling for better UX.
    settlement = payment_manager.await_settlement(
        payment_id=payment_request['payment_id'],
        timeout_seconds=600
    )

    if settlement['status'] == 'settled':
        print(f"✅ Payment confirmed! Transaction ID: {settlement['transaction_id']}")
        print(f"Amount received: {settlement['amount']} VND")

        # Step 3: Deliver the product
        # Your logic here—email the PDF, create account, unlock feature, etc.
        deliver_product(
            email=customer_email,
            product_id=product_id,
            transaction_id=settlement['transaction_id']
        )

        return settlement
    else:
        print(f"❌ Payment failed or timed out. Status: {settlement['status']}")
        return None

def deliver_product(email, product_id, transaction_id):
    """
    Deliver the digital product after payment confirmation.
    (Replace with your actual delivery logic.)
    """
    print(f"📦 Sending {product_id} to {email}...")
    print(f"Transaction reference: {transaction_id}")
    # Your email/database logic here
    pass

# Example usage
if __name__ == "__main__":
    sell_digital_product(
        customer_email="student@example.com",
        product_id="python_advanced_course",
        price_vnd=299000  # ~$12 USD
    )

Line-by-line breakdown:


Integrating with Claude via MCP Server

For AI agents to autonomously manage payments, use the AgentPay MCP server. This exposes payment functions as tools Claude (or other LLMs) can call.

MCP Configuration (Claude Desktop)

Add this to your Claude configuration file (claude_desktop_config.json):

{
  "mcpServers": {
    "agentpay": {
      "command": "agentpay-mcp",
      "env": {
        "MERCHANT_ACCOUNT": "0123456789",
        "BANK_CODE": "VCB",
        "API_KEY": "your_bank_api_key",
        "WEBHOOK_URL": "https://your-bot.com/webhooks/payment"
      }
    }
  }
}

Now Claude can natively call: - create_payment_request(amount, description, metadata) - check_settlement_status(payment_id) - cancel_payment(payment_id)


Real-World Walkthrough: AI Course-Selling Chatbot

Let's build a conversational chatbot that sells Python courses. Here's the flow:

User: "I want the advanced Python course."

Bot: (via Claude + AgentPay) "Great! The course is 299,000 VND (~$12). Scan this QR code or click here to pay."

[Customer scans QR → pays → VietQR routes to your merchant account]

Bot: (2 seconds later, after settlement) "✅ Payment confirmed! You now have lifetime access. Download here or log in to your account."

Behind the scenes: 1. Claude calls create_payment_request(amount=299000, description="Python Advanced Course"). 2. AgentPay generates a checkout URL (VietQR). 3. Your bot embeds the URL in the chat. 4. Customer pays via their bank app (instant). 5. AgentPay polls your bank feed (or uses a webhook). 6. Settlement confirmed → Claude triggers product delivery (email, account unlock, etc.).

Total payment latency: <2 seconds (vs. 24-48 hours with traditional gateways).


Best Practices: Do's and Don'ts

DO DON'T
Use webhooks for settlement confirmation (faster, cheaper than polling). Assume payment is instant—always await settlement.
Store transaction IDs in your database for reconciliation. Hardcode credentials; always use environment variables.
Set realistic payment timeouts (10–15 minutes for VietQR). Redirect users away from your chat—keep payments conversational.
Test with small amounts first ($1–2 equivalent). Forget to log failed payments for debugging.
Implement idempotency (prevent duplicate deliveries if webhook fires twice). Expose your API_KEY in logs or git history.

Advanced: Webhook-Based Settlement (Production-Ready)

Instead of polling, use webhooks for instant settlement notification:

from flask import Flask, request
import hmac
import hashlib

app = Flask(__name__)
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET")

@app.route('/webhooks/payment', methods=['POST'])
def payment_webhook():
    """
    Receive settlement confirmation from AgentPay.
    """
    payload = request.json
    signature = request.headers.get('X-Signature')

    # Verify webhook authenticity
    expected_sig = hmac.new(
        WEBHOOK_SECRET.encode(),
        request.get_data(),
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected_sig):
        return {"error": "Invalid signature"}, 401

    # Process settlement
    if payload['status'] == 'settled':
        payment_id = payload['payment_id']
        transaction_id = payload['transaction_id']
        amount = payload['amount']

        # Fetch original payment request from your database
        original_request = db.get_payment_request(payment_id)

        # Deliver the product
        deliver_product(
            email=original_request['customer_email'],
            product_id=original_request['product_id'],
            transaction_id=transaction_id
        )

        return {"status": "processed"}, 200

    return {"status": "ignored"}, 200

Webhooks eliminate polling latency and reduce your bot's computational overhead.


FAQ

Q1: What if the customer doesn't complete payment?

Payment requests expire after 15 minutes. Your bot can remind the customer or cancel and create a new request. No funds are held, so no refunds needed.

Q2: Can I refund a customer?

Yes—initiate a refund via your bank's API. Since the money goes directly to your account, refunds are your responsibility (not AgentPay's). AgentPay just confirms the receipt; it doesn't hold or mediate funds.

Q3: Does AgentPay work with international customers?

VietQR is Vietnam-only (requires a Vietnamese bank account). For international payments, layer a secondary gateway (Stripe, PayPal). AgentPay stays focused on domestic VietQR transactions.

Q4: What if settlement fails or takes a long time?

Rare—VietQR settlements are typically instant. If a customer's payment fails, they see an error in their bank app. Your bot receives a failed status from the settlement check and prompts them to try again or choose a different product.


Key Takeaways


Get Started Today

Your AI chatbot can sell digital products right now without the payment processing nightmare. AgentPay VN handles the complexity; you handle the customer.

Install AgentPay VN:

pip install agentpay-vn

Read the full docs and API reference: https://agentpay.servicesai.vn/v1/docs

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

Start building your payment-aware AI agent. The next step is yours.

Get started →

← All posts