Migrar da v1 — referência completa
Migrar da v1 — referência completa
Auditoria endpoint-por-endpoint da migração v1 → v2.
Para o resumo executivo de 2 minutos, veja Migrar da v1 — versão rápida.
Este documento existe para devs auditando a migração, time de ops, e casos edge. Lista as ~75 rotas integrator-facing e como cada uma se comporta na v2.
1. Autenticação
Antes (v1)
Agora (v2)
Diferenças:
- Token URL muda (passa pelo nosso CloudFront).
scope:api/full→api2/read api2/write.- TTL do JWT: 1h (mesmo da v1).
Idempotency-Key: opcional na v2 (auto-gerado se ausente; recomendado continuar enviando para controle de retry).X-Tenant-Id: obrigatório em todas as requisições/v1/*(excetoGET /v1/mee health). Deve bater com o tenant da conta quandoaccountIdestá no path.
2. Endpoints deprecated (continuam funcionando até 2026-11-21)
4 paths que existiam na v1 e ficaram fora da versão canônica da v2 foram reabilitados como aliases deprecated. Eles continuam respondendo normalmente — apenas anexam 3 headers de aviso na resposta:
Esses headers seguem RFC 8594 (Deprecation) e RFC 9745 (Sunset). Clientes podem detectá-los automaticamente para alertar a equipe.
Sunset previsto: 2026-11-21. Após essa data eles passam a retornar 410 Gone.
Essas rotas não aparecem mais no OpenAPI nem na Postman collection — só estão documentadas aqui pra dar tempo de migrar. Quem está começando uma integração nova deve usar diretamente os substitutos.
3. Endpoints removidos (8 rotas — retornam 404)
GET /v1/health continua existindo na v2. Foi adicionado um alias GET /health (sem /v1) para conveniência de health checks externos — você não precisa mudar nada.
4. Endpoints com mudança de comportamento
Mesmo path, mesmo método, mas comportamento ou shape JSON diferente.
4.1 Statement — cache → live (e payer/payee reduzidos)
GET /v1/accounts/{id}/statement
v1: lia de um cache local (DynamoDB) populado por webhooks. Latência ~50ms; enriquecia com tariff_ref e labels traduzidos. As linhas tinham payer.{bankCode,bankIspb,branch,account,pixKey,...} e beneficiary.{...} completos porque eram montados a partir dos webhooks (que trazem todos os campos bancários da contraparte).
v2: chama o liquidante na hora da request. Latência ~500ms-1.5s; sem tariff_ref derivado (a tarifa aparece como linha própria no extrato); header novo X-Source: live. Janela máxima por consulta: 31 dias.
O que mudou no shape de cada linha
A v2 padronizou o objeto da contraparte para name + document + a info do banco do nosso lado (banco liquidante = MT Bank). Os demais campos bancários da contraparte (branch, account, pixKey, etc.) não vêm mais nas linhas do extrato porque o endpoint de extrato do liquidante não os expõe.
v1 (legado, vindo do cache de webhooks):
v2 (live, vindo do liquidante):
Notas sobre o shape v2:
- O par
payer/payeeé montado a partir dadirectionda linha:direction=IN:payer= contraparte (quem nos pagou);payee= a nossa conta;direction=OUT:payer= a nossa conta;payee= contraparte (a quem pagamos).
- O lado self (nossa conta) sempre traz
name(titular) +document(CPF/CNPJ) + os identificadores do banco liquidante (bankCode,bankIspb,bankName). - O lado contraparte sempre traz só
name+document. Campos opcionais (bankCode,bankIspb,branch,account,pixKey,accountType,bankName) ficam omitidos quando vazios — opartyToDTOda v2 não devolve chaves com string vazia. counterParty(objeto extra comname+documentda contraparte) é mantido para facilitar lookup direto sem precisar inspecionardirection.- Removido o campo
authorizationCode(a API do liquidante não o expõe no extrato; estava sempre vazio na v1 também quando lido via fallback live).
Onde recuperar o payload bancário completo da contraparte
Se sua integração precisa de branch/account/pixKey/bankCode da contraparte, use uma das alternativas abaixo (todas trazem o payload completo, pois vêm de endpoints específicos de PIX, não do extrato):
- Webhook outbound:
pix.in.completed,pix.out.completed,pix.refund.completed,qrcode.paid— o envelope CorpX inclui o objetopayer/payeecom todos os campos bancários. - Lookup de pagamento individual:
GET /v1/accounts/{id}/pix/payments/lookup?endToEndId=...— retorna o objeto da transação enriquecido (igual ao que vinha no webhook). - QR Code:
GET /v1/accounts/{id}/pix/qr-code/lookup?identifier=...— para QRs pagos, incluipayer+paymentcomendToEnd.
Se sua integração dependia de polling agressivo do statement, prefira webhooks:
pix.in.receivedpara PIX recebidopix.out.confirmedpara PIX out concluídoboleto.paid/boleto.failedqrcode.paid
Os mesmos efeitos valem para os outros endpoints que liam do mesmo cache:
GET /v1/accounts/{id}/pix/transactionsGET /v1/accounts/{id}/pix/paymentsGET /v1/accounts/{id}/payments(alias)
Todos passam a consultar o liquidante em tempo real, sem cache local.
4.2 MED — ativo de novo, com contrato diferente da v1
Desde a v2.58.0 as rotas de MED respondem: GET /v1/accounts/{id}/pix/med, POST .../answer e as três de evidência. Quatro diferenças em relação à v1, todas detalhadas no guia de Disputas:
- A lista vem dos webhooks. O arranjo não oferece consulta de disputa, então o
GETdevolve o quepix.med.opened/pix.med.updatedregistraram. Assinar esses eventos passou a ser parte de integrar MED. - Não há status de disputa na API. Sem consulta no liquidante, o estado guardado não é verificável, então o
GETnão devolvestatusnem aceita filtro por ele. O que sai éansweredeclientAnswerDeadline. Para acompanhar estado, acumule os eventospix.med.updated— ostatusdeles é o do instante do evento. - O
answermudou de forma e de efeito:result(AGREE/DISAGREE) +reason, no lugar deanswer: "CONCORDO"/"DISCORDO"comevidences. É enviado uma única vez e registra a sua defesa, que segue com os anexos ao time que conduz a disputa — não vai ao liquidante. - Não existe decisão pela API. Devolver o PIX disputado, reter saldo ou recusar a devolução não são operações desta API.
POST .../sendePOST .../decidenão existem.
Evidência voltou a funcionar, com contrato próprio: evidence/upload-url (presign), evidence/add (registro) e GET evidence/download (listagem com URL assinada). Limites: PDF/JPEG/PNG/WebP/TXT/CSV, 5 MB por arquivo, 6 MB e 10 arquivos por disputa, tudo antes de responder.
4.3 Boleto — agora ativo
V1 retornava 503 em todos os endpoints de boleto (POST .../boleto/preview, POST .../boleto/pay, GET .../boleto/payments/{id}). V2 está ativo. Veja Pagamento de Boleto no guia de Cash Out.
Atenção a um detalhe de contrato: POST .../boleto/pay responde 202 (assíncrono) com status: "PROCESSING", não 200 com o pagamento já liquidado. O desfecho chega por boleto.paid / boleto.failed ou pelo GET .../boleto/payments/{paymentId}.
4.4 PIX out — sync vs async (não virou “tudo async”)
A v2 preserva a mesma divisão da v1:
O que mudou internamente (não obriga migrar de sync → async): a orquestração passou por Temporal, mas quem já chama POST .../pix/out sem /async continua no fluxo síncrono. Só migre para /async se quiser alto volume ou evitar esperar os ~25s na conexão HTTP.
Idempotência: retentar com a mesma Idempotency-Key reaproveita o mesmo paymentId/workflow quando ainda em curso; após FAILED, nova chave pode iniciar nova tentativa (ver Cash Out).
4.5 X-CF-Origin-Verify
V2 só aceita requests vindos do CloudFront. Tentar bater direto no execute-api da AWS retorna 403. Use sempre https://tenant.api.corpx.com/v1.
4.6 Webhooks temporariamente suspensos — fee.*, edi.*
Durante a janela de migração, 2 famílias de eventos não são emitidas:
MED: os webhooks
pix.med.opened/pix.med.updatedvoltaram a ser emitidos, e os endpoints de MED também (ver §4.2). Assinar esses dois eventos passou a ser parte de integrar MED: é deles que sai a listagem de disputas.
O que isso significa para você:
- Subscriptions a esses eventos podem ficar registradas — quando voltarem, retomam automaticamente.
- Se sua reconciliação dependia desses eventos, mude temporariamente para polling do extrato (consultas ao liquidante são tempo-real, não há defasagem de cache).
Reativação prevista por etapas:
fee.*— próxima minor após estabilização do refactor no-cache.edi.*— a definir; depende da nova pipeline de batches.
(Os webhooks pix.med.* já foram reativados — ver §4.2.)
4.7 Conciliação automática transação ↔ tarifa — suspensa
v1: o objeto de transação incluía um campo fee: { amount, ... } que pareava cada PIX/boleto com sua tarifa de processamento.
v2: esse campo foi removido temporariamente. A conciliação é feita do lado do cliente cruzando o identifier:
- Transação principal:
identifier = <seu identifier>(ou auto-gerado) - Tarifa correspondente:
identifier = fee-{slug}-{operationReferenceId}na mesma janela temporal, debitada deCORPX_FEE_ACCOUNT_ID
Como reconciliar pelo extrato:
Filtrar items onde identifier começa com fee- e cruzar com a transação principal pelo operationReferenceId embutido.
Quando o refactor no-cache estabilizar, o campo fee no objeto de transação volta. Não há mudança de payload prevista para esse retorno — apenas reaparição do campo.
4.8 Internal transfer by-bank-account — campos extras opcionais
POST /v1/accounts/{id}/transfers/internal/by-bank-account
V2 aceita dois campos extras opcionais: holderDocument e holderName. O liquidante atual precisa desses dados; quando o cliente não envia, o backend faz lookup automático. Não é breaking — clientes que continuam mandando só {branch, accountNumber, value, ...} funcionam normalmente.
4.9 QR-code PIX — resposta achatada (breaking no JSON)
Na tabela (§6), estes endpoints aparecem como body-diff, não como mantido nem alterado genérico: o path é o mesmo, mas o JSON de sucesso mudou. Quem faz response.data.payload ou lê data.location quebra até ajustar o parser — inclusive em POST .../pix/qr-code/dynamic.
Afeta os 5 endpoints de QR-code:
POST /v1/accounts/{id}/pix/qr-code/dynamicPOST /v1/accounts/{id}/pix/qr-code/staticGET /v1/accounts/{id}/pix/qr-code/lookup(e o alias deprecatedGET /v1/accounts/{id}/pix/qr-code)DELETE /v1/accounts/{id}/pix/qr-code
v1: envelope tipo Finaya:
v2: shape canônico achatado, sem envelope:
Mapeamento de campos:
Status code HTTP: v2 retorna 201 Created em criação (POST). GET continua 200.
Como migrar (mínimo):
Se a remoção do location for bloqueante para você, fale com o suporte — podemos avaliar reintroduzir o campo gerando uma URL CDN com o EMV cacheado.
5. Endpoints novos
6. Tabela completa
Status legenda:
- mantido: mesmo path e mesmo JSON de resposta em sucesso. Seu parser continua igual.
- body-diff: mesmo path; JSON de resposta diferente (breaking). Ex.: QR-code sem envelope
{ data: {...} }— ver §4.9. - alterado: mesmo path; comportamento diferente (live, latência, 503→200). O shape JSON de sucesso costuma ser compatível; leia a observação.
- deprecated: ainda funciona até 2026-11-21, com header
Deprecation: true. Migre para o substituto canônico antes do sunset. - removido: rota existia só na v1; retorna 404 na v2.
- adicionado: rota nova; existia só na v2.
Resumo (79 rotas): 39 mantidos, 4 body-diff (QR-code PIX — JSON achatado, §4.9; uma quinta rota de QR também tem resposta achatada, mas está classificada como deprecated), 13 alterados (statement live, MED de volta com contrato novo, boleto 503→200, etc.), 5 deprecated (aliases + QR sync, sunset 2026-11-21), 8 removidos (404 na v2), 7 adicionados, mais 2 desligados em 2026-05 (locked-balance) e 1 desativado (PATCH /pix/limits).
7. Account IDs preservados
Os account_id que você usa em todos os paths e webhooks são os mesmos antes e depois do cutover. Você não precisa atualizar referências armazenadas no seu sistema. Eles permanecem como UUIDs.
O que muda internamente (transparente pra você):
- Identificadores no liquidante são novos — você nunca via esse campo.
- Mecanismo de autenticação com o liquidante mudou — handler interno.
8. FAQ completo
Meu webhook URL precisa mudar? Não.
Meu HMAC secret muda? Não.
Account IDs mudam? Não.
Posso voltar pra v1 se algo der errado? Durante as primeiras 4h após o cutover, sim — temos rollback ensaiado. Após esse período, a infraestrutura antiga é gradualmente desligada.
Por quanto tempo o backoffice antigo fica disponível? 30 dias após o cutover.
Polling de extrato em alta frequência ainda funciona? Funciona, mas tem latência maior (~1s vs ~50ms do cache antigo) e tem janela máxima de 31 dias por consulta. Para mudanças, prefira webhooks.
Existe rate limit novo?
Mantemos os mesmos limites da v1 por tenant. Se você bater limite, retorna 429 Too Many Requests com Retry-After.
O campo fee voltará no objeto de transação?
Sim, na próxima minor após estabilização. Sem mudança de payload — apenas reaparição.
Os webhooks fee.* / edi.* voltarão?
Sim, em fases: fee.* na próxima minor; edi.* a definir. Os webhooks pix.med.* já voltaram, e os endpoints de MED também (§4.2).
Suporte
Contato: api@corpx.com — resposta em até 1h em horário comercial.