royalpay.Docs

Visão Geral

A Royalpay é uma API de pagamentos para receber e enviar Pix de forma simples e segura. A plataforma oferece:

Receber Pagamentos (Cash-In)

Gere cobranças Pix com copia e cola e link de pagamento para os seus clientes.

Realizar Saques (Cash-Out)

Envie o seu saldo para qualquer chave Pix ou para uma carteira USDT (BEP20).

Webhooks em Tempo Real

Receba notificações assinadas quando uma cobrança ou um saque muda de status.

Versão da API
Esta documentação se refere à API v1. Todas as requisições devem ser feitas para o endpoint base: https://useroyalpay.com.br/api/v1
Limites e ambiente
  • Limite de 100 requisições por minuto por chave e 40 criações por minuto por conta. Acima disso a API responde 429.
  • Não há ambiente de testes (sandbox): toda chave opera com dinheiro real. Valide a integração com o valor mínimo de cobrança.
  • Valores são inteiros em centavos: 10000 = R$ 100,00.
  • Requisições e respostas usam application/json.

Primeiros passos

  1. Crie a conta e gere a chave. Crie sua conta e aguarde a aprovação. Depois, em Chaves de acesso, crie uma chave. Ela aparece uma vez só.
  2. Gere a primeira cobrança. Um Pix de R$ 10,00 com POST /payments. A resposta traz o copia e cola e um link de pagamento.
  3. Configure o webhook. Em Webhooks, cadastre a URL do seu sistema para saber na hora quando o Pix cair.

Exemplo de Requisição

curl -X POST 'https://useroyalpay.com.br/api/v1/payments' \
  -H 'Authorization: Bearer SUA_CHAVE' \
  -H 'Idempotency-Key: pedido-1001' \
  -H 'Content-Type: application/json' \
  -d '{
    "amountCents": 1000,
    "description": "Meu primeiro Pix"
  }'

Autenticação

Conceito

A API da Royalpay usa uma chave de acesso enviada no header Authorization em todas as chamadas. As chaves de produção começam com rp_live_.

Header
Authorization: Bearer SUA_CHAVE
Segurança
A chave nunca deve aparecer no front-end (navegador ou app). Use só no seu servidor.

Criar uma chave

No painel, abra Chaves de acesso e crie uma nova chave com um nome para reconhecê-la depois. Marque Permitir saques só se a integração for sacar: isso pede a sua senha e, com 2FA ativo, o código do app autenticador. A chave aparece uma única vez; se perder, revogue e crie outra.

Permissões

Uma chamada fora das permissões da chave responde 403.

PermissãoO que permiteNa chave
payments:readConsultar cobranças, saques, saldo e checkouts.Sempre
payments:writeCriar cobranças.Sempre
withdrawals:writeSolicitar saques. Move dinheiro.Se marcada na criação

Valores e status

Toda rota enxerga só os dados da sua conta. Depois de gerada, a cobrança passa para COMPLETED quando o Pix é confirmado.

StatusSignificado
APPROVALSaque com o total reservado, aguardando aprovação da Royalpay. Ainda não foi enviado.
CREATEDSolicitação salva, aguardando envio.
PROCESSINGEnvio ao provedor iniciado.
PENDINGAguardando confirmação do provedor.
COMPLETEDConfirmada. Só este status significa pagamento recebido ou saque concluído.
FAILEDFalha confirmada. A reserva do saque volta ao saldo.
REVIEWResultado inconclusivo. A reserva fica mantida até a conferência; não reenvie.

Tarifas e limites

A tarifa vem da rota da sua conta. Enviar outra taxa no corpo não muda nada, e cada transação guarda a tarifa aplicada na criação.

OperaçãoTarifaExemplo de R$ 100
Cobrança · Vendedor3% + R$ 1,50Credita R$ 95,50
Cobrança · Ghost10% + R$ 1,50Credita R$ 88,50
Saque PixR$ 1,50Debita R$ 101,50 e envia R$ 100,00
Saque em USDT8% + R$ 1,50Debita R$ 109,50 e converte R$ 100,00
OperaçãoLimite
CobrançaDe R$ 5,00 a R$ 1.000,00, e o valor precisa ser maior que a tarifa.
Saque PixA partir de R$ 1,00.
Saque em USDTDe R$ 20,00 a R$ 3.000,00.
Requisições100 por minuto por chave e 40 criações por minuto por conta.

Idempotência

Toda criação de cobrança ou saque exige o header Idempotency-Key, com 8 a 100 letras, números, hífen ou sublinhado.

Header
Idempotency-Key: pedido-1001

Em caso de timeout, repita com a mesma chave: o mesmo corpo devolve a transação já criada, sem duplicar. Dados diferentes com a mesma chave respondem 409.

Erros

Toda resposta de erro traz error com a mensagem e code com um identificador. O status HTTP diz a categoria.

StatusNomeDescrição
400Dados inválidosCampo faltando, tipo errado ou Idempotency-Key ausente. code = VALIDATION_ERROR nos erros de campo.
401Não autenticadoChave ausente, inválida ou revogada.
403Sem permissãoConta não aprovada (code = ACCOUNT_NOT_APPROVED) ou chave sem a permissão da rota.
404Não encontradoO recurso não existe ou não pertence à sua conta.
409ConflitoIdempotency-Key usada com outros dados.
422Regra de negócioSaldo insuficiente, limite da conta ou valor que não cobre a tarifa.
429Muitas requisiçõesLimite atingido: espere antes de tentar de novo.
500Erro internoErro inesperado do nosso lado (code = INTERNAL_ERROR). Consulte a transação antes de repetir.

Exemplo de Resposta

JSON
{
  "error": "Saldo insuficiente para o valor do saque e a tarifa de R$ 1,50.",
  "code": "REQUEST_ERROR"
}
Timeout em saque
Consulte a transação ou repita com a mesma Idempotency-Key. Nunca reenvie com outra chave: um saque em REVIEW mantém a reserva até a conferência da Royalpay.

Gerar cobrança

POST

/payments

cashin

Autenticação: chave de acesso (Bearer) com a permissão payments:write.

Cria uma cobrança Pix para receber pagamento de um cliente. Retorna o copia e cola e o link de pagamento. HTTP 201 indica que a solicitação existe; só COMPLETED significa pagamento confirmado.

Headers

ParâmetroTipoDescrição
Idempotency-Key *stringIdentificador único da operação. Veja Idempotência.

Parâmetros

ParâmetroTipoDescrição
amountCents *integerValor em centavos, de 500 a 100000. Ex.: 10000
descriptionstringDescrição, de 3 a 200 caracteres. Sem o campo, vale “Cobrança Pix”.
payerNamestringNome do pagador, de 3 a 120 caracteres.
payerDocumentstringCPF válido do pagador. Sem pagador, o comprovante mostra “Pagador não identificado” até o pagamento trazer esse dado.
checkoutstringSlug de um checkout publicado da sua conta. O checkoutUrl da resposta abre o Pix com a identidade visual dele.

Exemplo de Requisição

curl -X POST 'https://useroyalpay.com.br/api/v1/payments' \
  -H 'Authorization: Bearer SUA_CHAVE' \
  -H 'Idempotency-Key: pedido-1001' \
  -H 'Content-Type: application/json' \
  -d '{
    "amountCents": 10000,
    "description": "Pedido 1001",
    "payerName": "Nome do cliente",
    "payerDocument": "52998224725"
  }'

Exemplo de Resposta

JSON
{
  "data": {
    "id": "UUID_DA_TRANSACAO",
    "kind": "DEPOSIT",
    "status": "PENDING",
    "amount_cents": 10000,
    "fee_cents": 450,
    "description": "Pedido 1001",
    "copy_paste": "CODIGO_PIX",
    "created_at": "2026-11-01T12:00:00.000Z"
  },
  "checkoutUrl": "https://useroyalpay.com.br/pagar/UUID_DA_TRANSACAO"
}

Respostas

StatusDescrição
201Cobrança criada, com copia e cola e checkoutUrl.
400Dados inválidos ou Idempotency-Key ausente.
401Chave ausente, inválida ou revogada.
403Conta não aprovada ou chave sem essa permissão.
409Idempotency-Key já usada com outros dados.
422Valor não cobre a tarifa, limite da conta atingido ou checkout fora do ar.

Listar cobranças

GET

/payments

cashin

Autenticação: chave de acesso (Bearer) com a permissão payments:read.

Lista as suas cobranças, 15 por página.

Parâmetros

ParâmetroTipoDescrição
pageintegerPágina, a partir de 1.
statusstringCREATED, PROCESSING, PENDING, COMPLETED, FAILED ou REVIEW.
searchstringBusca por nome, descrição ou ID.
fromdateData inicial, no formato AAAA-MM-DD.
todateData final, no formato AAAA-MM-DD.

Exemplo de Requisição

curl 'https://useroyalpay.com.br/api/v1/payments?page=1&status=COMPLETED' \
  -H 'Authorization: Bearer SUA_CHAVE'

Exemplo de Resposta

JSON
{
  "transactions": [
    {
      "id": "UUID_DA_TRANSACAO",
      "kind": "DEPOSIT",
      "status": "COMPLETED",
      "amount_cents": 10000
    }
  ],
  "total": 1,
  "page": 1,
  "pages": 1
}

Respostas

StatusDescrição
200Lista em transactions, com total, page e pages.
400Filtro inválido.
401Chave ausente, inválida ou revogada.
403Conta não aprovada ou chave sem essa permissão.

Consultar cobrança

GET

/payments/:id

cashin

Autenticação: chave de acesso (Bearer) com a permissão payments:read.

Consulta uma cobrança pelo id devolvido na criação. A resposta vem em data.

Parâmetros

ParâmetroTipoDescrição
id *uuidID devolvido na criação da cobrança (no caminho).

Exemplo de Requisição

curl 'https://useroyalpay.com.br/api/v1/payments/UUID_DA_TRANSACAO' \
  -H 'Authorization: Bearer SUA_CHAVE'

Respostas

StatusDescrição
200Dados da cobrança.
401Chave ausente, inválida ou revogada.
403Conta não aprovada ou chave sem essa permissão.
404O ID não existe ou não é da sua conta.

Solicitar saque

POST

/withdrawals

cashout

Autenticação: chave de acesso (Bearer) com a permissão withdrawals:write.

Solicita um saque para qualquer chave Pix. O valor mais a tarifa de R$ 1,50 são reservados na hora.

Aprovação manual
Todo saque começa em APPROVAL e só é enviado depois de aprovado pela Royalpay. Se for recusado, vira FAILED com o motivo em failure_reason, o total volta ao saldo e o evento withdrawal.failed é enviado.

Headers

ParâmetroTipoDescrição
Idempotency-Key *stringIdentificador único da operação. Veja Idempotência.

Parâmetros

ParâmetroTipoDescrição
amountCents *integerValor em centavos, a partir de 100. Ex.: 10000
pixKeyType *stringCPF, CNPJ, EMAIL, TELEFONE ou CHAVE_ALEATORIA.
pixKey *stringChave Pix. CPF e CNPJ só com números, telefone como +5511999999999 e chave aleatória em UUID.
descriptionstringDescrição, de 3 a 200 caracteres.

Exemplo de Requisição

curl -X POST 'https://useroyalpay.com.br/api/v1/withdrawals' \
  -H 'Authorization: Bearer SUA_CHAVE' \
  -H 'Idempotency-Key: saque-1001' \
  -H 'Content-Type: application/json' \
  -d '{
    "amountCents": 10000,
    "pixKeyType": "EMAIL",
    "pixKey": "financeiro@seunegocio.com",
    "description": "Saque do pedido 1001"
  }'

Exemplo de Resposta

JSON
{
  "data": {
    "id": "UUID_DA_TRANSACAO",
    "kind": "WITHDRAWAL",
    "status": "APPROVAL",
    "amount_cents": 10000,
    "fee_cents": 150,
    "pix_key_type": "EMAIL",
    "pix_key": "financeiro@seunegocio.com",
    "failure_reason": null,
    "created_at": "2026-11-01T12:00:00.000Z"
  },
  "checkoutUrl": null
}

Respostas

StatusDescrição
201Saque registrado em APPROVAL.
400Dados inválidos, chave Pix que não bate com o tipo ou Idempotency-Key ausente.
401Chave ausente, inválida ou revogada.
403Conta não aprovada, chave sem withdrawals:write ou 2FA redefinido há menos de 24 horas.
409Idempotency-Key já usada com outros dados.
422Saldo insuficiente para o valor mais a tarifa, ou limite da conta atingido.

Solicitar saque em USDT

POST

/withdrawals

cashout

Autenticação: chave de acesso (Bearer) com a permissão withdrawals:write.

Mesma rota do saque Pix, para uma carteira na rede BEP20. Segue a mesma reserva e a mesma aprovação manual.

Headers

ParâmetroTipoDescrição
Idempotency-Key *stringIdentificador único da operação. Veja Idempotência.

Parâmetros

ParâmetroTipoDescrição
amountCents *integerValor em centavos, de 2000 a 300000. Ex.: 10000
pixKeyType *stringSempre USDT_BEP20.
pixKey *stringCarteira BEP20: 0x seguido de 40 caracteres hexadecimais.
descriptionstringDescrição, de 3 a 200 caracteres.
Confira a carteira
Envio em cripto para o endereço errado não tem como ser desfeito.

Exemplo de Requisição

curl -X POST 'https://useroyalpay.com.br/api/v1/withdrawals' \
  -H 'Authorization: Bearer SUA_CHAVE' \
  -H 'Idempotency-Key: saque-usdt-1001' \
  -H 'Content-Type: application/json' \
  -d '{
    "amountCents": 10000,
    "pixKeyType": "USDT_BEP20",
    "pixKey": "0x0000000000000000000000000000000000000000"
  }'

Respostas

StatusDescrição
201Saque registrado em APPROVAL.
400Carteira inválida ou valor fora da faixa.
403Conta não aprovada, chave sem withdrawals:write ou 2FA redefinido há menos de 24 horas.
422Saldo insuficiente ou limite da conta atingido.

Listar saques

GET

/withdrawals

cashout

Autenticação: chave de acesso (Bearer) com a permissão payments:read.

Lista os seus saques, 15 por página, com os mesmos filtros de Listar cobranças.

Exemplo de Requisição

curl 'https://useroyalpay.com.br/api/v1/withdrawals?page=1' \
  -H 'Authorization: Bearer SUA_CHAVE'

Exemplo de Resposta

JSON
{
  "transactions": [
    {
      "id": "UUID_DA_TRANSACAO",
      "kind": "WITHDRAWAL",
      "status": "COMPLETED",
      "amount_cents": 10000
    }
  ],
  "total": 1,
  "page": 1,
  "pages": 1
}

Respostas

StatusDescrição
200Lista em transactions, com total, page e pages.
401Chave ausente, inválida ou revogada.
403Conta não aprovada ou chave sem essa permissão.

Consultar saque

GET

/withdrawals/:id

cashout

Autenticação: chave de acesso (Bearer) com a permissão payments:read.

Consulta um saque pelo id devolvido na criação. A resposta vem em data.

Parâmetros

ParâmetroTipoDescrição
id *uuidID devolvido na criação do saque (no caminho).

Exemplo de Requisição

curl 'https://useroyalpay.com.br/api/v1/withdrawals/UUID_DA_TRANSACAO' \
  -H 'Authorization: Bearer SUA_CHAVE'

Respostas

StatusDescrição
200Dados do saque.
401Chave ausente, inválida ou revogada.
403Conta não aprovada ou chave sem essa permissão.
404O ID não existe ou não é da sua conta.

Consultar saldo

GET

/balance

conta

Autenticação: chave de acesso (Bearer) com a permissão payments:read.

Saldo individual da sua conta, em centavos.

CampoDescrição
available_centsDisponível para sacar. Fica negativo se um MED bloquear mais do que há disponível.
reserved_centsComprometido com saques em andamento.
blocked_centsBloqueado por MED em aberto.

Exemplo de Requisição

curl 'https://useroyalpay.com.br/api/v1/balance' \
  -H 'Authorization: Bearer SUA_CHAVE'

Exemplo de Resposta

JSON
{
  "data": {
    "available_cents": 9550,
    "reserved_cents": 0,
    "blocked_cents": 0
  },
  "currency": "BRL"
}

Respostas

StatusDescrição
200Saldo da conta.
401Chave ausente, inválida ou revogada.
403Conta não aprovada ou chave sem essa permissão.

Listar checkouts

GET

/checkouts

conta

Autenticação: chave de acesso (Bearer) com a permissão payments:read.

Lista os checkouts publicados em Checkouts e os links deles. Pelo link público, o preço vem sempre da versão publicada.

Exemplo de Requisição

curl 'https://useroyalpay.com.br/api/v1/checkouts' \
  -H 'Authorization: Bearer SUA_CHAVE'

Exemplo de Resposta

JSON
{
  "data": [
    {
      "slug": "k3m9x2pa",
      "name": "Curso de março",
      "url": "https://useroyalpay.com.br/c/k3m9x2pa",
      "version": 3,
      "product": "Curso completo",
      "priceCents": 29700,
      "offerActive": true,
      "offerEndsAt": "2026-11-20T23:59:00.000Z"
    }
  ]
}

Respostas

StatusDescrição
200Checkouts publicados.
401Chave ausente, inválida ou revogada.
403Conta não aprovada ou chave sem essa permissão.

Configurar webhook

A Royalpay chama a sua URL com POST quando uma cobrança ou um saque é concluído ou falha. É a forma recomendada de acompanhar as operações.

  1. No painel, abra Webhooks.
  2. Cadastre a URL do seu sistema: HTTPS público, na porta 443.
  3. Guarde o segredo de assinatura. Salvar o webhook de novo gera outro segredo.
Reenvio automático
Se a entrega falhar, a Royalpay tenta de novo até 8 vezes, com intervalos crescentes de até 1 hora. Cada tentativa espera 5 segundos e redirecionamentos não são seguidos. Por isso, o seu sistema deve aceitar a mesma notificação mais de uma vez.

Payload dos eventos

Exemplo de uma cobrança paga. Em saques, netCents vem como null.

EventoQuando
payment.completedCobrança paga.
payment.failedCobrança falhou.
withdrawal.completedSaque concluído.
withdrawal.failedSaque falhou ou foi recusado. O total voltou ao saldo.

Exemplo de Payload

JSON
{
  "id": "UUID_DO_EVENTO",
  "event": "payment.completed",
  "createdAt": "2026-11-01T12:00:00.000Z",
  "data": {
    "id": "UUID_DA_TRANSACAO",
    "type": "DEPOSIT",
    "status": "COMPLETED",
    "amountCents": 10000,
    "feeCents": 450,
    "netCents": 9550,
    "currency": "BRL"
  }
}

Validar assinatura

Valide a assinatura com o corpo bruto, antes de interpretar o JSON. Ela é um HMAC SHA-256 de timestamp.corpo com o segredo do webhook.

HeaderO que é
X-Royalpay-SignatureAssinatura, no formato v1=hex.
X-Royalpay-TimestampMomento do envio, em segundos.
X-Royalpay-Event-IdID do evento, igual ao id do corpo.

Exemplo de Validação

Node
import { createHmac, timingSafeEqual } from "node:crypto";

const timestamp = request.headers["x-royalpay-timestamp"];
const signature = request.headers["x-royalpay-signature"];
if (typeof timestamp !== "string" || !/^\d+$/.test(timestamp)) {
  throw new Error("Timestamp inválido");
}
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
  throw new Error("Evento fora da janela de 5 minutos");
}
const expected = "v1=" + createHmac("sha256", WEBHOOK_SECRET)
  .update(timestamp + "." + rawBody)
  .digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signature ?? "");
if (a.length !== b.length || !timingSafeEqual(a, b)) {
  throw new Error("Assinatura inválida");
}
// Guarde o evento pelo id e responda 2xx.

Boas práticas

  • Valide a assinatura de toda notificação antes de usar os dados.
  • Responda 2xx rápido e processe o pedido depois, numa fila ou tarefa em segundo plano.
  • Trate repetições: use o id do evento para não entregar o mesmo pedido duas vezes.
  • Confirme em caso de dúvida com GET /payments/:id antes de liberar o produto.
Precisa de ajuda com a integração?
Abra um ticket pela Central de ajuda do painel. A conversa fica registrada do início ao fim.