Contestações e disputas
Registra uma disputa (contestação/chargeback) para uma transação e envia, de uma só vez, os documentos de defesa que comprovam a legitimidade da cobrança. Use quando o titular do cartão questiona uma
Registra uma disputa (contestação/chargeback) para uma transação e envia, de uma só vez, os documentos de defesa que comprovam a legitimidade da cobrança. Use quando o titular do cartão questiona uma compra junto ao banco emissor e você precisa apresentar evidências para reverter o estorno.
POST /v1/transactions/{transactionId}/dispute
Como funciona
Uma disputa (ou chargeback) acontece fora da Selectwin: o cliente liga para o banco emissor do cartão e contesta uma compra. O banco notifica a bandeira, que notifica a adquirente, que notifica a Selectwin. A transação então entra no status dispute e o valor correspondente costuma ficar bloqueado até a resolução.
Este endpoint é a sua resposta a essa contestação. Ele não "abre" um chargeback no banco — ele registra a disputa do lado da Selectwin e anexa os documentos de defesa (comprovantes de entrega, nota fiscal, registros de comunicação etc.). Esse pacote é encaminhado à adquirente, que o repassa à bandeira para julgamento.
Pontos importantes do mecanismo:
- Operação de escrita síncrona. A chamada retorna
200com o objeto completo da transação já com o arraydisputespreenchido. O julgamento, porém, é assíncrono e externo: pode levar de semanas a meses, conforme os prazos da bandeira. - Um envio por disputa. Reunir e enviar o máximo de evidências relevantes em uma única chamada aumenta as chances de defesa. Tentar disputar uma transação que já tem disputa em andamento retorna
409 transactionDisputeInProcess. - Acompanhe por webhook, não por polling. A mudança de status (
dispute→ resolvida a favor ou contra) chega por eventos de webhook. Não fique consultando a transação em laço — veja Proibição de polling. - Os tipos de documento são tabelados. O campo
documents[].typeaceita apenas os cinco valores do enum abaixo; cada tipo aparece agrupado em seu próprio array na resposta.
Os estados
disputeechargebackfazem parte do enum destatusda transação. A defesa documental é o que você controla; a decisão final é da bandeira.
Quando usar (e quando não usar)
Use quando:
- A transação está em
disputee você tem evidências de que a compra foi legítima e o produto/serviço foi entregue. - Você quer formalizar a contestação com documentação (comprovante de entrega assinado, nota fiscal, logs de comunicação).
Não use quando:
- O cliente tem razão e você prefere devolver o dinheiro: faça um Reembolso (
POST .../refund) antes que o caso vire chargeback — sai mais barato e evita a marca de disputa. - Você quer apenas concluir a cobrança de uma pré-autorização: isso é Capturar, não disputar.
- Não há documentação real para anexar: sem evidências, a disputa tende a ser encerrada em favor do cliente.
Requisição
Headers
| Cabeçalho | Obrigatório | Valor |
|---|---|---|
SelectKey | Sim | Sua chave de API. Em produção começa com sl_live_; em sandbox, sl_test_. Nunca use Authorization: Bearer/Basic. Veja Autenticação. |
Content-Type | Sim | application/json |
X-Idempotency-Key | Recomendado | Evita registrar a mesma disputa duas vezes se a chamada for reenviada. Veja Idempotência. |
Parâmetros de caminho
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
transactionId | string | Sim | ID da transação em disputa (ex.: tra_01hqzvabc). Trate como opaco — não faça parsing. |
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
description | string | Sim | Descrição e contexto da disputa. |
returnEmail | string (email) | Sim | E-mail de contato para correspondência sobre a disputa. |
documents | array | Sim | Documentos de defesa. Cada item segue o objeto Document abaixo. |
Objeto documents[]
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
type | string (enum) | Sim | Tipo do documento. Um dos valores da tabela Tipos de documento. |
description | string | Não | Descrição do documento. |
assetUrl | string (uri) | Não | URL do arquivo/documento enviado. |
shippingDate | string (data YYYY-MM-DD) | Não | Data de envio relacionada ao comprovante. |
trackingCode | string | Não | Código de rastreamento. |
carrier | string | Não | Transportadora. |
authentication | object | Não | Credenciais para a Selectwin acessar o documento, quando hospedado em sistema protegido. |
Objeto documents[].authentication
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
username | string | Não | Usuário para acessar o documento. |
password | string | Não | Senha (sensível). |
token | string | Não | Token bearer para sistemas externos. |
Tipos de documento (documents[].type)
| Valor | Descrição |
|---|---|
deliveryProof | Comprovante de entrega (ex.: foto da assinatura no recebimento). |
shipmentProof | Comprovante de envio/postagem. |
deliveryReceipt | Recibo de entrega. |
fiscalDocument | Documento fiscal (nota fiscal). |
communicationProof | Comprovante de comunicação com o cliente (ex.: histórico de suporte). |
Importante
type é o único campo do documento exigido pelo contrato. Ainda assim, envie assetUrl e uma description clara em cada item — sem o arquivo de fato, a evidência não defende a transação. Para comprovantes de transporte (shipmentProof/deliveryProof), inclua shippingDate, trackingCode e carrier.
Exemplo de requisição
curl -X POST https://api.selectwin.io/v1/transactions/tra_01hqzvabc/dispute \
-H "SelectKey: sl_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: dispute-tra_01hqzvabc-001" \
-d '{
"description": "Cliente alega não ter recebido o pedido. Anexamos comprovante de entrega assinado, nota fiscal e o histórico de atendimento.",
"returnEmail": "[email protected]",
"documents": [
{
"type": "deliveryProof",
"description": "Foto da assinatura do destinatário no momento da entrega.",
"assetUrl": "https://cdn.empresa.com/provas/assinatura.png",
"authentication": { "token": "bearer ey..." }
},
{
"type": "shipmentProof",
"description": "Comprovante de postagem emitido pela transportadora.",
"assetUrl": "https://cdn.empresa.com/provas/postagem.png",
"shippingDate": "2026-01-15",
"trackingCode": "CA1234CA",
"carrier": "Correios"
},
{
"type": "fiscalDocument",
"description": "Nota fiscal da compra.",
"assetUrl": "https://cdn.empresa.com/provas/nf.pdf",
"authentication": { "username": "usuario", "password": "senha" }
},
{
"type": "communicationProof",
"description": "Histórico de atendimento referente ao pedido.",
"assetUrl": "https://cdn.empresa.com/provas/suporte.png"
}
]
}'Resposta
200 OK — o corpo é o objeto completo da transação já com o status dispute e o array disputes preenchido. A resposta abaixo está abreviada nos campos não relacionados à disputa (o objeto inteiro tem customer, billing, items, receivables etc., como em Ler transação).
{
"id": "tra_01hqzvabc",
"customId": "PEDIDO-1042",
"amount": 5000,
"originalAmount": 5000,
"status": "dispute",
"method": "credit",
"currency": "BRL",
"receivables": [
{
"id": "rec_01hqzvabc",
"status": "dispute",
"amount": 4805,
"grossAmount": 5000,
"currency": "BRL"
}
],
"disputes": [
{
"id": "trd_01hqzvabc",
"returnEmail": "[email protected]"
}
],
"updatedAt": "2026-04-13T10:00:00.000Z",
"createdAt": "2026-04-12T17:56:33.000Z"
}Campos-chave da resposta
| Campo | Tipo | Descrição |
|---|---|---|
id | string | ID da transação (tra_…). |
status | string | Passa a dispute após o registro. |
currency | string | Moeda ISO 4217, atualmente BRL. |
amount | integer | Valor da transação em centavos (5000 = R$ 50,00). |
receivables[].status | string | Os recebíveis ligados à transação também passam a dispute. |
disputes[] | array | Lista de disputas registradas para a transação. |
disputes[].id | string | ID da disputa (trd_…). Guarde-o para correlacionar com os webhooks. |
disputes[].returnEmail | string | E-mail de contato informado no envio. |
Nota
Valores monetários são inteiros em centavos e datas são ISO 8601 em UTC (sufixo Z). Os IDs são opacos — armazene a string inteira sem fazer parsing. Detalhes em Convenções.
Erros
Trate sempre pelo error.code (estável), nunca pela message. Veja o Catálogo de Códigos de Erro e o envelope de erro.
error.code | HTTP | Quando ocorre |
|---|---|---|
transactionIdIsInvalid | 400 | transactionId malformado. |
invalidParameters | 400 | Corpo inválido — ex.: type fora do enum, returnEmail não é e-mail, documents ausente. Veja error.params. |
unauthorized | 401 | SelectKey ausente, inválida ou revogada. |
forbidden | 403 | Autenticado, mas sem permissão para disputar esta transação. |
transactionNotFound | 404 | Nenhuma transação com esse ID. |
transactionDisputeInProcess | 409 | Já existe uma disputa em andamento para esta transação. |
unprocessableEntity | 422 | A transação não está em um estado que permite disputa. |
tooManyRequests | 429 | Limite de requisições excedido — respeite error.retryAfterMinutes. |
serverError | 500 | Erro interno — repita com backoff. |
Boas práticas
- Reembolse antes de virar chargeback quando o cliente tem razão. Um Reembolso voluntário evita a marca de disputa e costuma ser mais barato que perder um chargeback.
- Envie todas as evidências em uma única chamada. Não há "adicionar documento depois" — reúna
deliveryProof,shipmentProof,fiscalDocumentecommunicationProofrelevantes de uma vez. - Para vendas físicas, priorize o rastreio. Inclua
shippingDate,trackingCodeecarriernos comprovantes de transporte; entrega com assinatura é a prova mais forte. - Use
assetUrlacessível. Se o arquivo exige login, preenchaauthentication(tokenouusername/password) para a Selectwin conseguir baixá-lo. - Defenda dentro do prazo. Não reenvie a mesma disputa:
409 transactionDisputeInProcessindica que já há uma em andamento. UseX-Idempotency-Keypara reenvios seguros da rede. - Acompanhe a resolução por webhook. Guarde
disputes[].ide correlacione com os eventos de transação; não consulte a transação em laço. - Previna disputas na origem. Descrições de produto claras, um descritor de fatura reconhecível e suporte ágil reduzem contestações — mais barato que ganhá-las.
Veja também
- Visão geral de Transações — modelo do objeto, status e operações.
- Reembolsar transação — alternativa à disputa quando o cliente tem razão.
- Capturar transação — concluir uma pré-autorização.
- Ler transação — recuperar o objeto completo e o array
disputes. - Listar transações — filtrar por
status=dispute. - Criar transação — origem do recurso disputado.
- Proibição de polling e Convenções.
How is this guide?