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

# Confirmar reembolso realizado

> Encerra um reembolso de boleto depois que a sua própria conta devolveu o dinheiro ao comprador.

`POST /refunds/:id/confirm`

Faz parte do recurso [Reembolsos](/pt-BR/refunds) — o objeto, os status e o ciclo estão lá.

Reembolso de boleto sai por transferência feita à mão, e quem faz a transferência é quem sabe que
ela aconteceu. Este endpoint é a porta de quem devolveu: ele marca o reembolso como `refunded` e
dispara o webhook `refund.refunded`.

Ele existe apenas para as contas que assumem a devolução em contrato. Quando quem devolve é a
plataforma, a confirmação é nossa — e a resposta aqui é `409`.

<Warning>
  **`409` quando a devolução não é sua.** Confirmar é declarar que o dinheiro saiu; se saiu do nosso
  caixa, aceitar a declaração de fora inverteria quem responde pelo valor. A sua tela de
  configurações de reembolso mostra quem devolve nesta conta.
</Warning>

<Warning>
  **`transferNote` é obrigatória quando o reembolso não tem dados bancários registrados** — ou seja,
  quando ele ainda está em `awaiting_bank_details` porque a conta do comprador foi coletada no seu
  sistema e nunca passou por aqui. Nesse caso a nota é o único registro de que a transferência
  existiu; sem ela, a resposta é `400`. Com os dados já registrados por
  [`POST /refunds/:id/bank-details`](/pt-BR/refunds/bank-details), ela é opcional e continua sendo o
  melhor lugar para o identificador da transferência.
</Warning>

<Note>
  **A transação continua `paid` depois desta confirmação.** O dinheiro não passou por nós: o valor da
  venda permanece no seu saldo e nada é debitado da sua carteira. Marcar a transação como estornada
  diria que a venda foi desfeita nos nossos números, quando ela continua paga — então o reembolso
  aparece no recurso de reembolsos e nos eventos `refund.*`, e não no status da transação. Isso vale
  só para este modo; quando a plataforma devolve, a transação segue o desfecho normal do estorno.
</Note>

<Note>
  **Status que aceitam confirmação:** `bank_details_received`, `ted_processing`, `failed` e —
  exclusivamente neste modo — `awaiting_bank_details`. Qualquer outro responde `409`. Um reembolso já
  `refunded` não é reconfirmado: a segunda chamada falha, em vez de ser ignorada.
</Note>

<Info>
  Endpoint idempotente. Envie o header `Idempotency-Key` para que um retry por timeout não confirme
  duas vezes. Veja [Convenções](/pt-BR/convencoes).
</Info>

## Exemplo

```bash theme={null}
curl -X POST https://api.sandbox.z2pay.com/v1/refunds/rfd_j3cpkaysqmix17mxhcmv8qypl/confirm \
  -H "x-api-key: $Z2PAY_API_KEY" \
  -H "Idempotency-Key: 9d2f7c30-5a18-4e6b-8c74-1f3b0a9e5d21" \
  -H "Content-Type: application/json" \
  -d '{
    "transferNote": "Pix 10/09/2026, E12345678202609101430"
  }'
```

```json theme={null}
{
  "id": "rfd_j3cpkaysqmix17mxhcmv8qypl",
  "transactionId": "txn_aqbcw2lky42xfidw5pcdss8h1",
  "paymentId": "pay_jxt9b5qv1x0h0h8ustleqjgr8",
  "amount": 14990,
  "currency": "BRL",
  "status": "refunded",
  "reason": "Cliente solicitou cancelamento da compra",
  "requestedByType": "api",
  "paymentMethod": "boleto",
  "customerId": "cust_lhsmn6ugmjotm5qvnunrr2hz1",
  "customerName": "Maria Silva",
  "customerEmail": "maria.silva@example.com",
  "customerDocument": "12345678909",
  "customerDocumentType": "cpf",
  "additionalInfo": null,
  "failureReason": null,
  "reviewedAt": "2025-06-29T14:02:11.000Z",
  "refundedAt": "2025-06-30T09:31:02.000Z",
  "createdAt": "2025-06-29T13:45:30.000Z",
  "updatedAt": "2025-06-30T09:31:02.000Z"
}
```


## OpenAPI

````yaml openapi/psp.json POST /refunds/{id}/confirm
openapi: 3.0.3
info:
  title: Z2Pay PSP API
  version: 1.0.0
  description: API pública do PSP — autenticação via API Key (Credential)
servers:
  - url: https://api.sandbox.z2pay.com/v1
    description: Sandbox
  - url: https://api.z2pay.com/v1
    description: Produção
security: []
tags:
  - name: Cards
    description: Cartões salvos de um cliente
  - name: Chargebacks
    description: Gerenciamento de chargebacks
  - name: Customers
    description: Gerenciamento de clientes (compradores)
  - name: Fees
    description: Tabela de taxas da conta (pix, boleto, cartão, saque, refund, chargeback)
  - name: Receivables
    description: >-
      Recebíveis: o que cada venda vai depositar na carteira, por recebedor e
      parcela, com data prevista e status
  - name: Recipients
    description: Gerenciamento de recebedores (sellers/merchants que recebem repasses)
  - name: Refunds
    description: Gerenciamento de reembolsos e estornos
  - name: Splits
    description: Regras de divisão do valor de uma venda entre recebedores
  - name: Transactions
    description: Gerenciamento de transações e payments
  - name: Wallets
    description: Saldo, extrato e resumo da carteira de um recebedor, agrupados por moeda
  - name: Webhooks
    description: Configuração, gerenciamento e histórico de entregas de webhooks
  - name: Withdrawals
    description: Solicitação e acompanhamento de saques (payouts) por recipient
paths:
  /refunds/{id}/confirm:
    post:
      tags:
        - Refunds
      summary: Confirmar reembolso realizado
      description: >-
        Marca como `refunded` um reembolso de boleto cuja transferência já foi
        feita pela própria conta. Disponível apenas quando a devolução é
        executada pela conta, e não pela plataforma — nesse caso quem confirma é
        a Z2Pay. Dispara o webhook `refund.refunded`.
      operationId: RefundController_confirmRefund
      parameters:
        - name: id
          in: path
          required: true
          description: ID do refund
          schema:
            type: string
        - name: Idempotency-Key
          in: header
          required: false
          description: Chave única para garantir idempotência da requisição
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                transferNote:
                  type: string
                  maxLength: 1000
                  nullable: true
                  description: >-
                    Como a transferência foi feita — meio, data e identificador
                    (ex: `PIX 10/09, E12345678`). Obrigatória quando o reembolso
                    está em `awaiting_bank_details`.
              default: {}
      responses:
        '200':
          description: Reembolso confirmado
        '400':
          description: >-
            Nota da transferência obrigatória — o reembolso não tem dados
            bancários registrados
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Identificador estável do erro. É por ele que você deve
                          ramificar, não pela mensagem.
                      message:
                        type: string
                        description: >-
                          Descrição legível. Pode mudar sem aviso e não deve ser
                          usada em condicional.
                      issues:
                        type: array
                        description: >-
                          Um item por campo rejeitado. Nunca vem vazio: se há
                          400 de validação, há pelo menos um.
                        items:
                          type: object
                          properties:
                            path:
                              type: string
                              description: >-
                                Campo que falhou. Vem vazio quando o erro é do
                                corpo como um todo.
                            message:
                              type: string
                              description: O que há de errado com esse campo.
              example:
                error:
                  code: VALIDATION_ERROR
                  message: Validation failed
                  issues:
                    - path: status
                      message: >-
                        Status inválido. Valores aceitos: pending,
                        waiting_payment, paid, refused, canceled, refunded
                    - path: startDate
                      message: >-
                        Data deve ser ISO 8601 com timezone (ex.:
                        2026-06-24T00:00:00Z)
        '401':
          description: Chave de API ausente, malformada ou inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Identificador estável do erro. É por ele que você deve
                          ramificar, não pela mensagem.
                      message:
                        type: string
                        description: >-
                          Descrição legível. Pode mudar sem aviso e não deve ser
                          usada em condicional.
              example:
                error:
                  code: UNAUTHORIZED
                  message: Invalid API key
        '404':
          description: Refund não encontrado
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Identificador estável do erro. É por ele que você deve
                          ramificar, não pela mensagem.
                      message:
                        type: string
                        description: >-
                          Descrição legível. Pode mudar sem aviso e não deve ser
                          usada em condicional.
              example:
                error:
                  code: NOT_FOUND
                  message: Refund not found
        '409':
          description: >-
            Reembolso pago pela plataforma (confirmação é da Z2Pay), status que
            não permite confirmação — ou a mesma Idempotency-Key ainda está em
            curso
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Identificador estável do erro. É por ele que você deve
                          ramificar, não pela mensagem.
                      message:
                        type: string
                        description: >-
                          Descrição legível. Pode mudar sem aviso e não deve ser
                          usada em condicional.
              example:
                error:
                  code: CONFLICT
                  message: No refundable payment found
        '422':
          description: >-
            Idempotency-Key já usada com um corpo diferente. Use uma chave nova
            para uma operação diferente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: >-
                      Mensagem do conflito de idempotência. Aqui `error` é
                      texto, não objeto — ramifique pelo status HTTP.
              example:
                error: Idempotency key already used with a different request body
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: API Key da Credential (gerada no Backoffice)

````