SelectwinDOCS
Transações

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 200 com o objeto completo da transação já com o array disputes preenchido. 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[].type aceita apenas os cinco valores do enum abaixo; cada tipo aparece agrupado em seu próprio array na resposta.

Os estados dispute e chargeback fazem parte do enum de status da 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 dispute e 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çalhoObrigatórioValor
SelectKeySimSua chave de API. Em produção começa com sl_live_; em sandbox, sl_test_. Nunca use Authorization: Bearer/Basic. Veja Autenticação.
Content-TypeSimapplication/json
X-Idempotency-KeyRecomendadoEvita registrar a mesma disputa duas vezes se a chamada for reenviada. Veja Idempotência.

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
transactionIdstringSimID da transação em disputa (ex.: tra_01hqzvabc). Trate como opaco — não faça parsing.

Corpo da requisição

CampoTipoObrigatórioDescrição
descriptionstringSimDescrição e contexto da disputa.
returnEmailstring (email)SimE-mail de contato para correspondência sobre a disputa.
documentsarraySimDocumentos de defesa. Cada item segue o objeto Document abaixo.

Objeto documents[]

CampoTipoObrigatórioDescrição
typestring (enum)SimTipo do documento. Um dos valores da tabela Tipos de documento.
descriptionstringNãoDescrição do documento.
assetUrlstring (uri)NãoURL do arquivo/documento enviado.
shippingDatestring (data YYYY-MM-DD)NãoData de envio relacionada ao comprovante.
trackingCodestringNãoCódigo de rastreamento.
carrierstringNãoTransportadora.
authenticationobjectNãoCredenciais para a Selectwin acessar o documento, quando hospedado em sistema protegido.

Objeto documents[].authentication

CampoTipoObrigatórioDescrição
usernamestringNãoUsuário para acessar o documento.
passwordstringNãoSenha (sensível).
tokenstringNãoToken bearer para sistemas externos.

Tipos de documento (documents[].type)

ValorDescrição
deliveryProofComprovante de entrega (ex.: foto da assinatura no recebimento).
shipmentProofComprovante de envio/postagem.
deliveryReceiptRecibo de entrega.
fiscalDocumentDocumento fiscal (nota fiscal).
communicationProofComprovante 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

CampoTipoDescrição
idstringID da transação (tra_…).
statusstringPassa a dispute após o registro.
currencystringMoeda ISO 4217, atualmente BRL.
amountintegerValor da transação em centavos (5000 = R$ 50,00).
receivables[].statusstringOs recebíveis ligados à transação também passam a dispute.
disputes[]arrayLista de disputas registradas para a transação.
disputes[].idstringID da disputa (trd_…). Guarde-o para correlacionar com os webhooks.
disputes[].returnEmailstringE-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.codeHTTPQuando ocorre
transactionIdIsInvalid400transactionId malformado.
invalidParameters400Corpo inválido — ex.: type fora do enum, returnEmail não é e-mail, documents ausente. Veja error.params.
unauthorized401SelectKey ausente, inválida ou revogada.
forbidden403Autenticado, mas sem permissão para disputar esta transação.
transactionNotFound404Nenhuma transação com esse ID.
transactionDisputeInProcess409Já existe uma disputa em andamento para esta transação.
unprocessableEntity422A transação não está em um estado que permite disputa.
tooManyRequests429Limite de requisições excedido — respeite error.retryAfterMinutes.
serverError500Erro interno — repita com backoff.

Boas práticas

  1. 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.
  2. Envie todas as evidências em uma única chamada. Não há "adicionar documento depois" — reúna deliveryProof, shipmentProof, fiscalDocument e communicationProof relevantes de uma vez.
  3. Para vendas físicas, priorize o rastreio. Inclua shippingDate, trackingCode e carrier nos comprovantes de transporte; entrega com assinatura é a prova mais forte.
  4. Use assetUrl acessível. Se o arquivo exige login, preencha authentication (token ou username/password) para a Selectwin conseguir baixá-lo.
  5. Defenda dentro do prazo. Não reenvie a mesma disputa: 409 transactionDisputeInProcess indica que já há uma em andamento. Use X-Idempotency-Key para reenvios seguros da rede.
  6. Acompanhe a resolução por webhook. Guarde disputes[].id e correlacione com os eventos de transação; não consulte a transação em laço.
  7. 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

How is this guide?

On this page