> ## Documentation Index
> Fetch the complete documentation index at: https://docs.econpay.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /payments/reversal

> Processar reembolso/estorno de uma transação

## Descrição

Processa o reembolso total de uma transação aprovada. O valor será devolvido ao cliente de acordo com o método de pagamento original.

<Warning>
  Apenas transações com status `APPROVED` podem ser estornadas.
</Warning>

## Headers

<ParamField header="Authorization" type="string" required>
  Bearer token JWT obtido no login
</ParamField>

## Request Body

<ParamField body="transaction_id" type="number" required>
  ID da transação a ser estornada
</ParamField>

<ParamField body="reason" type="string">
  Motivo do reembolso (opcional)
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Indica se a operação foi bem-sucedida
</ResponseField>

<ResponseField name="message" type="string">
  Mensagem de sucesso ou erro
</ResponseField>

<ResponseField name="transaction" type="object">
  <Expandable title="properties">
    <ResponseField name="id" type="number">
      ID da transação
    </ResponseField>

    <ResponseField name="order_number" type="string">
      Número do pedido
    </ResponseField>

    <ResponseField name="status" type="string">
      Novo status: `REFUNDED`
    </ResponseField>

    <ResponseField name="amount" type="number">
      Valor original em centavos
    </ResponseField>

    <ResponseField name="refund_amount" type="number">
      Valor estornado em centavos
    </ResponseField>

    <ResponseField name="refunded_at" type="string">
      Data do estorno (ISO 8601)
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.econpay.com.br/payments/reversal \
    --header 'Authorization: Bearer SEU_TOKEN_JWT' \
    --header 'Content-Type: application/json' \
    --data '{
      "transaction_id": 123,
      "reason": "Solicitação do cliente"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.econpay.com.br/payments/reversal', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      transaction_id: 123,
      reason: 'Solicitação do cliente'
    })
  });

  const refund = await response.json();

  if (refund.success) {
    console.log('Reembolso processado:', refund.transaction.order_number);
    console.log('Valor estornado:', refund.transaction.refund_amount / 100);
  }
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.econpay.com.br/payments/reversal',
      headers={
          'Authorization': f'Bearer {token}',
          'Content-Type': 'application/json'
      },
      json={
          'transaction_id': 123,
          'reason': 'Solicitação do cliente'
      }
  )

  refund = response.json()

  if refund['success']:
      print(f"Reembolso processado: {refund['transaction']['order_number']}")
      print(f"Valor: R$ {refund['transaction']['refund_amount'] / 100:.2f}")
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init('https://api.econpay.com.br/payments/reversal');

  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer ' . $token,
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
      'transaction_id' => 123,
      'reason' => 'Solicitação do cliente'
  ]));

  $response = curl_exec($ch);
  $refund = json_decode($response, true);

  if ($refund['success']) {
      echo 'Reembolso processado: ' . $refund['transaction']['order_number'];
  }

  curl_close($ch);
  ?>
  ```
</RequestExample>

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "success": true,
    "message": "Reembolso processado com sucesso",
    "transaction": {
      "id": 123,
      "order_number": "ORD-20240122-123456",
      "status": "REFUNDED",
      "amount": 10000,
      "refund_amount": 10000,
      "payment_type": "pix",
      "refunded_at": "2024-01-22T15:00:00Z",
      "created_at": "2024-01-22T10:30:00Z"
    }
  }
  ```

  ```json 400 - Status Inválido theme={null}
  {
    "success": false,
    "message": "Transação não pode ser estornada",
    "error": "Apenas transações com status APPROVED podem ser estornadas. Status atual: PENDING"
  }
  ```

  ```json 404 - Não Encontrada theme={null}
  {
    "success": false,
    "message": "Transação não encontrada",
    "error": "Nenhuma transação encontrada com ID: 999"
  }
  ```

  ```json 400 - Já Estornada theme={null}
  {
    "success": false,
    "message": "Transação não pode ser estornada",
    "error": "Esta transação já foi estornada"
  }
  ```
</ResponseExample>

## Prazos de Reembolso

O prazo para o cliente receber o reembolso varia por método de pagamento:

| Método            | Prazo                  |
| ----------------- | ---------------------- |
| PIX               | Instantâneo (segundos) |
| Cartão de Crédito | 5 a 10 dias úteis      |
| Cartão de Débito  | 5 a 10 dias úteis      |
| Boleto            | 5 a 10 dias úteis      |

<Note>
  Para cartões, o prazo depende da operadora do cartão do cliente.
</Note>

## Regras de Estorno

<AccordionGroup>
  <Accordion title="Quando posso estornar?">
    * Apenas transações com status `APPROVED`
    * Não há limite de tempo (pode estornar meses depois)
    * Cada transação pode ser estornada apenas uma vez
  </Accordion>

  <Accordion title="Estorno parcial">
    Atualmente, apenas estornos totais são suportados. O valor total da transação será devolvido.
  </Accordion>

  <Accordion title="Taxas de estorno">
    * PIX: Sem taxa adicional
    * Cartão: Taxa da adquirente pode ser cobrada
    * Boleto: Sem taxa adicional

    Consulte seu contrato para detalhes sobre taxas.
  </Accordion>

  <Accordion title="Webhook de estorno">
    Quando um estorno é processado, um webhook `payment.refunded` é enviado:

    ```json theme={null}
    {
      "event": "payment.refunded",
      "transaction_id": 123,
      "status": "REFUNDED",
      "refund_amount": 10000,
      "refunded_at": "2024-01-22T15:00:00Z"
    }
    ```
  </Accordion>
</AccordionGroup>

## Exemplo Completo

```javascript theme={null}
async function refundPayment(transactionId, reason) {
  try {
    // 1. Buscar detalhes da transação
    const transaction = await fetch(
      `https://api.econpay.com.br/transactions/${transactionId}`,
      {
        headers: { 'Authorization': `Bearer ${token}` }
      }
    ).then(r => r.json());
    
    // 2. Verificar se pode ser estornada
    if (transaction.status !== 'APPROVED') {
      throw new Error(`Transação não pode ser estornada. Status: ${transaction.status}`);
    }
    
    // 3. Processar estorno
    const refund = await fetch('https://api.econpay.com.br/payments/reversal', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        transaction_id: transactionId,
        reason: reason
      })
    }).then(r => r.json());
    
    if (refund.success) {
      console.log('✅ Reembolso processado com sucesso');
      console.log(`Pedido: ${refund.transaction.order_number}`);
      console.log(`Valor: R$ ${refund.transaction.refund_amount / 100}`);
      
      // 4. Notificar cliente
      await sendRefundEmail(transaction.customer.email, refund);
      
      return refund;
    } else {
      throw new Error(refund.error);
    }
  } catch (error) {
    console.error('❌ Erro ao processar reembolso:', error.message);
    throw error;
  }
}

// Uso
await refundPayment(123, 'Produto com defeito');
```

## Tratamento de Erros

```javascript theme={null}
async function safeRefund(transactionId, reason) {
  try {
    const response = await fetch('https://api.econpay.com.br/payments/reversal', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ transaction_id: transactionId, reason })
    });
    
    const data = await response.json();
    
    if (!response.ok) {
      switch (response.status) {
        case 400:
          if (data.error.includes('já foi estornada')) {
            console.log('Transação já estornada anteriormente');
            return { alreadyRefunded: true };
          }
          throw new Error(`Não pode estornar: ${data.error}`);
        
        case 404:
          throw new Error('Transação não encontrada');
        
        default:
          throw new Error(data.error || 'Erro desconhecido');
      }
    }
    
    return data;
  } catch (error) {
    console.error('Erro ao estornar:', error.message);
    throw error;
  }
}
```

## Próximos Passos

<CardGroup cols={2}>
  <Card title="Listar Transações" icon="list" href="/api-reference/transactions/list">
    Consultar transações para estornar
  </Card>

  <Card title="Detalhes da Transação" icon="file-invoice" href="/api-reference/transactions/details">
    Ver informações completas
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Receber notificações de estorno
  </Card>

  <Card title="Erros" icon="triangle-exclamation" href="/guides/errors">
    Códigos de erro
  </Card>
</CardGroup>
