{
  "markdown": "# AgentPay VN\n\n<!-- mcp-name: io.github.phuocdu/agentpay-vn -->\n\n[![PyPI version](https://img.shields.io/pypi/v/agentpay-vn?logo=pypi&logoColor=white)](https://pypi.org/project/agentpay-vn/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-listed-0098FF)](https://registry.modelcontextprotocol.io/v0/servers?search=agentpay-vn)\n[![phuocdu/agentpay-vn MCP server](https://glama.ai/mcp/servers/phuocdu/agentpay-vn/badges/score.svg)](https://glama.ai/mcp/servers/phuocdu/agentpay-vn)\n\n**VietQR payment infrastructure for AI agents — collect money inside any conversation.**\n\nAgentPay 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.\n\n> **Status:** Early access / self-hosted — running on the same swarm as [Sổ Nợ AI](https://sono.servicesai.vn).\n\n---\n\n## How it works\n\n```\nAI Agent                   AgentPay API              Bank feed (SePay)\n   |                            |                           |\n   |-- create_payment_request ->|                           |\n   |<- { qr_image_url, id } ----|                           |\n   |                            |                           |\n   |-- send QR to user -------->|                           |\n   |                            |      user scans & pays    |\n   |                            |<-- webhook (bank txn) ----|\n   |                            |-- match AP* pay_code      |\n   |                            |-- status → settled        |\n   |<-- await_settlement done --|                           |\n   |                            |                           |\n   |-- deliver order / unlock ->|                           |\n```\n\n1. **Create** — agent calls `POST /v1/payment-requests` → gets a VietQR image URL and a checkout page.\n2. **Send** — agent embeds the QR image or sends the checkout link to the user in chat.\n3. **Await** — agent calls `await_settlement()` (or the MCP tool) to poll until `status = settled`.\n4. **Deliver** — only after confirmed settlement does the agent release the goods/service.\n\n**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.\n\n---\n\n## Quick start\n\n### 1. Install\n\n```bash\npip install agentpay-vn\n```\n\n### 2. Set your API key\n\n```bash\nexport AGENTPAY_API_KEY=ap_test_xxx   # sandbox key for testing\n```\n\nGet a key from the admin dashboard (self-hosted) or contact the platform operator.\n\n### 3. Collect a payment (3 lines)\n\n```python\nfrom agentpay.client import AsyncAgentPayClient, await_settlement\nimport asyncio\n\nasync def main():\n    async with AsyncAgentPayClient(\"ap_test_xxx\") as client:\n        pr = await client.create_payment_request(amount=50_000, description=\"Order #1\")\n        print(pr[\"checkout_url\"])          # send this link to your user\n        result = await await_settlement(client, pr[\"id\"], timeout=120)\n        assert result[\"status\"] == \"settled\"\n\nasyncio.run(main())\n```\n\nSee [`examples/quickstart.py`](examples/quickstart.py) for the full runnable version.\n\n---\n\n## MCP server setup\n\nAgentPay ships an [MCP](https://modelcontextprotocol.io) server so any MCP-compatible AI agent can call it as a tool — no extra code needed.\n\n### Claude Desktop / Claude Code\n\nAdd to `claude_desktop_config.json` (or use [`examples/claude_desktop_config.json`](examples/claude_desktop_config.json)):\n\n```json\n{\n  \"mcpServers\": {\n    \"agentpay\": {\n      \"command\": \"python\",\n      \"args\": [\"-m\", \"agentpay.mcp_server\"],\n      \"env\": {\n        \"AGENTPAY_API_KEY\": \"ap_test_xxx\",\n        \"AGENTPAY_BASE_URL\": \"https://agentpay.servicesai.vn/v1\"\n      }\n    }\n  }\n}\n```\n\nOr use the installed console script:\n\n```json\n{\n  \"mcpServers\": {\n    \"agentpay\": {\n      \"command\": \"agentpay-mcp\",\n      \"env\": { \"AGENTPAY_API_KEY\": \"ap_live_xxx\" }\n    }\n  }\n}\n```\n\n### Available MCP tools\n\n| Tool | Description |\n|------|-------------|\n| `create_payment_request` | Generate a VietQR code for a given amount |\n| `check_payment` | Get current status of a payment request |\n| `await_settlement` | Poll until payment arrives or timeout (max 600 s) |\n| `list_recent_payments` | List last N settled transactions |\n\n---\n\n## Python SDK\n\n### Synchronous\n\n```python\nfrom agentpay.client import AgentPayClient\n\nwith AgentPayClient(\"ap_live_xxx\") as client:\n    # Create\n    pr = client.create_payment_request(\n        amount=150_000,\n        description=\"Consulting session 30 min\",\n        ttl_minutes=30,\n        idempotency_key=\"session-abc-123\",\n    )\n\n    # Poll manually\n    import time\n    for _ in range(60):\n        pr = client.get_payment_request(pr[\"id\"])\n        if pr[\"status\"] != \"pending\":\n            break\n        time.sleep(5)\n\n    # Reconcile\n    txns = client.list_transactions(limit=10)\n```\n\n### Asynchronous\n\n```python\nfrom agentpay.client import AsyncAgentPayClient, await_settlement\n\nasync with AsyncAgentPayClient(\"ap_live_xxx\") as client:\n    pr = await client.create_payment_request(amount=75_000, description=\"eBook download\")\n    result = await await_settlement(client, pr[\"id\"], timeout=300)\n    if result[\"status\"] == \"settled\":\n        send_download_link(result[\"metadata\"].get(\"email\"))\n```\n\n### Webhook verification\n\n```python\nimport hashlib, hmac\n\ndef verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:\n    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, signature_header)\n```\n\nRegister a webhook endpoint:\n\n```python\nep = client.register_webhook(\n    url=\"https://your-server.com/webhooks/agentpay\",\n    events=[\"payment.settled\", \"payment.expired\"],\n)\nprint(ep[\"secret\"])  # store this — shown only once\n```\n\n---\n\n## API reference\n\n- **OpenAPI spec:** [`agentpay-openapi.yaml`](agentpay-openapi.yaml)\n- **Base URL:** `https://agentpay.servicesai.vn/v1`\n- **Authentication:** `Authorization: Bearer ap_live_xxx` (or `ap_test_xxx` for sandbox)\n\n### Key endpoints\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `POST` | `/v1/payment-requests` | Create payment request |\n| `GET` | `/v1/payment-requests/{id}` | Get status |\n| `POST` | `/v1/payment-requests/{id}/cancel` | Cancel pending request |\n| `GET` | `/v1/transactions` | List settled transactions |\n| `POST` | `/v1/webhook-endpoints` | Register webhook URL |\n| `POST` | `/v1/sandbox/simulate-settlement` | Simulate payment (sandbox only) |\n| `GET` | `/pay/{pay_code}` | Public checkout page (HTML, mobile-friendly) |\n\n---\n\n## Self-hosting\n\nAgentPay runs as part of the [Sổ Nợ AI](https://sono.servicesai.vn) FastAPI backend.\n\n### Requirements\n\n- Docker Swarm cluster (same as Sono)\n- MongoDB (shared with Sono)\n- SePay bank feed account (for live payments)\n- Nginx with an `agentpay.servicesai.vn` vhost\n\n### Environment variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `AGENTPAY_BASE_URL` | `https://agentpay.servicesai.vn` | Public base URL for checkout links |\n| `MONGO_URI` | `mongodb://localhost:27017` | Inherited from Sono |\n| `BILLING_WEBHOOK_TOKEN` | — | SePay webhook token (inherited) |\n\n### Create an API key (admin)\n\n```bash\ncurl -X POST https://sono.servicesai.vn/api/admin/agentpay/keys \\\n  -H \"Authorization: Bearer <admin-jwt>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"org_id\": \"<shop-user-id>\", \"name\": \"My bot\", \"livemode\": true}'\n```\n\nThe response includes the full key — store it immediately; it is shown only once.\n\n---\n\n## Rate limits\n\n| Tier | Settled payments/month | Requests/minute |\n|------|----------------------|-----------------|\n| Free | 50 | 120 |\n\n---\n\n## Design principles\n\n1. **No money held** — QR codes point directly at the merchant's bank account.  AgentPay only reads the transaction feed; it never touches the money.\n\n2. **Idempotency** — pass an `Idempotency-Key` header on `POST /payment-requests` to safely retry without creating duplicates (24-hour deduplication window).\n\n3. **HMAC webhook verification** — every outbound webhook is signed with `HMAC-SHA256(whsec_..., raw_body)` in the `AgentPay-Signature` header.  Always verify before processing.\n\n4. **Sandbox** — use `ap_test_*` keys and `POST /v1/sandbox/simulate-settlement` to develop and test without real transactions.\n\n5. **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.\n\n---\n\n## License\n\nMIT © 2026 ServicesAI — see [LICENSE](LICENSE).\n",
  "bytes": 8830,
  "sha": "d86beaccb5e4de6121df71cb564deae07781f2ef1a87140806def8152bdea992",
  "repo_slug": "phuocdu/agentpay-vn",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_phuocdu_agentpay_vn_abe78437/readme"
}