Wraps the entire Robokassa payment gateway for Russian e-commerce into 18 MCP tools. You get invoice generation with fiscal receipt support, payment status checks via OpStateExt, full refund workflows, card pre-authorization holds, recurring subscription charges, and webhook signature verification for both ResultURL and SuccessURL callbacks. It also exposes marketplace split payments, SMS services, and the Partner API refund path. The library side handles signature computation and JWT tokens for the three different password types Robokassa uses. Reach for this if you're building or debugging Robokassa integrations and want an AI agent that can check payment states, initiate refunds, or validate webhooks without writing boilerplate.
📚 Documentation · PyPI · Docker · MCP Registry
Comprehensive Python client and Model Context Protocol server for Robokassa — the Russian payment gateway.
Covers the full API surface: checkout, XML status interfaces, refunds, holding (pre-auth), recurring subscriptions, 54-ФЗ fiscal receipts, Partner API, and auxiliary endpoints.
# As an MCP server for Claude Desktop / Claude Code / Cursor / Windsurf
uvx robokassa-mcp
# As a Python library
pip install robokassa-mcp
import asyncio
from decimal import Decimal
from robokassa import create_invoice, RobokassaClient
# Build a signed checkout URL (no HTTP — just URL construction).
invoice = create_invoice(
merchant_login="my-shop",
out_sum=Decimal("599.00"),
inv_id=12345,
password1="...",
description="Premium subscription",
email="user@example.com",
)
print(invoice.url) # https://auth.robokassa.ru/Merchant/Index.aspx?...
# Check the state of a payment (hits the OpStateExt XML endpoint).
async def check() -> None:
async with RobokassaClient("my-shop", password2="...") as client:
state = await client.check_payment(inv_id=12345)
print(state.is_paid, state.info.op_key)
asyncio.run(check())
from robokassa import RobokassaClient
async def refund_flow(inv_id: int) -> None:
async with RobokassaClient("my-shop", password2="p2", password3="p3") as client:
# 1. Fetch the payment state to get its OpKey.
state = await client.check_payment(inv_id)
assert state.info.op_key, "payment not complete yet"
# 2. Initiate a refund.
created = await client.refund_create(state.info.op_key)
print("refund requestId:", created.request_id)
# 3. Poll status until finished / canceled.
while True:
status = await client.refund_status(created.request_id)
if status.is_terminal:
print("final:", status.state)
break
from fastapi import FastAPI, Request, HTTPException, PlainTextResponse
from robokassa import verify_result_signature, build_ok_response
app = FastAPI()
@app.post("/robokassa/result")
async def result_url(req: Request) -> PlainTextResponse:
form = dict(await req.form())
if not verify_result_signature(form, password2="..."):
raise HTTPException(status_code=403, detail="Bad signature")
# ... persist the notification, mark invoice paid ...
return PlainTextResponse(build_ok_response(form["InvId"]))
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}
claude mcp add robokassa \
-e ROBOKASSA_LOGIN=my-shop \
-e ROBOKASSA_PASSWORD1=... \
-e ROBOKASSA_PASSWORD2=... \
-e ROBOKASSA_PASSWORD3=... \
-- uvx robokassa-mcp
Edit ~/.cursor/mcp.json:
{
"mcpServers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}
In user or workspace settings.json:
{
"github.copilot.chat.mcp.servers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}
Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"robokassa": {
"command": "uvx",
"args": ["robokassa-mcp"],
"env": {
"ROBOKASSA_LOGIN": "your-shop-login",
"ROBOKASSA_PASSWORD1": "password1",
"ROBOKASSA_PASSWORD2": "password2",
"ROBOKASSA_PASSWORD3": "password3"
}
}
}
}
uvx robokassa-mcp --transport http --port 8000
Flags: --transport {stdio,http,streamable-http,sse}, --host, --port.
All 18 tools are wrapped as @mcp.tool() and available to any MCP-capable agent (Claude Desktop, Claude Code, Cursor, Windsurf, etc.).
| Tool | Purpose | Auth |
|---|---|---|
create_invoice | Build a signed checkout URL (optional 54-ФЗ receipt). | Password#1 |
check_payment | Get current state of a payment by InvId (via OpStateExt). | Password#2 |
list_currencies | List payment methods available to the shop. | — |
calc_out_sum | Compute amount credited to shop for a given payment. | Password#1 |
refund_create | Initiate a refund (requires Refund API access). | Password#3 JWT |
refund_status | Poll refund progress by requestId. | — |
verify_result_signature | Validate a ResultURL webhook. | Password#2 |
verify_success_signature | Validate a SuccessURL redirect. | Password#1 |
hold_init / hold_confirm / hold_cancel | Two-step card pre-authorization. | Password#1 |
init_recurring_parent / recurring_charge | Subscription auto-charges. | Password#1 |
build_split_invoice | Marketplace multi-recipient checkout. | — |
send_sms | Paid SMS service. | Password#1 |
second_receipt_create / second_receipt_status | 54-ФЗ final receipt after advance. | Password#1 |
partner_refund | Alternative refund path for partner integrators. | Partner JWT |
Low-level signature helpers are available from Python only: compute_signature, op_state_signature, build_checkout_signature, build_refund_jwt, build_sms_signature, compute_result_signature, compute_success_signature, encode_fiscal_body.
Mapped against the 8 public Robokassa API groups:
| Group | Coverage | Module |
|---|---|---|
| Merchant Checkout | ✅ create_invoice (+ 54-ФЗ) | robokassa.checkout |
| XML Interfaces | ✅ check_payment, list_currencies, calc_out_sum | robokassa.xml_interface |
| Refund API | ✅ refund_create, refund_status | robokassa.refund |
| Holding / Pre-auth | ✅ init / confirm / cancel | robokassa.holding |
| Recurring | ✅ parent + child | robokassa.recurring |
| Fiscal 54-ФЗ | ✅ second receipt create / status | robokassa.fiscal |
| Partner API | 🟡 partner_refund only — see coverage notes | robokassa.partner |
| Auxiliary | ✅ send_sms, webhook signatures, split payments | robokassa.sms, robokassa.webhooks, robokassa.split |
Most high-level entry points fall back to these env vars when credentials aren't passed explicitly:
| Variable | Required for |
|---|---|
ROBOKASSA_LOGIN | All operations |
ROBOKASSA_PASSWORD1 | Checkout, webhook SuccessURL verification, CalcOutSumm, fiscal, SMS |
ROBOKASSA_PASSWORD2 | check_payment (OpStateExt), webhook ResultURL verification |
ROBOKASSA_PASSWORD3 | refund_create |
All signature-producing helpers accept algorithm= with "md5" / "sha256" / "sha384" / "sha512" — match whatever is configured in your Robokassa cabinet.
git clone https://github.com/artgas1/robokassa-mcp.git
cd robokassa-mcp
uv sync --all-extras --dev
uv run pytest # 107+ unit tests
uv run ruff check .
uv run pyright
MIT — see LICENSE. Drop-and-forget maintenance; PRs welcome but not guaranteed to be reviewed promptly.
ROBOKASSA_LOGIN*Merchant login identifier for the Robokassa shop.
ROBOKASSA_PASSWORD1secretShop's Password #1 — used for checkout URL signing, SuccessURL signature verification, CalcOutSumm, fiscal receipts, and SMS.
ROBOKASSA_PASSWORD2secretShop's Password #2 — used for OpStateExt payment status checks and ResultURL signature verification.
ROBOKASSA_PASSWORD3secretShop's Password #3 — used for Refund API (JWT HS256). Refund API access must be enabled in the cabinet.
io.github.shelvick/shopify-subscription-reconciliation
zleventer/google-ads-mcp
csoai-org/meok-stripe-acp-checkout-mcp
io.github.mharnett/google-ads
csoai-org/stripe-billing-mcp
co.pipeboard/google-ads-mcp