Caso de uso · Integração entre servidores

Leve o financeiro e a gestão de planos para dentro do seu produto

Seu cliente consulta cobranças, pagamentos e NFS-e e pode pedir upgrade ou downgrade sem sair do dashboard. O backend integra tudo com uma chave própria; o RecoPay permanece responsável por planos, preços, ciclo, pagamento, efetivação e auditoria.

Plano e recursos necessários

Você precisa de API habilitada e Integrações Externas ativo, com financeiro:cliente:ler para leitura e assinaturas:cliente:alterar-plano para troca de plano. Esta integração usa a sessão do seu SaaS e não depende de publicar a Central do Cliente em código aberto. A emissão de notas depende do recurso fiscal do plano; o Starter não inclui NFS-e.

Confira os requisitos por tipo de integração e compare os planos disponíveis.

O objetivo

Uma área financeira própria, com o RecoPay como fonte de verdade

Use este fluxo quando o cliente já trabalha dentro do dashboard do seu produto e deve consultar ali mesmo suas faturas e documentos. O RecoPay continua responsável por gerar cobranças, conciliar pagamentos, calcular valores atuais e processar NFS-e. Seu sistema apresenta esses dados sem replicar a lógica financeira.

A integração é restrita a uma assinatura por chamada. Isso evita misturar produtos diferentes do mesmo cliente e permite que cada conta do seu sistema veja somente o contrato ao qual está vinculada.

Não existe segundo login

O usuário não informa a senha do RecoPay no dashboard do produto. A Central do Cliente RecoPay continua opcional e independente desta integração.

Seu produto

  • Autentica o usuário com sua identidade própria.
  • Relaciona a conta local à referência da assinatura.
  • Mantém a chave da API apenas no servidor.
  • Autoriza cada tela e download antes de consultar.

RecoPay

  • Identifica a empresa pela chave rpk_.
  • Resolve a assinatura pela referência pública.
  • Revalida cliente, cobrança, pagamento e nota.
  • Retorna valores, status, checkout e documentos.
Desenho recomendado

O navegador conversa com o seu backend, nunca diretamente com o RecoPay

O cliente entra no produto

Seu dashboard autentica o usuário normalmente e cria uma sessão própria, por exemplo com cookie seguro.

O backend identifica o tenant local

A sessão determina a conta, workspace ou empresa local. Não aceite um identificador financeiro escolhido livremente pelo navegador.

O backend recupera a referência persistida

Leia do seu banco a assinaturaReferencia associada à conta autenticada durante a contratação e o provisionamento.

O backend chama a API RecoPay

Envie a chave rpk_ no header Bearer e a referência pública na rota. Devolva ao navegador somente os dados necessários.

Fluxo de confiança
Navegador autenticado
  └─ GET /api/minha-conta/financeiro        [sessão do produto]
       └─ Backend resolve assinaturaReferencia no banco local
            └─ GET https://api.recopay.com.br/integracoes/...
                 Authorization: Bearer rpk_... [segredo do servidor]
Correlação segura

Persista a referência da assinatura no ciclo de venda

O RecoPay devolve duas referências com finalidades diferentes. contratacaoReferencia correlaciona checkout, redirecionamento, webhook e logs. assinaturaReferencia identifica de forma pública e estável o contrato financeiro nas consultas posteriores.

ReferênciaOnde apareceComo usar
contratacaoReferenciaResposta da contratação, webhook e URL de boas-vindasEncontrar o onboarding ou provisionamento pendente.
assinaturaReferenciaResposta da contratação e webhook confirmadoPersistir junto à conta local e consultar o financeiro.
Registro local recomendado

Crie o vínculo inicial durante uma contratação iniciada por uma sessão autenticada ou por um onboarding pendente conhecido. Confirme-o quando chegar o webhook de primeiro pagamento. Não associe automaticamente uma assinatura a uma conta apenas porque e-mail ou documento parecem iguais.

O parâmetro ref não autentica ninguém

A URL de boas-vindas ajuda a localizar um fluxo já conhecido. Ela nunca deve conceder acesso, trocar a conta vinculada ou substituir a confirmação por webhook.

Configuração

Crie uma chave exclusiva para o portal integrado

  1. No RecoPay, abra Utilitários → Integrações Externas.
  2. Escolha a finalidade Portal financeiro no seu produto.
  3. Confirme os escopos financeiro:cliente:ler e assinaturas:cliente:alterar-plano.
  4. Gere a chave, copie o segredo exibido uma única vez e salve-o no cofre de segredos do backend.

O primeiro escopo permite listar cobranças, pagamentos e notas e baixar PDF e XML. O segundo permite listar opções elegíveis, simular, solicitar, acompanhar e cancelar um downgrade ainda agendado. Se o seu portal for apenas de leitura, conceda somente financeiro:cliente:ler. Você também pode separar leitura e troca de plano em duas chaves para reduzir privilégios.

Configuração protegida do servidor
RECOPAY_API_BASE_URL=https://api.recopay.com.br
RECOPAY_API_KEY=rpk_PREFIXO_SEGREDO

# Nunca use VITE_, NEXT_PUBLIC_, PUBLIC_ ou equivalente nesta chave.
Contrato HTTP

Consulte cobranças, pagamentos e notas pela assinatura

As listagens aceitam status, pagina e tamanhoPagina. O tamanho fica limitado entre 1 e 100. O filtro usa o status nativo de cada recurso.

Cobranças

GET/integracoes/assinaturas/{assinaturaReferencia}/cobrancas
Enviado ao RecoPay
curl --request GET \
  --url "https://api.recopay.com.br/integracoes/assinaturas/REFERENCIA/cobrancas?status=pendente&pagina=1&tamanhoPagina=20" \
  --header "Authorization: Bearer SUA_CHAVE_RPK" \
  --header "Accept: application/json"
Recebido do RecoPay · HTTP 200
{
  "sucesso": true,
  "mensagem": "Cobrancas da assinatura carregadas com sucesso.",
  "dados": {
    "pagina": 1,
    "tamanhoPagina": 20,
    "total": 1,
    "itens": [{
      "id": 2481,
      "planoNome": "Plano Profissional",
      "competencia": "2026-09-01T00:00:00",
      "vencimento": "2026-09-10T00:00:00",
      "valorOriginal": 149.90,
      "valorDesconto": 0.00,
      "valorMulta": 0.00,
      "valorJuros": 0.00,
      "valorTotal": 149.90,
      "moeda": "BRL",
      "status": "pendente",
      "formaPagamento": "Pix",
      "dataPagamento": null,
      "checkoutUrl": "https://recopay.app/cobrancas/visualizar/..."
    }]
  }
}

Pagamentos

GET/integracoes/assinaturas/{assinaturaReferencia}/pagamentos

Cada item relaciona o pagamento à cobrança, informa método, status, valor, datas de autorização, captura ou estorno e apenas os dados seguros do cartão quando existirem.

Recebido do RecoPay · pagamentos
{
  "sucesso": true,
  "mensagem": "Pagamentos da assinatura carregados com sucesso.",
  "dados": {
    "pagina": 1,
    "tamanhoPagina": 20,
    "total": 1,
    "itens": [{
      "id": 731,
      "cobrancaId": 2480,
      "planoNome": "Plano Profissional",
      "gateway": "mercadopago",
      "metodo": "Pix",
      "status": "pago",
      "valor": 149.90,
      "moeda": "BRL",
      "dataAutorizacao": "2026-08-10T10:31:00",
      "dataCaptura": "2026-08-10T10:31:02",
      "dataEstorno": null,
      "dataCriacao": "2026-08-10T10:29:00",
      "dataAtualizacao": "2026-08-10T10:31:02",
      "competenciaCobranca": "2026-08-01T00:00:00",
      "vencimentoCobranca": "2026-08-10T00:00:00",
      "statusCobranca": "paga",
      "cartaoBandeira": null,
      "cartaoUltimosDigitos": null,
      "checkoutUrl": "https://recopay.app/cobrancas/visualizar/..."
    }]
  }
}

Notas fiscais

GET/integracoes/assinaturas/{assinaturaReferencia}/notas

Cada item informa status, número, chave de acesso, competência, emissão, valores e se PDF ou XML estão disponíveis. A listagem não expõe payload fiscal bruto, certificado, debug do gateway ou dados internos.

Recebido do RecoPay · notas fiscais
{
  "sucesso": true,
  "mensagem": "Notas fiscais da assinatura carregadas com sucesso.",
  "dados": {
    "pagina": 1,
    "tamanhoPagina": 20,
    "total": 1,
    "itens": [{
      "id": 184,
      "cobrancaId": 2480,
      "planoNome": "Plano Profissional",
      "numeroNfse": "2214",
      "chaveAcesso": "350600312102565230001570000000002214...",
      "status": "autorizada",
      "dataEmissao": "2026-08-10T10:36:00",
      "dataCompetencia": "2026-08-01T00:00:00",
      "dataCancelamento": null,
      "valorServico": 149.90,
      "valorIss": 3.00,
      "aliquotaIss": 2.00,
      "descricaoServico": "Licenca mensal do produto",
      "pdfDisponivel": true,
      "xmlDisponivel": true
    }]
  }
}
Catálogo permitido

Peça ao RecoPay as opções disponíveis para aquela assinatura

Não copie a tabela de planos para decidir uma troca e não monte preços no produto integrado. A consulta considera o tenant da chave, a assinatura ativa, o produto contratado e a periodicidade, além de informar eventual alteração pendente. Planos de outro produto não são apresentados. A simulação e a confirmação revalidam inadimplência, cancelamento agendado e concorrência antes de aceitar a mudança.

O consumidor escolhe; o RecoPay calcula

Seu sistema envia somente o planoDestinoId. Tipo, preço, diferença, data de aplicação, componentes e cobrança são definidos pelo RecoPay.

GET/integracoes/assinaturas/{assinaturaReferencia}/planos-disponiveis
Resposta · HTTP 200
{
  "assinaturaReferencia": "assinatura-publica-estavel",
  "planoAtual": {
    "id": 12,
    "nome": "Profissional",
    "valor": 149.90,
    "moeda": "BRL",
    "periodicidade": "mensal",
    "periodicidadeIntervalo": 1
  },
  "planosDisponiveis": [
    {
      "id": 11,
      "nome": "Essencial",
      "valor": 99.90,
      "moeda": "BRL",
      "periodicidade": "mensal",
      "periodicidadeIntervalo": 1,
      "tipoAlteracao": "downgrade"
    },
    {
      "id": 13,
      "nome": "Escala",
      "valor": 249.90,
      "moeda": "BRL",
      "periodicidade": "mensal",
      "periodicidadeIntervalo": 1,
      "tipoAlteracao": "upgrade"
    }
  ],
  "alteracaoPendente": null,
  "ultimaAlteracaoEfetivada": null
}

Os valores representam o contrato padrão formado pelos componentes obrigatórios ativos do plano. Componentes opcionais não são escolhidos por esta API. Se o produto precisar permitir composição variável, trate-a em um fluxo específico depois da troca; não acrescente campos comerciais ao pedido de alteração.

Decisão em duas etapas

Simule primeiro e confirme exatamente a opção apresentada

A simulação não grava dados e pode ser refeita sempre que a tela for aberta. Ela valida o estado atual e explica o efeito da transição. O corpo aceita somente o campo obrigatório planoDestinoId; propriedades adicionais são rejeitadas. Na confirmação, gere uma chave de idempotência nova para a ação lógica e preserve-a durante timeouts e novas tentativas. A Idempotency-Key deve possuir de 1 a 120 caracteres e aceitar somente letras, números, ponto, hífen, underline e dois-pontos.

POST/integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/simulacao
Corpo da simulação
{
  "planoDestinoId": 13
}
Simulação de upgrade · HTTP 200
{
  "assinaturaReferencia": "assinatura-publica-estavel",
  "tipo": "upgrade",
  "planoAtual": { "id": 12, "nome": "Profissional", "valor": 149.90, "moeda": "BRL", "periodicidade": "mensal", "periodicidadeIntervalo": 1 },
  "planoDestino": { "id": 13, "nome": "Escala", "valor": 249.90, "moeda": "BRL", "periodicidade": "mensal", "periodicidadeIntervalo": 1 },
  "valorAlteracao": 100.00,
  "moeda": "BRL",
  "aplicacao": "apos_pagamento",
  "efetivarEm": null,
  "inicioCicloAtual": "2026-09-10",
  "fimCicloAtual": "2026-10-09",
  "proximoVencimento": "2026-10-10",
  "mensagem": "O novo plano sera ativado somente depois da confirmacao do pagamento da diferenca integral. A data de renovacao nao muda."
}

Confirmar a alteração

POST/integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano
Confirmação idempotente
curl --request POST \
  --url "https://api.recopay.com.br/integracoes/assinaturas/REFERENCIA/alteracoes-plano" \
  --header "Authorization: Bearer SUA_CHAVE_RPK" \
  --header "Idempotency-Key: troca-plano-workspace-4831-20260904" \
  --header "Content-Type: application/json" \
  --data '{"planoDestinoId":13}'

Upgrade

  • Cobra a diferença integral entre o contrato atual e o destino.
  • Preserva a próxima renovação e não reinicia o ciclo.
  • Mantém o plano atual até o pagamento ser confirmado.
  • Efetiva o snapshot do destino após a quitação.

Downgrade

  • Não gera cobrança, crédito ou estorno.
  • Mantém o plano atual até o fim do ciclo.
  • Agenda a aplicação para efetivarEm.
  • Pode ser cancelado enquanto estiver agendada.
Upgrade criado · HTTP 201
{
  "assinaturaReferencia": "assinatura-publica-estavel",
  "alteracaoReferencia": "3ae7807b-1eaf-4b5c-852d-ae92920f374d",
  "tipo": "upgrade",
  "status": "aguardando_pagamento",
  "valorAlteracao": 100.00,
  "moeda": "BRL",
  "aplicacao": "apos_pagamento",
  "efetivarEm": null,
  "efetivadaEm": null,
  "inicioCicloAtual": "2026-09-10",
  "fimCicloAtual": "2026-10-09",
  "proximoVencimento": "2026-10-10",
  "planoAtualId": 12,
  "planoDestinoId": 13,
  "cobrancaId": 2510,
  "checkoutUrl": "https://recopay.app/cobrancas/visualizar/...",
  "repetido": false
}

Abra o checkoutUrl para o cliente pagar a diferença. Um HTTP 201 significa que a alteração foi criada, não que o plano já mudou. Repetir o mesmo corpo com a mesma Idempotency-Key devolve HTTP 200, o mesmo recurso e repetido: true. Reutilizar a chave com outro corpo retorna 409.

Downgrade criado · HTTP 201
{
  "assinaturaReferencia": "assinatura-publica-estavel",
  "alteracaoReferencia": "4d2b063f-c37d-4b71-b27c-85bbc2261c5b",
  "tipo": "downgrade",
  "status": "agendada",
  "valorAlteracao": 0.00,
  "moeda": "BRL",
  "aplicacao": "proximo_ciclo",
  "efetivarEm": "2026-10-10",
  "efetivadaEm": null,
  "inicioCicloAtual": "2026-10-10",
  "fimCicloAtual": "2026-11-09",
  "proximoVencimento": "2026-11-10",
  "planoAtualId": 12,
  "planoDestinoId": 11,
  "cobrancaId": null,
  "checkoutUrl": null,
  "repetido": false
}
Estado persistido

Consulte até alcançar um estado terminal

GET/integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/{alteracaoReferencia}

Use a consulta após timeout, ao retornar do checkout e como reconciliação de segurança. Os estados efetivada, cancelada, falhou e expirada são terminais. Não conclua a troca local apenas porque a cobrança foi criada ou o usuário voltou para o dashboard.

StatusLeitura corretaAção do produto
aguardando_pagamentoUpgrade criado; plano antigo continua ativo.Oferecer checkoutUrl e consultar novamente.
pagamento_confirmadoPagamento identificado; efetivação em processamento.Mostrar processamento, sem liberar pelo nome do plano.
agendadaDowngrade será aplicado no próximo ciclo.Exibir data e permitir cancelamento.
processandoRecoPay está trocando snapshots.Aguardar webhook ou nova consulta.
efetivadaPlano e contrato foram alterados.Atualizar o estado local e as permissões derivadas.
canceladaDowngrade agendado foi desfeito.Manter o plano atual.
falhou / expiradaEstado terminal sem troca.Não alterar o acesso; registrar e orientar suporte.

Cancelar um downgrade

POST/integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/{alteracaoReferencia}/cancelamento
Cancelamento idempotente
curl --request POST \
  --url "https://api.recopay.com.br/integracoes/assinaturas/REFERENCIA/alteracoes-plano/ALTERACAO/cancelamento" \
  --header "Authorization: Bearer SUA_CHAVE_RPK" \
  --header "Idempotency-Key: cancelar-troca-workspace-4831-20260904"

Somente um downgrade ainda agendada pode ser cancelado. Upgrade não é cancelado por essa rota: enquanto não pago, a cobrança segue o fluxo financeiro normal; depois do pagamento, a efetivação pertence ao RecoPay.

Atualização assíncrona

Receba mudanças de estado pelo webhook do produto

Os eventos usam a mesma URL e o mesmo segredo configurados no produto. O RecoPay persiste o corpo original, assina cada tentativa e considera entregue somente após HTTP 2xx. O campo canônico evento identifica o tipo de evento; o consumidor deve deduplicar por eventoId e também manter alteracaoReferencia como identidade da operação.

EventoQuando ocorre
assinatura.plano_alteracao_agendadaUm downgrade foi aceito para o próximo ciclo.
assinatura.plano_alteracao_efetivadaO snapshot do novo plano passou a reger a assinatura.
assinatura.plano_alteracao_canceladaUm downgrade agendado foi cancelado.
assinatura.plano_alteracao_falhouO RecoPay encerrou as tentativas sem efetivar.
assinatura.plano_alteracao_expiradaA obrigação associada ao upgrade foi cancelada ou estornada antes da efetivação.
Headers enviados
X-Recopay-Event-Id: 3b530fd4-493e-41ca-a52a-ddd98c63a875
X-Recopay-Timestamp: 1788541200
X-Recopay-Signature: v1=HMAC_SHA256(timestamp + "." + corpo_original)
Corpo de alteração efetivada
{
  "eventoId": "3b530fd4-493e-41ca-a52a-ddd98c63a875",
  "evento": "assinatura.plano_alteracao_efetivada",
  "ocorridoEm": "2026-09-04T18:20:00Z",
  "assinaturaReferencia": "assinatura-publica-estavel",
  "alteracaoReferencia": "3ae7807b-1eaf-4b5c-852d-ae92920f374d",
  "tipoAlteracao": "upgrade",
  "status": "efetivada",
  "planoOrigem": { "id": 12, "nome": "Profissional" },
  "planoDestino": { "id": 13, "nome": "Escala" },
  "efetivarEm": null,
  "efetivadaEm": "2026-09-04T18:20:03Z",
  "inicioCicloAtual": "2026-09-10",
  "fimCicloAtual": "2026-10-09",
  "proximoVencimento": "2026-10-10",
  "cobrancaId": 2510,
  "erro": null
}

Os nomes de data são idênticos na simulação, na consulta e no webhook. Em um downgrade efetivado, inicioCicloAtual é a abertura do ciclo novo, fimCicloAtual é seu último dia e proximoVencimento é a renovação seguinte. Os schemas reutilizáveis AlteracaoPlanoWebhookPayload e AlteracaoPlanoWebhookHeaders também estão publicados no Swagger.

  1. Leia o corpo como bytes, sem desserializar antes da validação.
  2. Rejeite timestamps com diferença superior a cinco minutos.
  3. Calcule HMAC-SHA256 sobre timestamp + "." + corpoOriginal.
  4. Compare a assinatura em tempo constante.
  5. Reserve eventoId em armazenamento durável; repetição devolve 2xx sem executar novamente.
  6. Atualize o vínculo local pela assinaturaReferencia já conhecida e confirme por consulta quando necessário.
Webhook acelera; consulta reconcilia

Uma entrega pode atrasar ou ser repetida. Mantenha a rota de consulta como recuperação. Nunca altere permissões locais por um payload sem assinatura válida ou por um plano informado pelo navegador.

BFF do produto

Resolva a assinatura a partir da sessão local

O ponto mais importante não está no fetch: está na autorização anterior. O backend deve obter a conta atual da sessão e procurar a referência vinculada a essa conta. Não receba assinaturaReferencia do navegador como fonte de autoridade.

Node.js · exemplo simplificado
app.get('/api/minha-conta/financeiro', exigirSessao, async (req, res) => {
  const contaLocalId = req.session.contaId;
  const vinculo = await db.vinculosRecopay.findByConta(contaLocalId);

  if (!vinculo?.assinaturaReferencia) {
    return res.status(404).json({ codigo: 'financeiro_nao_vinculado' });
  }

  const base = `${process.env.RECOPAY_API_BASE_URL}/integracoes/assinaturas/` +
    encodeURIComponent(vinculo.assinaturaReferencia);
  const headers = {
    Authorization: `Bearer ${process.env.RECOPAY_API_KEY}`,
    Accept: 'application/json'
  };

  const [cobrancas, pagamentos, notas] = await Promise.all([
    fetch(`${base}/cobrancas?tamanhoPagina=20`, { headers }),
    fetch(`${base}/pagamentos?tamanhoPagina=20`, { headers }),
    fetch(`${base}/notas?tamanhoPagina=20`, { headers })
  ]);

  if ([cobrancas, pagamentos, notas].some(r => !r.ok)) {
    return res.status(502).json({ codigo: 'financeiro_temporariamente_indisponivel' });
  }

  res.set('Cache-Control', 'private, no-store');
  return res.json({
    cobrancas: (await cobrancas.json()).dados,
    pagamentos: (await pagamentos.json()).dados,
    notas: (await notas.json()).dados
  });
});

Em uma aplicação com múltiplos produtos, mantenha um vínculo por contrato. Se uma conta possuir mais de uma assinatura, o backend pode listar abas locais conhecidas, mas cada consulta ao RecoPay continua usando exatamente uma referência persistida.

Download protegido

Transmita PDF e XML pelo backend do produto

GET/integracoes/assinaturas/{assinaturaReferencia}/notas/{notaId}/pdf
GET/integracoes/assinaturas/{assinaturaReferencia}/notas/{notaId}/xml

Quando o usuário solicitar um documento, autorize novamente a conta local, recupere a referência no servidor e faça streaming da resposta RecoPay. Não devolva a chave Bearer nem uma URL autenticada ao navegador.

A API RecoPay somente entrega o arquivo quando a nota pertence a uma cobrança da mesma assinatura, cliente e empresa. Informar o ID de uma nota de outra assinatura retorna 404.

Content-Type e nome do arquivo

Preserve application/pdf ou application/xml e o Content-Disposition devolvido pela API. Não converta o documento para JSON ou Base64 sem necessidade.

Experiência do cliente

Mostre estados financeiros sem reinterpretá-los

ÁreaInformação principalAção recomendada
Em abertoVencimento, valor atual e formaAbrir o checkoutUrl oficial para pagamento.
PagasValor, data de pagamento e métodoExibir comprovante local somente se o produto o produzir.
NFS-eStatus, número, competência e valorHabilitar PDF/XML apenas quando disponíveis.
PlanosPlano atual, opções e tipo calculadoSimular antes de habilitar a confirmação.
Troca pendenteStatus, vigência ou link de pagamentoMostrar a operação em andamento e impedir outra solicitação.
Sem dadosNenhum recurso nesta assinatura ou filtroExplicar o estado; não tratar lista vazia como falha.

Não recalcule multa, juros, descontos ou situação de pagamento no frontend. Use os valores e status retornados. Para a decisão de bloquear ou liberar funcionalidades por inadimplência, utilize separadamente a rota de situação financeira com o escopo financeiro:ler.

Defesa em profundidade

Valide o vínculo nos dois sistemas

  • A chave rpk_ fica somente no cofre de segredos do backend.
  • O navegador chama rotas autenticadas do próprio produto, sem Bearer RecoPay.
  • O backend resolve a referência pelo tenant da sessão, nunca por query string livre.
  • A API RecoPay extrai empresa_id da chave e nunca aceita esse campo do consumidor.
  • Assinatura, cliente, cobrança, pagamento e nota são filtrados novamente pelo mesmo tenant.
  • Recursos fora do escopo retornam 404 para evitar enumeração.
  • Logs não registram chave, senha, token, documento completo nem respostas fiscais brutas.
  • Use TLS, rotação de chave, timeout curto e limite de conexões no cliente HTTP.
Duas autorizações independentes

Seu produto decide se o usuário atual pode acessar a conta local. O RecoPay decide se a chave pode consultar a assinatura da empresa. Uma camada não substitui a outra.

Resiliência

Trate falhas sem bloquear o produto inteiro

RespostaSignificadoTratamento
400Referência, corpo ou idempotência inválidosCorrigir a requisição; não repetir automaticamente.
401Chave ausente, inválida ou revogadaInterromper chamadas e rotacionar a credencial.
403Escopo ausente ou integração indisponívelRevisar a finalidade e o estado da chave.
404Recurso ou plano não pertence ao contextoReconciliar o vínculo; nunca tentar outros IDs.
409Mesmo plano, inadimplência, alteração pendente ou conflito idempotenteMostrar a condição real e atualizar o estado antes de permitir nova ação.
422Periodicidade incompatível ou transição sem classificação seguraRetirar a opção da interface e revisar o catálogo no RecoPay.
429Limite temporárioRespeitar Retry-After e aplicar backoff com jitter.
503 ou timeoutIndisponibilidade transitória; Retry-After indica a espera mínima quando disponívelConsultar a alteração antes de repetir a escrita com a mesma chave e o mesmo corpo.
500Falha interna inesperadaPreservar o requestId, consultar o recurso e acionar o suporte se persistir.

Você pode usar cache privado curto para melhorar a experiência, mas cobranças em aberto e links de pagamento devem ser atualizados antes de uma ação crítica. Nunca transforme indisponibilidade da API em inadimplência, bloqueio ou cancelamento.

Antes de publicar

Checklist de produção

  • Chave exclusiva criada
  • Escopo financeiro:cliente:ler
  • Escopo assinaturas:cliente:alterar-plano
  • Segredo somente no backend
  • Rotação documentada
  • assinaturaReferencia persistida
  • Vínculo por tenant local
  • Webhook idempotente
  • Boas-vindas sem autoridade
  • BFF exige sessão local
  • Navegador não escolhe referência
  • Timeout configurado
  • Backoff com limite
  • Paginação implementada
  • Filtros por status validados
  • Listas vazias tratadas
  • PDF e XML por streaming
  • Simulação antes da confirmação
  • Idempotency-Key persistida
  • Upgrade só após pagamento
  • Downgrade no próximo ciclo
  • Cancelamento apenas de agendada
  • Webhooks com HMAC
  • Deduplicação por eventoId
  • Reconciliação por consulta
  • Teste horizontal entre contas
  • Teste entre assinaturas
  • Teste entre empresas
  • Logs sem segredos
Implementação assistida

Contrato resumido para agentes de IA

Prompt de integração
OBJETIVO
Exibir cobrancas, pagamentos e NFS-e e permitir upgrade ou downgrade de uma assinatura RecoPay dentro do dashboard do produto terceiro.

IDENTIDADES
- O cliente autentica somente no produto terceiro.
- Nao pedir, armazenar ou conhecer a senha RecoPay.
- Nao usar token rct.* neste fluxo.
- A Central do Cliente RecoPay permanece opcional e independente.

VINCULO
- Persistir contratacaoReferencia para correlacao do onboarding.
- Persistir assinaturaReferencia junto ao tenant local provisionado.
- Confirmar o vinculo pelo webhook de primeiro pagamento.
- Nao vincular contas apenas por coincidencia de e-mail ou documento.
- O navegador nunca escolhe livremente assinaturaReferencia.

AUTENTICACAO DA API
- Criar chave rpk_ com os escopos financeiro:cliente:ler e assinaturas:cliente:alterar-plano.
- Manter a chave somente no backend e fora de logs.
- Enviar Authorization: Bearer em todas as chamadas.

ROTAS
- GET /integracoes/assinaturas/{assinaturaReferencia}/cobrancas
- GET /integracoes/assinaturas/{assinaturaReferencia}/pagamentos
- GET /integracoes/assinaturas/{assinaturaReferencia}/notas
- GET /integracoes/assinaturas/{assinaturaReferencia}/notas/{notaId}/pdf
- GET /integracoes/assinaturas/{assinaturaReferencia}/notas/{notaId}/xml
- GET /integracoes/assinaturas/{assinaturaReferencia}/planos-disponiveis
- POST /integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/simulacao
- POST /integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano [Idempotency-Key]
- GET /integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/{alteracaoReferencia}
- POST /integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/{alteracaoReferencia}/cancelamento [Idempotency-Key]
- Listagens aceitam status, pagina e tamanhoPagina entre 1 e 100.

ALTERACAO DE PLANO
- Enviar somente planoDestinoId; RecoPay define tipo, valor, componentes, data e cobranca.
- Sempre simular antes de confirmar.
- Persistir Idempotency-Key por operacao e reutiliza-la em timeout.
- Upgrade cobra a diferenca integral, preserva o ciclo e so efetiva apos pagamento.
- Downgrade nao gera credito ou estorno e efetiva no proximo ciclo.
- Somente downgrade agendado pode ser cancelado.
- Nao liberar recursos enquanto o status nao for efetivada.

WEBHOOKS DE PLANO
- assinatura.plano_alteracao_agendada
- assinatura.plano_alteracao_efetivada
- assinatura.plano_alteracao_cancelada
- assinatura.plano_alteracao_falhou
- Validar X-Recopay-Timestamp e X-Recopay-Signature sobre timestamp + "." + corpo original.
- Deduplicar X-Recopay-Event-Id e reconciliar pela rota GET.

ARQUITETURA
1. Navegador chama o backend do produto com sua sessao local.
2. Backend resolve o tenant e busca assinaturaReferencia no banco local.
3. Backend chama o RecoPay com a chave rpk_.
4. Backend devolve apenas os dados necessarios ou transmite o arquivo.

GUARDRAILS
- Nao expor rpk_ em JavaScript, app distribuido, cookie, URL ou resposta.
- Nao aceitar empresaId, clienteId ou assinaturaId numerico do navegador.
- Autorizar a conta local antes de toda consulta e download.
- Nao recalcular valores ou reinterpretar status financeiros.
- Nao enviar valor, periodicidade, tipo de alteracao, data ou componentes ao solicitar troca.
- Recurso de outra empresa ou assinatura deve resultar em 404.
- Indisponibilidade da API nunca significa inadimplencia.

Continue sua integração

Próximo passo

Implemente primeiro o vínculo, depois o autosserviço

Homologue a correlação entre contratação, webhook e conta local. Em seguida conecte as consultas; por último, adicione simulação, confirmação idempotente e reconciliação das trocas de plano.