docs
Endpoints

Request Refund

Overview

The PUT /api/pix/:e2eid/devolucao/:id endpoint requests a refund for a received PIX. You provide the End to End ID (e2eid) of the original PIX and a refund identifier generated by your system.

The refund can be full or partial. The sum of all refunds cannot exceed the original PIX amount.

Endpoint

PUT https://api.fypay.me/api/pix/{e2eid}/devolucao/{id}

Authentication

stringobrigatorio

Bearer token obtained from POST https://api.fypay.me/api/auth/token. This route does not use a client certificate.

URL Parameters

e2eidstringobrigatorio

Identifier of the received PIX to be refunded. Accepts the End to End ID (data.endToEndId from the RECEIVE webhook) or the numeric FyPay transaction ID (loc.id of the charge or data.id of the webhook).

Example: E12345678202401151030abcdefghijk

idstringobrigatorio

Identifier generated by your system to represent the refund. Up to 100 characters and unique per account: reusing an id returns 400 with the code PIX_DUPLICATE_EXTERNAL_ID.

Example: D123456789

Request Body

stringobrigatorio

Requested refund amount. String in decimal format with exactly 2 decimal places (^\d{1,10}\.\d{2}$).

The sum of all refunds cannot exceed the original PIX amount.

Example: "7.89"

string

Refund nature: ORIGINAL or RETIRADA. Accepted for compatibility with the Central Bank standard and returned in the response. Today every refund is processed as a regular refund, regardless of this field.

string

Text shown to the payer with information about the refund.

Maximum: 140 characters.

Request

curl -X PUT https://api.fypay.me/api/pix/E12345678202401151030abcdefghijk/devolucao/D123456789 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "valor": "7.89",
    "descricao": "Devolução solicitada pelo recebedor"
  }'
const e2eid = 'E12345678202401151030abcdefghijk';
const refundId = 'D123456789';

const response = await fetch(
  `https://api.fypay.me/api/pix/${e2eid}/devolucao/${refundId}`,
  {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      valor: '7.89',
      descricao: 'Devolução solicitada pelo recebedor',
    }),
  }
);

const refund = await response.json();
import requests

e2eid = 'E12345678202401151030abcdefghijk'
refund_id = 'D123456789'

response = requests.put(
    f'https://api.fypay.me/api/pix/{e2eid}/devolucao/{refund_id}',
    headers={
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json',
    },
    json={
        'valor': '7.89',
        'descricao': 'Devolução solicitada pelo recebedor',
    }
)

refund = response.json()

Response

{
  "id": "D123456789",
  "rtrId": "00000000000000000000000000000789",
  "valor": "7.89",
  "natureza": "ORIGINAL",
  "descricao": "Devolução solicitada pelo recebedor",
  "horario": {
    "solicitacao": "2024-01-15T10:30:00.000Z"
  },
  "status": "EM_PROCESSAMENTO"
}
{
  "statusCode": 400,
  "code": "PIX_REFUND_EXCEEDS_AVAILABLE",
  "message": "Refund value (R$ 25.00) exceeds available amount to refund (R$ 20.00)",
  "userMessage": "Valor do reembolso excede o valor disponível.",
  "errorId": "c0a8012e-7b1f-4c55-9d1e-2f9a8c3b4d5e"
}
{
  "statusCode": 404,
  "code": "PIX_TRANSACTION_NOT_FOUND",
  "message": "Transaction with e2eId E12345678202401151030abcdefghijk not found",
  "userMessage": "Transação não encontrada.",
  "errorId": "c0a8012e-7b1f-4c55-9d1e-2f9a8c3b4d5e"
}

Response Fields

idstring

Refund identifier (the same value sent in the URL).

rtrIdstring

Refund identifier at FyPay: the internal ID of the refund transaction, left-padded with zeros to 32 characters. It is not the refund End to End ID; that one arrives in data.refunds[0].endToEndId in the REFUND webhook.

valorstring

Refund amount, string with 2 decimal places.

naturezastring

The natureza value sent (ORIGINAL or RETIRADA), or ORIGINAL if omitted.

descricaostring

The descricao text sent, when present.

horarioobject

statusstring

Refund status at response time:

  • EM_PROCESSAMENTO: refund being processed (normal case)
  • DEVOLVIDO: refund already settled
  • NAO_REALIZADO: refund failed
motivostring

Present only when status = NAO_REALIZADO, with the text Erro ao processar devolução.

The final refund result arrives through the REFUND webhook, on the URLs registered for the refund_in event with the PIX BACEN format.

Refund Webhook

When the refund is processed, you receive a REFUND webhook (excerpt):

{
  "data": {
    "id": 12345,
    "txId": "7978c0c97ea847e78e8849634473c1f1",
    "status": "REFUNDED",
    "payment": {
      "amount": "100",
      "currency": "BRL"
    },
    "refunds": [
      {
        "status": "LIQUIDATED",
        "payment": {
          "amount": 7.89,
          "currency": "BRL"
        },
        "errorCode": null,
        "eventDate": "2024-01-15T10:30:00.000Z",
        "endToEndId": "D12345678202401151030abcdefghijk",
        "information": "Devolução solicitada pelo recebedor"
      }
    ],
    "endToEndId": "E12345678202401151030abcdefghijk",
    "creditDebitType": "DEBIT"
  },
  "type": "REFUND"
}

REFUND Webhook

See the full REFUND webhook documentation

Refund Deadline

Refunds can be requested up to 89 days after the original PIX was received. After that the API responds 400 with the code PIX_REFUND_DEADLINE_EXCEEDED.

Partial Refunds

You can request several partial refunds for the same PIX, each with its own id:

await requestRefund(e2eid, 'DEV001', '30.00');

await requestRefund(e2eid, 'DEV002', '50.00');

await requestRefund(e2eid, 'DEV003', '25.00');

If the original PIX was R$ 100.00, the first two add up to R$ 80.00 and the third fails with 400 PIX_REFUND_EXCEEDS_AVAILABLE, because only R$ 20.00 remains to be refunded.

Common Errors

HTTP codecodeCause
400PUB_REQUEST_BODY_INVALIDvalor in the wrong format, invalid natureza or descricao over 140 characters
400PIX_DUPLICATE_EXTERNAL_IDRefund id already used on this account
400PIX_REFUND_EXCEEDS_AVAILABLEAmount above the balance still available for refund
400PIX_REFUND_DEADLINE_EXCEEDEDMore than 89 days since the original PIX
400PIX_INVALID_TRANSACTION_TYPE_FOR_REFUNDThe transaction is not a received PIX
400PIX_INVALID_TRANSACTION_STATEThe original transaction is not in a state that allows refunds
400PIX_TRANSACTION_ACCOUNT_MISMATCHThe transaction belongs to another account
401Missing, invalid or expired token
404PIX_TRANSACTION_NOT_FOUNDNo PIX found for the given e2eid

Next Steps

On this page