payments-mcp
MCP Server (Model Context Protocol) para centralizar integrações de pagamento:
- Pagar.me (Core API v5): customers, recipients, Pix, cartão, split 100%, charges, captura/cancelamento, tokenização (card_token)
- Woovi/OpenPix: charges Pix, consulta/listagem, deleção, refunds, verificação de webhook (HMAC)
O servidor expõe tools MCP para serem chamadas por um client MCP (ex: um agente/LLM), via stdio (padrão) ou MCP over HTTP (opcional).
Licença
MIT - Veja: ./LICENSE.
Stack e arquitetura
- Node.js + TypeScript
- MCP TypeScript SDK (
@modelcontextprotocol/sdk) usando oMcpServer(high-level) comregisterToole schemas Zod. - Zod para validação de entrada
- Axios para Woovi/OpenPix
- SDK oficial Pagar.me
@pagarme/pagarme-nodejs-sdk - Express (opcional): para expor MCP over HTTP (
/mcp) viaStreamableHTTPServerTransport
Estrutura de pastas (clean, por domínio):
src/index.ts: bootstrap do MCP server (stdio)src/http/server.ts: transport HTTP opcional (MCP over HTTP)src/mcp/server.ts: factory de criação doMcpServer(tools registradas)src/tools/register.ts: registry central de toolssrc/mcp/utils.ts: helpers de resposta/erro (ok,fail)src/integrations/pagarme/*: client, schemas e tools Pagar.mesrc/integrations/woovi/*: client, schemas e tools Woovi/OpenPix
Requisitos
- Node.js 18+ (recomendado) / npm
- Credenciais de Pagar.me e/ou Woovi/OpenPix
Instalação
npm install
Build:
npm run build
Rodar (stdio):
npm start
Dev:
npm run dev
Observação: o build sempre limpa
dist/antes de compilar.
Variáveis de ambiente
Crie um .env na raiz (ou exporte no ambiente):
Copie o template:
cp env.example .env
Pagar.me
PAGARME_API_KEY(obrigatória): usada como Basic Auth username (password vazio)PAGARME_PUBLIC_KEY(opcional, mas recomendado): necessária parapagarme_create_card_token/pagarme_get_token
Woovi/OpenPix
WOOVI_APP_ID(obrigatória): headerAuthorization(AppID)WOOVI_BASE_URL(opcional):- produção:
https://api.openpix.com.br/api/v1(default) - sandbox:
https://api.woovi-sandbox.com/api/v1
- produção:
Modos de execução (MCP)
MCP via stdio (local)
Modo padrão (ex: Cursor). O client MCP executa este processo e conversa via stdin/stdout.
MCP over HTTP (opcional)
Se você definir MCP_HTTP_PORT, o servidor também expõe MCP via HTTP (Streamable HTTP).
Exemplo:
export MCP_HTTP_PORT=3001
npm start
Endpoints:
GET /healthPOST /mcp(protocolo MCP)GET /mcp(protocolo MCP, com sessão)DELETE /mcp(protocolo MCP, com sessão)
Importante: isso é MCP over HTTP, não é uma REST API para o frontend.
Para usar via HTTP, utilize um client MCP HTTP (ex:
StreamableHTTPClientTransport). O servidor usa sessões via headermcp-session-id(o client gerencia isso automaticamente).
Exemplo (TypeScript) de client MCP HTTP:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "my-client", version: "1.0.0" });
const transport = new StreamableHTTPClientTransport(new URL("http://localhost:3001/mcp"));
await client.connect(transport);
// Agora você pode listar/callar tools via MCP
Rodar com Docker
Build da imagem
docker build -t payments-mcp:local .
Subir como serviço (MCP over HTTP)
Opção 1 (docker run):
docker run --rm -p 3001:3001 --env-file .env -e MCP_HTTP_PORT=3001 payments-mcp:local
Opção 2 (docker compose):
docker compose up --build
Health check:
curl -s http://localhost:3001/health
Rodar E2E dentro do container
Smoke:
docker run --rm --env-file .env payments-mcp:local npm run e2e:smoke
Full:
docker run --rm --env-file .env payments-mcp:local npm run e2e
Pagar.me — funcionalidades (tools MCP)
Customers
pagarme_create_customerpagarme_get_customerpagarme_update_customer_metadata
Recipients (personal)
pagarme_create_recipientpagarme_update_recipient_default_bank_accountpagarme_get_recipients
Orders / Pix / Cartão (split 100%)
pagarme_get_orderpagarme_create_order_pix_splitpagarme_create_order_credit_card_split
Split 100%:
- O recipient (personal) recebe 100% do valor do pedido e arcará com as taxas (configurado como
liable=trueechargeProcessingFee=trueno split do payment).
Charges
pagarme_get_chargepagarme_get_charge_transactions(útil para Pix — QRCode vem das transações)pagarme_capture_charge(quando cartão foi criado comcapture=false)pagarme_cancel_charge
Tokenização (cartão)
pagarme_create_card_token(usaPAGARME_PUBLIC_KEYoupublicKeyno payload)pagarme_get_token
Woovi/OpenPix — funcionalidades (tools MCP)
As tools foram implementadas seguindo a documentação do OpenPix (Woovi), incluindo:
Charges (Pix)
woovi_create_charge(POST/api/v1/charge)woovi_get_charge(GET/api/v1/charge/{id})woovi_list_charges(GET/api/v1/chargecom filtros)woovi_delete_charge(DELETE/api/v1/charge/{id})
Saída “pronta para FrontEnd”:
As tools woovi_create_charge e woovi_get_charge retornam um objeto normalizado com:
charge.brCodecharge.qrCodeImagecharge.paymentLinkUrlcharge.expiresDatecharge.status- e
rawcom o payload integral da API
Refunds
woovi_create_refund(POST/api/v1/refund)woovi_list_refunds(GET/api/v1/refund)woovi_get_refund(GET/api/v1/refund/{id})woovi_get_charge_refunds(GET/api/v1/charge/{id}/refund)woovi_create_charge_refund(POST/api/v1/charge/{id}/refund)
Webhook
woovi_verify_webhook_hmac: valida HMAC do webhook usandosha1+ base64 e o headerX-OpenPix-Signature.
Fluxos recomendados
Pix via Pagar.me (preferência atual)
- (opcional)
pagarme_create_customer(aluno) pagarme_create_recipient(personal)pagarme_create_order_pix_split→ retornachargeIdepix.qrCode/qrCodeUrl/expiresAt- Polling de status com
pagarme_get_charge/pagarme_get_order
Pix via Woovi/OpenPix (alternativo)
woovi_create_charge→ retornacharge.brCode,charge.qrCodeImage,charge.paymentLinkUrlwoovi_get_charge/woovi_list_charges→ acompanhar status- Se precisar estornar:
woovi_create_refund(comtransactionEndToEndId)
Cartão via Pagar.me
- (opcional)
pagarme_create_card_token→ obtémcard_token pagarme_create_order_credit_card_split(usacardTokenoucardId)- Se
capture=false:pagarme_capture_charge - Cancelamento/estorno:
pagarme_cancel_charge
Exemplos de payloads (copiar/colar)
Pagar.me — Pix + split 100%
{
"recipientId": "rp_xxxxxxxxxx",
"items": [
{ "amount": 15000, "description": "Mensalidade", "quantity": 1 }
],
"customer": {
"name": "Aluno Exemplo",
"email": "aluno@exemplo.com",
"document": "98765432100",
"type": "individual",
"address": {
"street": "Rua Exemplo",
"number": "100",
"zipCode": "01001000",
"neighborhood": "Centro",
"city": "São Paulo",
"state": "SP",
"country": "BR"
}
},
"pix": { "expiresIn": 3600 },
"idempotencyKey": "order-pix-pay_001"
}
Pagar.me — tokenização (card_token)
{
"publicKey": "pk_xxxxxxxxxx",
"card": {
"number": "4111111111111111",
"holderName": "ALUNO EXEMPLO",
"expMonth": 12,
"expYear": 2030,
"cvv": "123",
"brand": "visa",
"label": "Blah"
},
"idempotencyKey": "token-stu_123"
}
Pagar.me — Cartão + split 100%
{
"recipientId": "rp_xxxxxxxxxx",
"items": [
{ "amount": 15000, "description": "Mensalidade", "quantity": 1 }
],
"customer": {
"name": "Aluno Exemplo",
"email": "aluno@exemplo.com",
"document": "98765432100",
"type": "individual",
"address": {
"street": "Rua Exemplo",
"number": "100",
"zipCode": "01001000",
"neighborhood": "Centro",
"city": "São Paulo",
"state": "SP",
"country": "BR"
}
},
"creditCard": {
"capture": true,
"installments": 1,
"statementDescriptor": "Blah",
"cardToken": "card_tok_xxx"
},
"idempotencyKey": "order-cc-pay_002"
}
Woovi/OpenPix — criar charge Pix
{
"correlationID": "pay_123",
"value": 15000,
"comment": "Mensalidade",
"customer": {
"name": "Aluno Exemplo",
"email": "aluno@exemplo.com",
"phone": "+5511999999999",
"taxID": "471.737.080-52"
}
}
Woovi/OpenPix — refund
{
"transactionEndToEndId": "E1234567...",
"correlationID": "refund_pay_123",
"value": 15000,
"comment": "Estorno"
}
Woovi/OpenPix — validar webhook (HMAC)
{
"secret": "hmac-secret-key",
"signature": "jgR2XF0PKDiAwHP1s+TryvxMySQ=",
"body": "{\"event\":\"OPENPIX:CHARGE_COMPLETED\"}"
}
Referências (Context7)
- OpenPix/Woovi — charges/refunds/webhook HMAC:
developers_openpix_br(docs emapi.mdedocs/webhook/seguranca/webhook-hmac.md) - Pagar.me — SDK Node:
pagarme/pagarme-nodejs-sdk - MCP TypeScript SDK:
modelcontextprotocol/typescript-sdk
Autor
Luiz Pillon.