Build a Paid MCP Server: Charge Users Inside Claude
The Problem: AI Agents Need Money Too
You've built a powerful Model Context Protocol (MCP) server. Maybe it's a research tool, a code generator, or a content analyzer. Claude's ecosystem loves it. Users are asking for it. But here's the friction:
How do you collect payment when Claude is orchestrating the entire interaction?
Traditional payment flows break the agent's autonomy. You can't redirect to Stripe's checkout and expect Claude to handle it gracefully. You need a payment solution that: - Works inside the Claude environment - Executes in milliseconds (no lengthy redirects) - Settles instantly to your bank account - Never touches your server's memory
That's exactly the problem AgentPay VN solves.
Why AgentPay VN Changes the Game
AgentPay VN is an open-source Python SDK (MIT license) + MCP server that lets AI agents collect VietQR payments—Vietnam's standardized QR payment format—without ever holding funds.
Here's what makes it different:
- Zero liability: Money flows directly from customer → merchant bank account. Your server never touches the funds.
- Bank-confirmed settlement: A bank feed verifies payment confirmation before your agent continues.
- AI-native: Designed to work with Claude's decision-making, not against it.
- Three-step flow:
create_payment_request→send_checkout_url→await_settlement. - Drop-in integration: Install with
pip install agentpay-vnand integrate in under 20 minutes.
Unlike Stripe or PayPal, there's no long-lived session state, no webhook complexity, and no redirect fatigue.
Architecture: How Payments Flow Through Claude
When Claude uses an AgentPay MCP server, here's what happens:
Claude Agent AgentPay MCP Server VietQR/Bank
| | |
|--[request payment]---------->| |
| |--[create QR code]------->|
|<--[checkout URL]-------------| |
| | |
|--(sends to user)------------>| (user scans QR) |
| | |
| |<--[payment received]-----|
|<--[await_settlement OK]------| |
| | |
|--(continues workflow)------->|
The agent never waits blindly. It polls the settlement status, and the bank feed confirms the money arrived. Only then does it proceed.
Getting Started: Installation & Setup
Step 1: Install the SDK
pip install agentpay-vn
Step 2: Set Your Bank Details
Create a .env file in your project:
# .env
MERCHANT_BANK_ACCOUNT=1234567890
MERCHANT_BANK_NAME=VietcomBank # or your Vietnamese bank
MERCHANT_NAME="Your Business Name"
AGENTPAY_API_KEY=your_api_key_here # from agentpay.servicesai.vn/v1/docs
Step 3: Start the MCP Server
agentpay-mcp
This boots a local server on http://localhost:3000 exposing AgentPay's tools to Claude.
Code Example 1: Basic Payment Request Flow
Here's a minimal Python script showing how to create and await a payment:
from agentpay_vn import PaymentClient
import asyncio
import os
# Initialize the client
client = PaymentClient(
api_key=os.getenv("AGENTPAY_API_KEY"),
merchant_bank="VietcomBank",
merchant_account="1234567890"
)
async def charge_user_for_premium_feature():
"""
Example: User wants to unlock a premium report.
Price: 50,000 VND (~$2 USD)
"""
# Step 1: Create a payment request
payment = await client.create_payment_request(
amount_vnd=50000,
description="Premium Report - Monthly Subscription",
customer_name="Nguyen Van A",
order_id="ORD_2024_001"
)
# Returns: { 'id': 'pay_abc123', 'checkout_url': 'https://...qr...', 'expires_at': '2024-...' }
print(f"Send this URL to customer: {payment['checkout_url']}")
# The customer receives a link with an embedded VietQR code.
# They scan it with their banking app and confirm payment.
# Step 2: Wait for settlement
# Poll every 2 seconds (bank feed updates within 10-30 seconds in Vietnam)
settlement = await client.await_settlement(
payment_id=payment['id'],
poll_interval_seconds=2,
max_wait_seconds=120
)
if settlement['status'] == 'confirmed':
print(f"✓ Payment received! {settlement['amount_vnd']} VND")
print(f" Settlement ref: {settlement['bank_ref']}")
# Money is now in your merchant account.
# Unlock the premium feature for this user.
return True
else:
print("✗ Payment timeout or cancelled.")
return False
# Run it
asyncio.run(charge_user_for_premium_feature())
Line-by-line explanation:
- create_payment_request(): Generates a unique VietQR code for this transaction. Returns a checkout URL and payment ID.
- await_settlement(): Polls the bank feed (via AgentPay's cloud relay) every 2 seconds. The bank confirms the money within 10–30 seconds. Once confirmed, you proceed.
- No redirect, no session, no webhook complexity.
Code Example 2: MCP Server Configuration for Claude
To expose AgentPay tools to Claude, configure your MCP server in Claude's config.json (or equivalent):
{
"mcpServers": {
"agentpay": {
"command": "agentpay-mcp",
"env": {
"AGENTPAY_API_KEY": "your_api_key",
"MERCHANT_BANK": "VietcomBank",
"MERCHANT_ACCOUNT": "1234567890",
"MERCHANT_NAME": "Your Shop"
}
}
}
}
Once configured, Claude gains access to three tools:
create_payment_request- Initiates a charge.get_payment_status- Checks if customer has paid (non-blocking).await_settlement- Blocks until payment confirmed (typically 10–30 seconds).
Claude automatically routes through these based on your agent's logic.
Real-World Example: Online Course Checkout Bot
Imagine you run an online Python course platform. A user messages Claude:
"I want to buy your 'Advanced Async Patterns' course."
Here's what Claude orchestrates:
1. Claude: "Great! That's 199,000 VND. Let me create a payment link."
→ Calls: create_payment_request(amount_vnd=199000, description="Advanced Async Patterns Course")
2. Claude: "Scan this QR code with your bank app to confirm."
→ Sends checkout_url to user
3. [User scans QR and confirms payment in their bank app: ~10 seconds]
4. Claude: [Non-blocking check] "Is payment confirmed?"
→ Calls: get_payment_status() → Returns: pending
5. Claude: [Waits] "Still processing..."
→ Calls: await_settlement() [polls internally]
6. [Bank feed confirms payment received]
7. Claude: "✓ Payment confirmed! Here's your course access link and login."
→ Sends enrollment credentials
Total time: 40–50 seconds. No page redirects. No session timeouts. No confusion.
Advanced Tips: Handling Edge Cases
Tip 1: Retry Logic for Network Blips
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
async def robust_await_settlement(client, payment_id):
return await client.await_settlement(payment_id, poll_interval_seconds=3)
If the bank feed is briefly unavailable, retry with exponential backoff.
Tip 2: Multi-Currency Pricing
VietQR is VND-only, but you can accept USD by converting at real-time rates:
import httpx
async def usd_to_vnd(usd_amount):
async with httpx.AsyncClient() as client:
r = await client.get("https://api.exchangerate-api.com/v4/latest/USD")
rate = r.json()["rates"]["VND"]
return int(usd_amount * rate)
usd_price = 10 # $10
vnd_price = await usd_to_vnd(usd_price) # ~250,000 VND
await agentpay.create_payment_request(amount_vnd=vnd_price, ...)
Tip 3: Timeout Handling
If a user abandons the QR code, your agent should gracefully exit:
try:
settlement = await client.await_settlement(
payment_id=payment['id'],
max_wait_seconds=300 # 5 minutes
)
except TimeoutError:
print("User didn't pay within 5 minutes. Cancelling order.")
await client.cancel_payment(payment['id'])
Do's and Don'ts
| Do | Don't |
|---|---|
| ✓ Create a new payment request per order. | ✗ Reuse payment IDs across customers. |
| ✓ Await settlement before unlocking access. | ✗ Trust get_payment_status() alone; always use await_settlement() for critical paths. |
✓ Store order_id in your DB for reconciliation. |
✗ Assume the transaction succeeded without bank confirmation. |
| ✓ Set reasonable timeouts (3–5 min). | ✗ Wait indefinitely; users may abandon payment. |
| ✓ Log settlement refs for support tickets. | ✗ Ignore the bank_ref field; it's your proof of payment. |
Deployment Checklist
Before going live:
- [ ] Test with a real VietQR bank account (AgentPay supports major Vietnamese banks).
- [ ] Set
.envvariables in your production environment (never hardcode API keys). - [ ] Use a queue (Redis, RabbitMQ) to decouple payment polling from Claude's main thread.
- [ ] Implement idempotency: if Claude retries, use the same
order_idto avoid duplicate charges. - [ ] Monitor bank feed latency; set alerts if confirmations exceed 60 seconds.
- [ ] Log all payment events to a database for PCI compliance and dispute resolution.
FAQ
Q: Does AgentPay hold customer money? No. The VietQR code directs payment straight to your bank account. AgentPay only relays the bank's settlement confirmation. You own the money immediately.
Q: What if the bank feed is delayed?
Vietnam's VietQR system typically confirms within 10–30 seconds. If you hit the timeout, gracefully ask the user to retry or contact support. AgentPay provides a bank_ref for manual reconciliation.
Q: Can I charge non-Vietnamese customers? VietQR is Vietnam-specific. Non-Vietnamese users must have a Vietnamese bank account to pay. If you need international support, consider pairing AgentPay with Stripe for non-VN users.
Q: Is my customer's banking data secure? Yes. AgentPay never stores banking credentials. VietQR is a standardized, bank-issued QR protocol with built-in encryption. Your server only sees the payment confirmation, not the customer's account details.
Key Takeaways
- AgentPay VN enables AI agents to collect real money without breaking the conversational flow.
- Three-step integration: install SDK, configure MCP, call three functions (
create_payment_request,get_payment_status,await_settlement). - Money goes straight to your bank; AgentPay is a relay only, removing liability and complexity.
- VietQR is instant: 10–30 second confirmation means users don't wait around.
- Perfect for: courses, reports, subscriptions, premium features, consultations—anything Claude offers that has value.
- Deployment is simple: single
.envfile, single MCP config, robust retry logic.
Next Steps
Ready to monetize your Claude agent?
- Install AgentPay VN:
pip install agentpay-vn - Read the full docs: https://agentpay.servicesai.vn/v1/docs
- Explore the source code: https://github.com/phuocdu/agentpay-vn
- Start the MCP server:
agentpay-mcp - Build your first paid agent and share it with us!
The future of AI commerce runs through agents. AgentPay VN is your bridge to revenue.