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.
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.
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.
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.
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]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ência | Onde aparece | Como usar |
|---|---|---|
contratacaoReferencia | Resposta da contratação, webhook e URL de boas-vindas | Encontrar o onboarding ou provisionamento pendente. |
assinaturaReferencia | Resposta da contratação e webhook confirmado | Persistir junto à conta local e consultar o financeiro. |
{
"contaLocalId": "workspace_4831",
"recopayContratacaoReferencia": "550e8400-e29b-41d4-a716-446655440000",
"recopayAssinaturaReferencia": "assinatura-publica-estavel",
"vinculoStatus": "ativo"
}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.
ref não autentica ninguémA 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.
Crie uma chave exclusiva para o portal integrado
- No RecoPay, abra Utilitários → Integrações Externas.
- Escolha a finalidade Portal financeiro no seu produto.
- Confirme os escopos
financeiro:cliente:lereassinaturas:cliente:alterar-plano. - 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.
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.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
/integracoes/assinaturas/{assinaturaReferencia}/cobrancascurl --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"{
"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
/integracoes/assinaturas/{assinaturaReferencia}/pagamentosCada 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.
{
"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
/integracoes/assinaturas/{assinaturaReferencia}/notasCada 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.
{
"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
}]
}
}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.
Seu sistema envia somente o planoDestinoId. Tipo, preço, diferença, data de aplicação, componentes e cobrança são definidos pelo RecoPay.
/integracoes/assinaturas/{assinaturaReferencia}/planos-disponiveis{
"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.
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.
/integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/simulacao{
"planoDestinoId": 13
}{
"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
/integracoes/assinaturas/{assinaturaReferencia}/alteracoes-planocurl --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.
{
"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.
{
"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
}Consulte até alcançar um estado terminal
/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.
| Status | Leitura correta | Ação do produto |
|---|---|---|
aguardando_pagamento | Upgrade criado; plano antigo continua ativo. | Oferecer checkoutUrl e consultar novamente. |
pagamento_confirmado | Pagamento identificado; efetivação em processamento. | Mostrar processamento, sem liberar pelo nome do plano. |
agendada | Downgrade será aplicado no próximo ciclo. | Exibir data e permitir cancelamento. |
processando | RecoPay está trocando snapshots. | Aguardar webhook ou nova consulta. |
efetivada | Plano e contrato foram alterados. | Atualizar o estado local e as permissões derivadas. |
cancelada | Downgrade agendado foi desfeito. | Manter o plano atual. |
falhou / expirada | Estado terminal sem troca. | Não alterar o acesso; registrar e orientar suporte. |
Cancelar um downgrade
/integracoes/assinaturas/{assinaturaReferencia}/alteracoes-plano/{alteracaoReferencia}/cancelamentocurl --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.
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.
| Evento | Quando ocorre |
|---|---|
assinatura.plano_alteracao_agendada | Um downgrade foi aceito para o próximo ciclo. |
assinatura.plano_alteracao_efetivada | O snapshot do novo plano passou a reger a assinatura. |
assinatura.plano_alteracao_cancelada | Um downgrade agendado foi cancelado. |
assinatura.plano_alteracao_falhou | O RecoPay encerrou as tentativas sem efetivar. |
assinatura.plano_alteracao_expirada | A obrigação associada ao upgrade foi cancelada ou estornada antes da efetivação. |
X-Recopay-Event-Id: 3b530fd4-493e-41ca-a52a-ddd98c63a875
X-Recopay-Timestamp: 1788541200
X-Recopay-Signature: v1=HMAC_SHA256(timestamp + "." + corpo_original){
"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.
- Leia o corpo como bytes, sem desserializar antes da validação.
- Rejeite timestamps com diferença superior a cinco minutos.
- Calcule HMAC-SHA256 sobre
timestamp + "." + corpoOriginal. - Compare a assinatura em tempo constante.
- Reserve
eventoIdem armazenamento durável; repetição devolve2xxsem executar novamente. - Atualize o vínculo local pela
assinaturaReferenciajá conhecida e confirme por consulta quando necessário.
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.
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.
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.
Transmita PDF e XML pelo backend do produto
/integracoes/assinaturas/{assinaturaReferencia}/notas/{notaId}/pdf/integracoes/assinaturas/{assinaturaReferencia}/notas/{notaId}/xmlQuando 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.
Preserve application/pdf ou application/xml e o Content-Disposition devolvido pela API. Não converta o documento para JSON ou Base64 sem necessidade.
Mostre estados financeiros sem reinterpretá-los
| Área | Informação principal | Ação recomendada |
|---|---|---|
| Em aberto | Vencimento, valor atual e forma | Abrir o checkoutUrl oficial para pagamento. |
| Pagas | Valor, data de pagamento e método | Exibir comprovante local somente se o produto o produzir. |
| NFS-e | Status, número, competência e valor | Habilitar PDF/XML apenas quando disponíveis. |
| Planos | Plano atual, opções e tipo calculado | Simular antes de habilitar a confirmação. |
| Troca pendente | Status, vigência ou link de pagamento | Mostrar a operação em andamento e impedir outra solicitação. |
| Sem dados | Nenhum recurso nesta assinatura ou filtro | Explicar 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.
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_idda 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
404para 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.
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.
Trate falhas sem bloquear o produto inteiro
| Resposta | Significado | Tratamento |
|---|---|---|
400 | Referência, corpo ou idempotência inválidos | Corrigir a requisição; não repetir automaticamente. |
401 | Chave ausente, inválida ou revogada | Interromper chamadas e rotacionar a credencial. |
403 | Escopo ausente ou integração indisponível | Revisar a finalidade e o estado da chave. |
404 | Recurso ou plano não pertence ao contexto | Reconciliar o vínculo; nunca tentar outros IDs. |
409 | Mesmo plano, inadimplência, alteração pendente ou conflito idempotente | Mostrar a condição real e atualizar o estado antes de permitir nova ação. |
422 | Periodicidade incompatível ou transição sem classificação segura | Retirar a opção da interface e revisar o catálogo no RecoPay. |
429 | Limite temporário | Respeitar Retry-After e aplicar backoff com jitter. |
503 ou timeout | Indisponibilidade transitória; Retry-After indica a espera mínima quando disponível | Consultar a alteração antes de repetir a escrita com a mesma chave e o mesmo corpo. |
500 | Falha interna inesperada | Preservar 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.
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
Contrato resumido para agentes de IA
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
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.