# Mcp Ezpay Einvoice

> MCP Server for Taiwan's ezPay E-Invoice API — 7 AI-callable tools for invoice issuance (B2B/B2C), voiding, allowances, and querying via Model Context Protocol

- **Type:** MCP server
- **Install:** `agentstack add mcp-asgard-ai-platform-mcp-ezpay-einvoice`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [asgard-ai-platform](https://agentstack.voostack.com/s/asgard-ai-platform)
- **Installs:** 0
- **Category:** [Finance & Payments](https://agentstack.voostack.com/c/finance-and-payments)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [asgard-ai-platform](https://github.com/asgard-ai-platform)
- **Source:** https://github.com/asgard-ai-platform/mcp-ezpay-einvoice
- **Website:** https://inv.ezpay.com.tw/

## Install

```sh
agentstack add mcp-asgard-ai-platform-mcp-ezpay-einvoice
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# mcp-ezpay-einvoice

**MCP Server for Taiwan's ezPay E-Invoice API**

[](https://pypi.org/project/mcp-ezpay-einvoice/)
[](https://pypi.org/project/mcp-ezpay-einvoice/)
[](https://opensource.org/licenses/MIT)
[](https://modelcontextprotocol.io/)
[](https://github.com/asgard-ai-platform/mcp-ezpay-einvoice/stargazers)
[](https://github.com/asgard-ai-platform/mcp-ezpay-einvoice/issues)
[](https://github.com/asgard-ai-platform/mcp-ezpay-einvoice/commits/main)

[Traditional Chinese (繁體中文)](README.zh-TW.md)

---

## Overview

An MCP (Model Context Protocol) server that exposes 7 AI-callable tools for the full Taiwan e-invoice lifecycle through the [ezPay](https://www.ezpay.com.tw/) platform. Covers invoice issuance (B2B/B2C), triggering, voiding, allowances (credit notes/refunds), and querying -- all accessible to AI assistants like Claude via the standard MCP protocol.

Part of the [Asgard AI Platform](https://github.com/asgard-ai-platform) open-source ecosystem.

## Features

- **issue_invoice** -- Issue B2B (business) or B2C (individual) e-invoices with full item detail, tax types, carriers, and donation codes
- **trigger_invoice** -- Trigger deferred or scheduled invoices for immediate issuance
- **void_invoice** -- Void issued invoices within the allowed reporting period
- **issue_allowance** -- Issue allowances (credit notes / partial refunds) against existing invoices
- **trigger_allowance** -- Confirm or cancel pending allowances
- **void_allowance** -- Void confirmed allowances
- **query_invoice** -- Query invoice details by invoice number or order number
- **AES-256-CBC encryption** -- Implements the ezPay encrypted form POST protocol (URL-encode, PKCS7 pad, AES encrypt, hex encode)
- **CheckCode verification** -- SHA-256 based response validation
- **Dual environment** -- Supports both test (`cinv.ezpay.com.tw`) and production (`inv.ezpay.com.tw`) environments

## Prerequisites

- Python 3.10 or higher
- An ezPay merchant account with API credentials (MerchantID, HashKey, HashIV)
  - Test environment: register at https://cinv.ezpay.com.tw/
  - Production environment: register at https://inv.ezpay.com.tw/

## Installation

### Option 1: Install from PyPI

```bash
pip install mcp-ezpay-einvoice
```

Or with [uv](https://github.com/astral-sh/uv):

```bash
uv pip install mcp-ezpay-einvoice
```

### Option 2: Run directly with uvx (no install needed)

```bash
EZPAY_MERCHANT_ID=your_id EZPAY_HASH_KEY=your_key EZPAY_HASH_IV=your_iv \
  uvx mcp-ezpay-einvoice
```

### Option 3: Install from source

```bash
git clone https://github.com/asgard-ai-platform/mcp-ezpay-einvoice.git
cd mcp-ezpay-einvoice
uv venv && source .venv/bin/activate
uv pip install -e .
```

## Configuration

Set the following environment variables before running the server:

| Environment Variable | Required | Description |
|---------------------|----------|-------------|
| `EZPAY_MERCHANT_ID` | Yes | Your ezPay merchant ID |
| `EZPAY_HASH_KEY` | Yes | AES-256 encryption key (32 chars) |
| `EZPAY_HASH_IV` | Yes | AES-CBC initialization vector (16 chars) |
| `EZPAY_IS_PRODUCTION` | No | Set to `true` for production. Defaults to `false` (test environment) |

You can also copy the `.env.example` file to `.env` and fill in your values:

```bash
cp .env.example .env
```

## Usage

### Claude Desktop

Add the following to your `claude_desktop_config.json`:

**Using uvx (recommended -- no manual install needed):**

```json
{
  "mcpServers": {
    "ezpay-einvoice": {
      "command": "uvx",
      "args": ["mcp-ezpay-einvoice"],
      "env": {
        "EZPAY_MERCHANT_ID": "your_merchant_id",
        "EZPAY_HASH_KEY": "your_hash_key",
        "EZPAY_HASH_IV": "your_hash_iv",
        "EZPAY_IS_PRODUCTION": "false"
      }
    }
  }
}
```

**Using pip install:**

```json
{
  "mcpServers": {
    "ezpay-einvoice": {
      "command": "mcp-ezpay-einvoice",
      "env": {
        "EZPAY_MERCHANT_ID": "your_merchant_id",
        "EZPAY_HASH_KEY": "your_hash_key",
        "EZPAY_HASH_IV": "your_hash_iv",
        "EZPAY_IS_PRODUCTION": "false"
      }
    }
  }
}
```

### Claude Code

If you cloned the repo, the `.mcp.json` in the project root is auto-discovered by Claude Code. Just set the environment variables:

```bash
export EZPAY_MERCHANT_ID=your_merchant_id
export EZPAY_HASH_KEY=your_hash_key
export EZPAY_HASH_IV=your_hash_iv
```

Or add the server via CLI:

```bash
claude mcp add ezpay-einvoice -- uvx mcp-ezpay-einvoice
```

### Cursor / Windsurf

Add to your MCP settings (`.cursor/mcp.json` or equivalent):

```json
{
  "mcpServers": {
    "ezpay-einvoice": {
      "command": "uvx",
      "args": ["mcp-ezpay-einvoice"],
      "env": {
        "EZPAY_MERCHANT_ID": "your_merchant_id",
        "EZPAY_HASH_KEY": "your_hash_key",
        "EZPAY_HASH_IV": "your_hash_iv",
        "EZPAY_IS_PRODUCTION": "false"
      }
    }
  }
}
```

### Running Directly

```bash
# With environment variables
EZPAY_MERCHANT_ID=your_id EZPAY_HASH_KEY=your_key EZPAY_HASH_IV=your_iv \
  python mcp_server.py

# Or with uvx
EZPAY_MERCHANT_ID=your_id EZPAY_HASH_KEY=your_key EZPAY_HASH_IV=your_iv \
  uvx mcp-ezpay-einvoice
```

### Testing

```bash
# Validate credentials and connectivity
python scripts/auth/test_connection.py

# Run all 7 tool E2E tests
python tests/test_all_tools.py
```

## Usage Examples

Once the MCP server is running, an AI assistant (e.g. Claude) can call these tools on your behalf. Here are real-world scenarios showing what you say and how the AI responds.

---

### "Help me issue an invoice for a customer who bought a test product"

> **You:** 幫我開一張發票，客人買了一個測試商品 105 元含稅，要印紙本發票

**AI calls:**

```
issue_invoice(
  merchant_order_no = "ORDER20260404001",
  buyer_name        = "Test Buyer",
  category          = "B2C",
  tax_type          = "1",
  tax_rate          = 5,
  amt               = 100,
  tax_amt           = 5,
  total_amt         = 105,
  item_name         = "Test Product",
  item_count        = "1",
  item_unit         = "pc",
  item_price        = "105",
  item_amt          = "105",
  print_flag        = "Y",
  status            = "1",
)
```

**Result:** `SUCCESS` -- Invoice `TE00000000` issued, amount NT$105, random code `9393`. The response includes BarCode, QRcodeL, and QRcodeR for printing.

---

### "Issue a B2B invoice with the buyer's tax ID"

> **You:** 幫我開一張 B2B 發票給統編 54352706 的公司，品名是顧問服務費 10000 元加稅 500 元

**AI calls:**

```
issue_invoice(
  merchant_order_no = "B2B20260404001",
  buyer_name        = "範例科技股份有限公司",
  buyer_ubn         = "54352706",
  category          = "B2B",
  tax_type          = "1",
  tax_rate          = 5,
  amt               = 10000,
  tax_amt           = 500,
  total_amt         = 10500,
  item_name         = "顧問服務費",
  item_count        = "1",
  item_unit         = "式",
  item_price        = "10000",
  item_amt          = "10000",
  print_flag        = "Y",
  status            = "1",
)
```

**Result:** `SUCCESS` -- B2B invoice issued with buyer UBN `54352706`. The printed invoice includes BarCode and QR codes for tax reporting.

---

### "Issue a B2C invoice with phone barcode carrier"

> **You:** 客人要存手機條碼載具 /ABC1234，不印紙本，品項是拿鐵咖啡 2 杯 65 元、巧克力蛋糕 1 個 85 元

**AI calls:**

```
issue_invoice(
  merchant_order_no = "POS20260404001",
  buyer_name        = "顧客",
  category          = "B2C",
  carrier_type      = "0",
  carrier_num       = "/ABC1234",
  tax_type          = "1",
  tax_rate          = 5,
  amt               = 205,
  tax_amt           = 10,
  total_amt         = 215,
  item_name         = "拿鐵咖啡|巧克力蛋糕",
  item_count        = "2|1",
  item_unit         = "杯|個",
  item_price        = "65|85",
  item_amt          = "130|85",
  print_flag        = "N",
  status            = "1",
)
```

**Result:** `SUCCESS` -- Invoice stored to phone barcode carrier `/ABC1234`, no paper copy printed.

---

### "Query the invoice I just issued"

> **You:** 幫我查一下訂單 ORDER20260404001 的發票資料

**AI calls:**

```
query_invoice(
  search_type       = "1",
  merchant_order_no = "ORDER20260404001",
  total_amt         = 105,
)
```

**Result:** `SUCCESS` -- Returns full invoice details including invoice number `TE00000000`, buyer info, tax breakdown (Amt: 100, TaxAmt: 5, TotalAmt: 105), item details, invoice status (1=issued), upload status, BarCode, and QR codes.

---

### "I need to issue a refund for a returned item"

> **You:** 客人退了一杯拿鐵 65 元，幫我對發票 TE00000000 開折讓

**AI calls:**

```
issue_allowance(
  invoice_no        = "TE00000000",
  merchant_order_no = "ORDER20260404001",
  item_name         = "拿鐵咖啡",
  item_count        = "1",
  item_unit         = "杯",
  item_price        = "65",
  item_amt          = "65",
  item_tax_amt      = "3",
  total_amt         = 68,
  status            = "1",
)
```

**Result:** `SUCCESS` -- Allowance issued against invoice `TE00000000` for NT$68 (65 + 3 tax). The remaining invoice amount is updated accordingly.

---

### "Void that invoice -- it was issued by mistake"

> **You:** 發票 TE00000000 開錯了，幫我作廢，原因是誤開發票

**AI calls:**

```
void_invoice(
  invoice_number = "TE00000000",
  invalid_reason = "誤開發票",
)
```

**Result:** `SUCCESS` -- Invoice `TE00000000` voided. The platform will notify the buyer and upload the void record to the tax authority.

> **Note:** Invoices can only be voided before the 14th of the next odd month (e.g., invoices issued in March-April can be voided before May 14th).

---

### "Create a scheduled invoice for next week"

> **You:** 幫我建一張預約發票，預計 2026-04-10 開立，金額 1000 元含稅

**AI calls:**

```
issue_invoice(
  merchant_order_no  = "SCH20260404001",
  buyer_name         = "預約客戶",
  category           = "B2C",
  tax_type           = "1",
  tax_rate           = 5,
  amt                = 952,
  tax_amt            = 48,
  total_amt          = 1000,
  item_name          = "訂閱服務",
  item_count         = "1",
  item_unit          = "式",
  item_price         = "1000",
  item_amt           = "1000",
  print_flag         = "Y",
  status             = "3",
  create_status_time = "2026-04-10",
)
```

**Result:** `SUCCESS` -- Invoice data saved, scheduled to issue on 2026-04-10. If you need to issue it earlier, use `trigger_invoice` to trigger it immediately.

---

### "Trigger that scheduled invoice now"

> **You:** 預約發票 SCH20260404001 要提前開立，幫我觸發

**AI calls:**

```
trigger_invoice(
  invoice_trans_no  = "26040423034604894",
  merchant_order_no = "SCH20260404001",
  total_amt         = 1000,
)
```

**Result:** `SUCCESS` -- Scheduled invoice triggered and issued immediately. Invoice number and random code are returned.

## Tools Reference

| Tool | Description | Key Parameters |
|------|-------------|----------------|
| `issue_invoice` | Issue B2B/B2C e-invoice | `category`, `buyer_name`, `tax_type`, `amt`, `total_amt`, `item_name`, `item_count`, `item_price`, `print_flag` |
| `trigger_invoice` | Trigger deferred/scheduled invoice | `invoice_trans_no`, `merchant_order_no`, `total_amt` |
| `void_invoice` | Void an issued invoice | `invoice_number`, `invalid_reason` |
| `issue_allowance` | Issue allowance (credit note) | `invoice_no`, `item_name`, `item_count`, `item_price`, `total_amt` |
| `trigger_allowance` | Confirm or cancel pending allowance | `allowance_no`, `allowance_status` (`C`=confirm, `D`=cancel) |
| `void_allowance` | Void confirmed allowance | `allowance_no`, `invalid_reason` |
| `query_invoice` | Query invoice details | `search_type` (`0`=by invoice number, `1`=by order number) |

## Error Codes Reference

Common ezPay API response status codes:

| Status | Meaning |
|--------|---------|
| `SUCCESS` | Operation completed successfully |
| `LIB10001` | Merchant ID does not exist |
| `LIB10002` | Encryption verification failed |
| `LIB10003` | Timestamp has expired |
| `INV10001` | Duplicate merchant order number |
| `INV10003` | Invoice number does not exist |
| `INV20001` | Invoice has already been voided |
| `INV20002` | Invoice void period has passed |
| `ALW10001` | Allowance amount exceeds invoice amount |
| `ALW10002` | Allowance number does not exist |

For the complete error code list, refer to the [ezPay API documentation](https://inv.ezpay.com.tw/).

## Architecture

```
stdio (JSON-RPC 2.0)
  -> mcp_server.py           Entry point, side-effect import triggers tool registration
    -> app.py                FastMCP("mcp-ezpay-einvoice") singleton
      -> tools/invoice_tools.py    7 @mcp.tool() decorated functions
        -> connectors/ezpay_client.py   Encrypted form POST connector
          -> auth/ezpay_crypto.py       AES-256-CBC encrypt + CheckCode verify
            -> config/settings.py       Endpoints, URL builder, env var config
```

```
mcp-ezpay-einvoice/
|-- app.py                          # FastMCP server singleton
|-- mcp_server.py                   # Entry point (stdio transport)
|-- config/settings.py              # API endpoints, URL builder, credentials
|-- connectors/ezpay_client.py      # Encrypted form POST connector
|-- auth/ezpay_crypto.py            # AES-256-CBC encryption, CheckCode
|-- tools/invoice_tools.py          # 7 MCP tools (invoice + allowance lifecycle)
|-- tests/test_all_tools.py         # E2E test runner
|-- scripts/auth/test_connection.py # Connection and credential validator
|-- .mcp.json                       # Claude Code auto-discovery config
`-- .env.example                    # Environment variable template
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions and guidelines.

1. Fork the repository
2. Create a feature branch: `git checkout -b feat/your-feature`
3. Make changes and run tests
4. Submit a pull request

## License

MIT License -- see [LICENSE](LICENSE) for details.

## Part of the Asgard Ecosystem

This server is part of the Asgard AI Platform, connecting AI assistants to real-world services across e-commerce, finance, government data, and more. See the full [Asgard AI Platform](https://github.com/asgard-ai-platform).

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [asgard-ai-platform](https://github.com/asgard-ai-platform)
- **Source:** [asgard-ai-platform/mcp-ezpay-einvoice](https://github.com/asgard-ai-platform/mcp-ezpay-einvoice)
- **License:** MIT
- **Homepage:** https://inv.ezpay.com.tw/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-asgard-ai-platform-mcp-ezpay-einvoice
- Seller: https://agentstack.voostack.com/s/asgard-ai-platform
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
