Skip to main content

AgentPay VN

PyPI version License: MIT MCP Registry phuocdu/agentpay-vn MCP server

VietQR payment infrastructure for AI agents — collect money inside any conversation.

AgentPay VN lets AI agents (Claude, GPT, custom bots) generate payment QR codes, send them to users, and automatically confirm when the money arrives — all without ever holding or touching funds. Money flows directly from the payer's bank account into the merchant's account; AgentPay only reads the bank transaction feed to confirm settlement.

Status: Early access / self-hosted — running on the same swarm as Sổ Nợ AI.


How it works

AI Agent                   AgentPay API              Bank feed (SePay)
   |                            |                           |
   |-- create_payment_request ->|                           |
   |<- { qr_image_url, id } ----|                           |
   |                            |                           |
   |-- send QR to user -------->|                           |
   |                            |      user scans & pays    |
   |                            |<-- webhook (bank txn) ----|
   |                            |-- match AP* pay_code      |
   |                            |-- status → settled        |
   |<-- await_settlement done --|                           |
   |                            |                           |
   |-- deliver order / unlock ->|                           |
  1. Create — agent calls POST /v1/payment-requests → gets a VietQR image URL and a checkout page.
  2. Send — agent embeds the QR image or sends the checkout link to the user in chat.
  3. Await — agent calls await_settlement() (or the MCP tool) to poll until status = settled.
  4. Deliver — only after confirmed settlement does the agent release the goods/service.

AgentPay never holds money. The QR points directly at the merchant's bank account number. The platform only monitors the bank transaction feed to detect matching transfers.


Quick start

1. Install

pip install agentpay-vn

2. Get an API key — no account needed

A sandbox key is self-serve and instant:

curl -X POST https://agentpay.servicesai.vn/v1/sandbox/register \
  -H "Content-Type: application/json" -d '{"shop_name": "My Bot"}'
# -> { "api_key": "ap_test_...", "expires_at": "..." }

export AGENTPAY_API_KEY=ap_test_xxx

From Python: register_sandbox(). From an agent: just call the register_sandbox MCP tool — it issues the key and applies it to the session.

Sandbox keys last 7 days, move no real money, and renew by calling the same endpoint with the same email. For real payments you need an ap_live_* key, which requires a registered merchant with a Vietnamese bank account — sign up at agentpay.servicesai.vn.

3. Collect a payment (3 lines)

from agentpay.client import AsyncAgentPayClient, await_settlement
import asyncio

async def main():
    async with AsyncAgentPayClient("ap_test_xxx") as client:
        pr = await client.create_payment_request(amount=50_000, description="Order #1")
        print(pr["checkout_url"])          # send this link to your user
        result = await await_settlement(client, pr["id"], timeout=120)
        assert result["status"] == "settled"

asyncio.run(main())

See examples/quickstart.py for the full runnable version.


MCP server setup

AgentPay ships an MCP server so any MCP-compatible AI agent can call it as a tool — no extra code needed.

Claude Desktop / Claude Code

Add to claude_desktop_config.json (or use examples/claude_desktop_config.json):

{
  "mcpServers": {
    "agentpay": {
      "command": "python",
      "args": ["-m", "agentpay.mcp_server"],
      "env": {
        "AGENTPAY_API_KEY": "ap_test_xxx",
        "AGENTPAY_BASE_URL": "https://agentpay.servicesai.vn/v1"
      }
    }
  }
}

Or use the installed console script:

{
  "mcpServers": {
    "agentpay": {
      "command": "agentpay-mcp",
      "env": { "AGENTPAY_API_KEY": "ap_live_xxx" }
    }
  }
}

Available MCP tools

Tool Description
register_sandbox Self-issue a free ap_test_* key — call this first when no key is set
create_payment_request Generate a VietQR code for a given amount
check_payment Get current status of a payment request
await_settlement Poll until payment arrives or timeout (max 600 s)
list_recent_payments List last N settled transactions

Agent skill (Claude Code, Cursor, and other agents)

The MCP server gives an agent the tools. The bundled skill gives it the judgement: when to charge, how to format a VND amount, and the rule that nothing ships before status = settled. See skills/agentpay-vn/SKILL.md.

This repository is also a Claude Code plugin marketplace, so the skill and the MCP server install together in one step:

claude plugin marketplace add phuocdu/agentpay-vn
claude plugin install agentpay-vn@agentpay-vn

Claude Code prompts for your API key (stored in the OS credential store, not in settings.json). Leave it blank to start in sandbox — the agent will call register_sandbox on its first charge.

For other agents, copy skills/agentpay-vn/ into wherever that agent reads skills from, and add the MCP server as shown above.


Python SDK

Synchronous

from agentpay.client import AgentPayClient

with AgentPayClient("ap_live_xxx") as client:
    # Create
    pr = client.create_payment_request(
        amount=150_000,
        description="Consulting session 30 min",
        ttl_minutes=30,
        idempotency_key="session-abc-123",
    )

    # Poll manually
    import time
    for _ in range(60):
        pr = client.get_payment_request(pr["id"])
        if pr["status"] != "pending":
            break
        time.sleep(5)

    # Reconcile
    txns = client.list_transactions(limit=10)

Asynchronous

from agentpay.client import AsyncAgentPayClient, await_settlement

async with AsyncAgentPayClient("ap_live_xxx") as client:
    pr = await client.create_payment_request(amount=75_000, description="eBook download")
    result = await await_settlement(client, pr["id"], timeout=300)
    if result["status"] == "settled":
        send_download_link(result["metadata"].get("email"))

Webhook verification

import hashlib, hmac

def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Register a webhook endpoint:

ep = client.register_webhook(
    url="https://your-server.com/webhooks/agentpay",
    events=["payment.settled", "payment.expired"],
)
print(ep["secret"])  # store this — shown only once

API reference

  • OpenAPI spec: agentpay-openapi.yaml
  • Base URL: https://agentpay.servicesai.vn/v1
  • Authentication: Authorization: Bearer ap_live_xxx (or ap_test_xxx for sandbox)

Key endpoints

Method Path Description
POST /v1/payment-requests Create payment request
GET /v1/payment-requests/{id} Get status
POST /v1/payment-requests/{id}/cancel Cancel pending request
GET /v1/transactions List settled transactions
POST /v1/webhook-endpoints Register webhook URL
POST /v1/sandbox/simulate-settlement Simulate payment (sandbox only)
GET /pay/{pay_code} Public checkout page (HTML, mobile-friendly)

Self-hosting

AgentPay runs as part of the Sổ Nợ AI FastAPI backend.

Requirements

  • Docker Swarm cluster (same as Sono)
  • MongoDB (shared with Sono)
  • SePay bank feed account (for live payments)
  • Nginx with an agentpay.servicesai.vn vhost

Environment variables

Variable Default Description
AGENTPAY_BASE_URL https://agentpay.servicesai.vn Public base URL for checkout links
MONGO_URI mongodb://localhost:27017 Inherited from Sono
BILLING_WEBHOOK_TOKEN — SePay webhook token (inherited)

Create an API key (admin)

curl -X POST https://sono.servicesai.vn/api/admin/agentpay/keys \
  -H "Authorization: Bearer <admin-jwt>" \
  -H "Content-Type: application/json" \
  -d '{"org_id": "<shop-user-id>", "name": "My bot", "livemode": true}'

The response includes the full key — store it immediately; it is shown only once.


Rate limits

Tier Settled payments/month Requests/minute
Free 50 120

Design principles

  1. No money held — QR codes point directly at the merchant's bank account. AgentPay only reads the transaction feed; it never touches the money.

  2. Idempotency — pass an Idempotency-Key header on POST /payment-requests to safely retry without creating duplicates (24-hour deduplication window).

  3. HMAC webhook verification — every outbound webhook is signed with HMAC-SHA256(whsec_..., raw_body) in the AgentPay-Signature header. Always verify before processing.

  4. Sandbox — use ap_test_* keys and POST /v1/sandbox/simulate-settlement to develop and test without real transactions.

  5. Minimal trust surface — the MCP server is a thin REST client with no local secrets beyond the API key. Compromising an agent key only exposes one tenant's payment-request creation ability.


License

MIT © 2026 ServicesAI — see LICENSE.

Metadata

Release files for agentpay-vn 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agentpay-vn 1.1.0
File Size Uploaded Provenance
agentpay_vn-1.1.0.tar.gz 21.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agentpay-vn 1.1.0
File Interpreter ABI Platform
agentpay_vn-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.8 kB

Release files / agentpay_vn-1.1.0.tar.gz

Download URL agentpay_vn-1.1.0.tar.gz
Size 21.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4321f850aca6b9baacb2e42c3752857d4fceba146053c51127df0abc6bf1547a
BLAKE2b-256 checksum
How to use checksums
a8effeeb937cdb76a4d957c469143c65be938ba656b352c14d1a0b1012ee3c13
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / agentpay_vn-1.1.0-py3-none-any.whl

Download URL agentpay_vn-1.1.0-py3-none-any.whl
Size 13.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
30aca7cb5377c56ec51777e878d1880068a3a5d989b06cd2fb34a13606e66158
BLAKE2b-256 checksum
How to use checksums
8fbd6df6be8cfdd5ea3920675875418c6ff223b8e095731018e5ab40d09b0214
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Security for agentpay-vn 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page