Skip to main content
Glama
phuocdu

agentpay-vn

by phuocdu

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.


Related MCP server: Lightning Enable MCP

Quick start

1. Install

pip install agentpay-vn

2. Set your API key

export AGENTPAY_API_KEY=ap_test_xxx   # sandbox key for testing

Get a key from the admin dashboard (self-hosted) or contact the platform operator.

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

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


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.

Available Tools

4 tools
await_settlementA

Wait for a payment request to be settled (polls on behalf of the agent).

Polls every 5 seconds until status != pending or the timeout is reached (maximum 600 s). Call this after sending the QR to the payer. If the timeout expires while still pending, ask the user whether to keep waiting or cancel.

Args: payment_request_id: The id returned by create_payment_request. timeout_seconds: How long to wait in seconds (10–600, default 180).

ParametersJSON Schema
NameRequiredDescriptionDefault
payment_request_idYes
timeout_secondsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Describes polling interval (every 5s), timeout (max 600s), and handling of timeout expiry. Lacks mention of error states or invalid IDs, but main behavior is transparent. No annotations provided, so description carries full burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Concise and well-structured: purpose sentence, behavioral paragraph, guidance sentence, then argument descriptions. No redundant or missing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Comprehensive for a polling tool: covers behavior, parameters, usage context, and timeout handling. Output schema exists, so return values need not be explained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Adds significant meaning beyond the schema: explains `payment_request_id` as returned by `create_payment_request` and provides range and default for `timeout_seconds`. Schema itself has no property descriptions (0% coverage).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the tool awaits settlement of a payment request via polling. Distinguishes from siblings like `check_payment` which likely only checks status without waiting.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: 'Call this after sending the QR to the payer' and advises on timeout behavior. Does not explicitly exclude use cases but context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_paymentA

Check the current status of a payment request.

Returns: One of: pending | settled | underpaid | expired | cancelled, along with the amount received so far. Only treat a payment as complete when status=settled.

ParametersJSON Schema
NameRequiredDescriptionDefault
payment_request_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so the description carries the burden. It discloses possible statuses (pending, settled, underpaid, expired, cancelled) and includes amount received. It advises when payment is considered complete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no fluff. The first sentence front-loads the purpose. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple check with output schema (though not shown), the description explains the possible statuses and the condition for completeness. It covers the essential behavioral context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%. The single parameter 'payment_request_id' has no additional explanation in the description beyond its name and type. The description does not compensate for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Check the current status of a payment request' with a specific verb and resource. It distinguishes from sibling tools like 'await_settlement' (waiting) and 'create_payment_request' (creation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: 'Only treat a payment as complete when status=settled.' While it doesn't explicitly list when not to use or alternatives, the sibling tool names imply usage boundaries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_payment_requestA

Create a VietQR payment request.

Args: amount: Amount in VND, minimum 1 000. description: Short description for the payer (e.g. "Order #123 — 2 kg coffee"). ttl_minutes: QR validity window in minutes (5–1 440, default 60). metadata_note: Internal note from the agent (order id, conversation id, etc.) — echoed back in webhook events.

Returns: id, pay_code, QR image URL, and checkout page URL. Send qr_image_url or checkout_url to the payer, then call await_settlement(id) to wait for the money to arrive.

ParametersJSON Schema
NameRequiredDescriptionDefault
amountYes
descriptionYes
ttl_minutesNo
metadata_noteNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It explains return values and the metadata_note echo behavior, but does not disclose side effects, idempotency, or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with Args, Returns, and workflow steps. It is slightly verbose but every sentence serves a purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the richness of the output schema (implied returns) and the workflow instruction, the description is largely complete. It could include more detail on error handling or validation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description compensates fully. It explains each parameter with constraints (amount min, description example, ttl_minutes range, metadata_note usage) and adds meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with 'Create a VietQR payment request,' which uses a specific verb and resource. It clearly distinguishes from sibling tools that settle, check, or list payments.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear workflow: create the request, then send the URL to the payer and call await_settlement. It does not explicitly state when not to use this tool, but the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_recent_paymentsB

List the most recently settled transactions (quick reconciliation).

Args: limit: Number of transactions to return (1–50, default 10).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description must disclose behaviors. Only mentions 'quick reconciliation' hinting at performance but does not state read-only nature, idempotency, or other traits. Minimal disclosure beyond the tool's name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely concise: two sentences with no extraneous words. Front-loaded with purpose, then parameter details. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, return values need not be described. However, lacks definition of 'recent' (timeframe), ordering, and filtering options. Adequate for a simple list but could provide more context for proper use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 0% coverage (no description in schema). Description adds meaning to the sole parameter: specifies range (1-50) and default (10), which is not in the schema (only type and default provided). Adds actionable constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'List the most recently settled transactions' - specific verb (list) and resource (recently settled transactions). Sibling tools like await_settlement, check_payment, and create_payment_request provide context that distinguishes this as a listing tool, though not explicitly called out in the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus siblings. Does not mention prerequisites, typical scenarios, or when not to use. Implies quick reconciliation but no explicit comparisons.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 4 tool updatesv1.0.1
    • First observedawait_settlement
    • First observedcheck_payment
    • First observedcreate_payment_request
    • First observedlist_recent_payments

TDQS

A3.9/5.0
Disambiguation5/5

Each tool has a distinct and clear purpose: creating a payment request, checking status, awaiting settlement, and listing recent payments. No two tools overlap in functionality, ensuring an agent can easily select the correct one.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern (create_payment_request, check_payment, await_settlement, list_recent_payments). The naming is predictable and unambiguous.

Tool Count4/5

Four tools is a reasonable number for a focused payment processing server. While it covers core operations, it is slightly lean; adding a cancel tool might improve completeness, but the count is appropriate.

Completeness4/5

The tool set covers the main lifecycle of a payment request: create, check, await, and list. Missing an explicit cancel/expire function, but the await tool handles timeouts gracefully. Minor gap, but overall sufficient for typical workflows.

Maintenance

ActivityStale
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/phuocdu/agentpay-vn'

If you have feedback or need assistance with the MCP directory API, please join our Discord server