Skip to main content
Glama
billing.ts6 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import { makeAbacatePayRequest } from "../http/api.js"; import { resolveApiKey } from "../utils/api-key.js"; import { formatHttpError } from "../utils/errors.js"; export function registerBillingTools(server: McpServer) { server.tool( "createBilling", "Cria uma nova cobrança no Abacate Pay", { frequency: z.enum(["ONE_TIME", "MULTIPLE_PAYMENTS"]).default("ONE_TIME").describe("Tipo de frequência da cobrança"), methods: z.array(z.enum(["PIX"])).default(["PIX"]).describe("Métodos de pagamento (atualmente apenas PIX)"), products: z.array(z.object({ externalId: z.string().describe("ID externo do produto"), name: z.string().describe("Nome do produto"), description: z.string().describe("Descrição do produto"), quantity: z.number().describe("Quantidade do produto"), price: z.number().describe("Preço unitário em centavos") })).describe("Lista de produtos"), returnUrl: z.string().url().describe("URL para redirecionar caso o cliente clique em 'Voltar'"), completionUrl: z.string().url().describe("URL para redirecionar quando o pagamento for concluído"), customerId: z.string().optional().describe("ID de um cliente já cadastrado (opcional)") }, async (params) => { const { frequency, methods, products, returnUrl, completionUrl, customerId } = params as any; const finalApiKey = resolveApiKey(); if (!finalApiKey) { return { content: [ { type: "text", text: "❌ Erro: API key é obrigatória. Configure via header HTTP ou configure globalmente via variável de ambiente ABACATE_PAY_API_KEY." } ] }; } const requestBody: any = { frequency, methods, products, returnUrl, completionUrl }; if (customerId) { requestBody.customerId = customerId; } const result = await makeAbacatePayRequest<any>("/billing/create", finalApiKey, { method: "POST", body: JSON.stringify(requestBody) }); if (result.error) { const errorMessage = formatHttpError(result.error); return { content: [ { type: "text", text: `Falha ao criar cobrança: ${errorMessage}` } ] }; } const data = result.data?.data; if (!data) { return { content: [ { type: "text", text: "Erro: Resposta inválida da API" } ] }; } const totalAmount = (data.amount / 100).toFixed(2); return { content: [ { type: "text", text: `Cobrança criada com sucesso! 🎉\n\n` + `📋 **Detalhes da Cobrança:**\n` + `• ID: ${data.id}\n` + `• Status: ${data.status}\n` + `• Valor Total: R$ ${totalAmount}\n` + `• Frequência: ${data.frequency}\n` + `• Métodos: ${data.methods.join(', ')}\n` + `• Produtos: ${data.products.length} item(s)\n\n` + `🔗 **Link de Pagamento:**\n${data.url}\n\n` + `${data.devMode ? '⚠️ Modo de desenvolvimento ativo' : '✅ Modo de produção'}` } ] }; } ); server.tool( "listBillings", "Lista todas as cobranças criadas no Abacate Pay", { }, async () => { const finalApiKey = resolveApiKey(); if (!finalApiKey) { return { content: [ { type: "text", text: "❌ Erro: API key é obrigatória. Configure via header HTTP ou configure globalmente via variável de ambiente ABACATE_PAY_API_KEY." } ] }; } const result = await makeAbacatePayRequest<any>("/billing/list", finalApiKey, { method: "GET" }); if (result.error) { const errorMessage = formatHttpError(result.error); return { content: [ { type: "text", text: `Falha ao listar cobranças: ${errorMessage}` } ] }; } if (!result.data?.data || result.data.data.length === 0) { return { content: [ { type: "text", text: "Nenhuma cobrança encontrada." } ] }; } const billingsList = result.data.data.map((billing: any, index: number) => { const amount = (billing.amount / 100).toFixed(2); const customer = billing.customer?.metadata; const statusEmojis: Record<string, string> = { 'PENDING': '⏳', 'PAID': '✅', 'EXPIRED': '⏰', 'CANCELLED': '❌', 'REFUNDED': '↩️' }; const statusEmoji = statusEmojis[billing.status] || '❓'; return `${index + 1}. ${statusEmoji} **${billing.status}** - R$ ${amount} 📋 ID: ${billing.id} 🔗 URL: ${billing.url} 📦 Produtos: ${billing.products.length} item(s) 👤 Cliente: ${customer?.name || 'N/A'} 📅 Frequência: ${billing.frequency} 💳 Métodos: ${billing.methods.join(', ')} ${billing.devMode ? '⚠️ Modo Dev' : '✅ Produção'}`; }).join('\n\n'); return { content: [ { type: "text", text: `📋 **Lista de Cobranças** (${result.data.data.length} encontrada(s)):\n\n${billingsList}` } ] }; } ); }

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/AbacatePay/abacatepay-mcp'

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