Ir para o conteúdo
Docs

Início rápido

Crie uma chave no painel, gere a primeira cobrança PIX e receba o webhook de pagamento.

Crie uma chave de API

No painel, abra Desenvolvedor › Credenciais e clique em Nova chave. Marque só as permissões que a integração usa e dê um nome que diga onde ela vai rodar, como “Checkout produção”.

O segredo começa com mxp_live_ e aparece uma única vez. Guarde no cofre de segredos ou numa variável de ambiente do seu servidor.

Variável de ambienteShell
export MAXXIPAY_API_KEY="mxp_live_…"

Crie a primeira cobrança

Envie o valor em centavos, uma descrição e os dados de quem paga. O cabeçalho Idempotency-Key garante que uma nova tentativa não crie uma segunda cobrança: use o identificador do pedido no seu sistema.

O campo externalId é opcional e guarda o seu identificador junto da cobrança, para conciliar depois e filtrar listas.

Exemplo de retorno, pelo contrato da rota. Não cria cobrança nem saque.

const response = await fetch("https://api.maxxipay.com/v1/charges", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MAXXIPAY_API_KEY}`,
    "Idempotency-Key": "pedido-1042",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    amountCents: 4990,
    description: "Pedido 1042",
    payerName: "Cliente Exemplo",
    payerDocument: "529.982.247-25",
    externalId: "pedido-1042",
    metadata: {
      canal: "checkout"
    }
  }),
});

const charge = await response.json();
RespostaJSON201 Created
{
  "id": "6f0c1a52-1d7e-4b8a-9f43-2c5e8d9b7a10",
  "object": "charge",
  "status": "pending",
  "amountCents": 4990,
  "feeCents": null,
  "netCents": null,
  "currency": "BRL",
  "description": "Pedido 1042",
  "payerName": "Cliente Exemplo",
  "payerDocument": "52998224725",
  "pixCopyPaste": "00020101021226870014br.gov.bcb.pix2565pix.exemplo.com.br/qr/v2/6f0c1a521d7e4b8a9f432c5e8d9b7a1052040000530398654044.905802BR6304B7C1",
  "pixQrCode": "iVBORw0KGgoAAAANSUhEUgAA…",
  "endToEndId": null,
  "externalId": "pedido-1042",
  "metadata": {
    "canal": "checkout"
  },
  "failureReason": null,
  "expiresAt": "2026-11-02T19:12:00.000Z",
  "paidAt": null,
  "createdAt": "2026-11-02T18:12:00.000Z",
  "updatedAt": "2026-11-02T18:12:00.000Z"
}

Mostre o PIX ao pagador

A resposta traz pixCopyPaste, o código PIX copia e cola, e pixQrCode, o PNG desse código em base64. Mostre o texto com um botão de copiar e a imagem direto em <img src="data:image/png;base64,...">.

A cobrança vale por 1 hora. O horário limite vem em expiresAt: depois dele o código não aceita pagamento.

Imagem do QR Code
const src = `data:image/png;base64,${charge.pixQrCode}`;
const html = `<img src="${src}" alt="QR Code PIX">`;

Receba o webhook

Em Desenvolvedor › Webhooks, clique em Novo endpoint, informe a URL https e escolha os eventos. O painel mostra um segredo whsec_ uma única vez: ele assina cada entrega.

Quando o pagador paga, a MaxxiPay envia charge.paid com a cobrança completa. Confira a assinatura do corpo bruto, responda 2xx em até 5 segundos e processe depois.

Corpo do webhookJSON
{
  "id": "charge.paid:6f0c1a52-1d7e-4b8a-9f43-2c5e8d9b7a10",
  "type": "charge.paid",
  "createdAt": "2026-11-02T18:13:41.000Z",
  "data": {
    "id": "6f0c1a52-1d7e-4b8a-9f43-2c5e8d9b7a10",
    "object": "charge",
    "status": "paid",
    "amountCents": 4990,
    "feeCents": 99,
    "netCents": 4891,
    "currency": "BRL",
    "description": "Pedido 1042",
    "payerName": "Cliente Exemplo",
    "payerDocument": "52998224725",
    "pixCopyPaste": "00020101021226870014br.gov.bcb.pix2565pix.exemplo.com.br/qr/v2/6f0c1a521d7e4b8a9f432c5e8d9b7a1052040000530398654044.905802BR6304B7C1",
    "pixQrCode": "iVBORw0KGgoAAAANSUhEUgAA…",
    "endToEndId": "E18236120202611021813s0a1b2c3d4e",
    "externalId": "pedido-1042",
    "metadata": {
      "canal": "checkout"
    },
    "failureReason": null,
    "expiresAt": "2026-11-02T19:12:00.000Z",
    "paidAt": "2026-11-02T18:13:41.000Z",
    "createdAt": "2026-11-02T18:12:00.000Z",
    "updatedAt": "2026-11-02T18:13:41.000Z"
  }
}
Verificação da assinatura
import crypto from "node:crypto";
import express from "express";

const app = express();
const secret = process.env.MAXXIPAY_WEBHOOK_SECRET;

function isValid(rawBody, timestamp, header) {
  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!Number.isFinite(age) || age > 300) return false;
  const signed = Buffer.concat([Buffer.from(timestamp + "."), rawBody]);
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(signed).digest("hex");
  const received = Buffer.from(header ?? "");
  const wanted = Buffer.from(expected);
  return received.length === wanted.length && crypto.timingSafeEqual(received, wanted);
}

app.post("/webhooks/maxxipay", express.raw({ type: "application/json" }), async (req, res) => {
  if (!isValid(req.body, req.get("x-maxxipay-timestamp") ?? "", req.get("x-maxxipay-signature"))) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(req.body.toString("utf8"));
  res.sendStatus(200);
  await processEvent(event);
});

Confira o pagamento

Com o webhook processado, a cobrança está paid, com feeCents, netCents e o endToEndId da transação. O valor líquido já entra no saldo disponível.

Próximos passos: veja os status possíveis, as boas práticas de webhook e como sacar o saldo.

Consultar a cobrança
const response = await fetch("https://api.maxxipay.com/v1/charges/6f0c1a52-1d7e-4b8a-9f43-2c5e8d9b7a10", {
  headers: {
    Authorization: `Bearer ${process.env.MAXXIPAY_API_KEY}`,
  },
});

const charge = await response.json();
esc