Mechanism for validating withdrawals via webhooks

A way to confirm transfers through a special Webhook.

Set up withdrawal validation via Webhook

This mechanism lets your application authorize or refuse outgoing operations before they are processed by Asaas.

Even if a request has been authenticated with a valid API key, the operation will only be executed after your application approves it.

📘

By the end of this guide, you will have configured a Webhook to validate outgoing operations and will know how to respond with an approval or refusal.

When to use it

Use this mechanism to apply additional controls, such as:

  • validating the origin of the operation;
  • checking amounts and recipients;
  • operational limits;
  • anti-fraud rules;
  • identifying misuse of the API key.

The mechanism can be applied to transfers, bill payments, Pix QR Code payments, mobile phone top-ups and, optionally, Pix refunds and Payment Split settlements.

How it works

  1. Your application requests the operation and stores the data returned by Asaas.
  2. Approximately five seconds later, Asaas sends a POST to the configured URL.
  3. Your application compares the received payload with the registered operation.
  4. Your application responds with APPROVED or REFUSED.
  5. Asaas executes or cancels the operation according to the response.
⚠️

If the call to your Webhook fails three times or does not return a valid status, the operation will be canceled.

1. Enable the mechanism

Go to User menu > Integrations > Security mechanisms.

Provide:

  • the URL that will receive the validation requests;
  • the email for error notifications;
  • an authentication token.

The token is optional, but we recommend using it. Asaas will send it in the header:

asaas-access-token: your_token

Your application must validate this value before processing the request.

🚧

Attention

After activation, all transfers and other withdrawal operations performed through the API will be subject to validation.

Operations performed through the interface

You can also enable validation for operations requested through the web interface.

In this case, operations performed through both the API and the interface will go through the same flow.

Pix refunds

📘

To also validate Pix refunds, check the Enable withdrawal authorization for Pix refunds option.

This setting is optional and independent of the validation of other withdrawals.

Payment Split settlement

📘

To also validate Payment Split settlements, check the Enable withdrawal authorization for Payment Splits option.

This setting is optional and independent of the validation of other withdrawals.

In this case, the validation Webhook is sent approximately five seconds after the Split settlement, which occurs when the charge is paid.

While the option is enabled, all Payment Split settlements go through validation, regardless of the setting for operations performed through the interface.

Subaccounts

📘

The root account's configuration is automatically applied to subaccounts, including BaaS and non-BaaS operations.

2. Prepare your application

Before approving an operation, validate:

  • whether the request originated from your system;
  • whether the received ID matches the registered operation;
  • whether the amount, recipient, and other information remain intact;
  • whether the operation complies with internal limits and rules;
  • whether the token sent in the header is valid;
  • whether there are signs of misuse of the API key.
⚠️

Do not approve an operation just because the payload has a valid structure.

Compare the received data with the request previously registered by your application.

3. Identify the operation type

The type field indicates which operation needs to be validated.

Operationtype valueObject sent
TransferTRANSFERtransfer
Bill paymentBILLbill
Pix QR Code paymentPIX_QR_CODEpixQrCode
Mobile phone top-upMOBILE_PHONE_RECHARGEmobilePhoneRecharge
Pix refundPIX_REFUNDpixRefund
Payment Split settlementPAYMENT_SPLITpaymentSplit

Payload examples

Transfer

{
  "type": "TRANSFER",
  "transfer": {
    "object": "transfer",
    "id": "0bed986c-737d-49bf-a1cc-beca916797c4",
    "dateCreated": "2022-05-27",
    "status": "PENDING",
    "effectiveDate": null,
    "type": "BANK_ACCOUNT",
    "value": 22,
    "netValue": 22,
    "transferFee": 0,
    "scheduleDate": "2022-05-27",
    "confirmedDate": null,
    "failReason": null,
    "bankAccount": {
      "bank": {
        "code": null,
        "ispb": "00000000",
        "name": null
      },
      "accountName": "ASAAS GESTAO FINANCEIRA S.A.",
      "ownerName": "ASAAS GESTAO FINANCEIRA S.A.",
      "cpfCnpj": "70609293000194",
      "agency": "4124",
      "agencyDigit": null,
      "account": "42142",
      "accountDigit": "1",
      "pixAddressKey": null
    },
    "transactionReceiptUrl": null,
    "operationType": "PIX",
    "description": null
  }
}

Bill payment

{
  "type": "BILL",
  "bill": {
    "object": "bill",
    "id": 623471,
    "status": "PENDING",
    "value": 20.0,
    "discount": 0,
    "interest": 0,
    "fine": 0,
    "identificationField": "23793381286001234107143000012345890460000002000",
    "dueDate": "2024-01-01",
    "scheduleDate": "2024-01-01",
    "paymentDate": null,
    "fee": 0,
    "description": null,
    "companyName": null,
    "transactionReceiptUrl": null,
    "canBeCancelled": true,
    "failReasons": null,
    "bankId": 4,
    "awaitingCriticalActionAuthorization": false,
    "bank": {
      "object": "bank",
      "id": 4,
      "code": "237",
      "name": "Bradesco"
    }
  }
}

Pix QR Code payment

{
  "type": "PIX_QR_CODE",
  "pixQrCode": {
    "id": "aa10c444-3f02-40e7-a248-2d00cff5a45d",
    "endToEndIdentifier": "E1954055020220714160403012347510",
    "finality": null,
    "value": 2,
    "changeValue": null,
    "refundedValue": 0,
    "effectiveDate": "2022-07-14 13:04:03",
    "scheduledDate": null,
    "status": "AWAITING_REQUEST",
    "type": "DEBIT",
    "originType": "STATIC_QRCODE",
    "conciliationIdentifier": null,
    "description": null,
    "transactionReceiptUrl": null,
    "refusalReason": null,
    "canBeCancelled": true,
    "originalTransaction": null,
    "externalAccount": {
      "ispb": 18236120,
      "ispbName": "NU PAGAMENTOS S.A. - INSTITUIÇÃO DE PAGAMENTO",
      "name": "John Doe",
      "cpfCnpj": "***.123.456-**",
      "addressKey": "[email protected]",
      "addressKeyType": "EMAIL"
    },
    "qrCode": {
      "payer": null,
      "conciliationIdentifier": null,
      "originalValue": 1.00,
      "dueDate": null,
      "interest": 0,
      "fine": 0,
      "discount": 0,
      "expirationDate": null
    },
    "payment": null
  }
}

Mobile phone top-up

{
  "type": "MOBILE_PHONE_RECHARGE",
  "mobilePhoneRecharge": {
    "id": "d29f7fdb-4cf9-4524-a44e-d1f3fd9ec0d3",
    "value": 20,
    "phoneNumber": "47999999999",
    "status": "PENDING",
    "canBeCancelled": true,
    "operatorName": "Claro"
  }
}

Pix refund

{
  "type": "PIX_REFUND",
  "pixRefund": {
    "id": "06391ba9-cbf9-4926-8988-374ac5d71cae",
    "transferId": "f3956d6d-6dbb-4882-8146-9df82288d95b",
    "endToEndIdentifier": null,
    "finality": null,
    "value": 200,
    "changeValue": null,
    "refundedValue": 0,
    "dateCreated": "17/12/2024 15:27:42",
    "effectiveDate": "17/12/2024 15:27:42",
    "scheduledDate": null,
    "status": "AWAITING_REQUEST",
    "type": "CREDIT_REFUND",
    "originType": null,
    "conciliationIdentifier": null,
    "description": null,
    "transactionReceiptUrl": null,
    "chargedFeeValue": 0,
    "canBeRefunded": false,
    "refundDisabledReason": "The type of this transaction does not allow it to be refunded.",
    "refusalReason": null,
    "canBeCancelled": false,
    "originalTransaction": {
      "id": "b9852968-7825-4458-b069-d266ce8455c9",
      "endToEndIdentifier": "6709a838-7422-4198-94ed-76166a70c595",
      "value": 1000,
      "effectiveDate": "17/12/2024 15:26:57"
    },
    "externalAccount": {
      "ispb": 19540550,
      "ispbName": "ASAAS GESTÃO FINANCEIRA INSTITUIÇÃO DE PAGAMENTO S.A.",
      "name": "John Doe",
      "agency": "0",
      "account": "0000000",
      "accountDigit": "0",
      "accountType": "CHECKING_ACCOUNT",
      "cpfCnpj": "***.138.240-**",
      "addressKey": null,
      "addressKeyType": null
    },
    "qrCode": null,
    "payment": "pay_e4xnd1cc04w2n33n",
    "addressKey": null,
    "addressKeyType": null,
    "externalReference": null
  }
}

Payment Split settlement

{
  "type": "PAYMENT_SPLIT",
  "paymentSplit": {
    "id": "157ac22a-6edd-4c46-8094-d78ca03f16a9",
    "status": "AWAITING_CREDIT",
    "payment": {
      "id": "pay_wnv5k3idzzbm1rte",
      "confirmedDate": "23/09/2026",
      "invoiceNumber": "00174367",
      "externalReference": null
    },
    "walletId": "64e8b366-903f-4112-aaff-da2220df0b62",
    "creditDate": null,
    "fixedValue": 40,
    "totalValue": 45.3,
    "description": "Split description",
    "originAccountId": "09ab105a-8f47-4dd2-bb45-4fcec3d8eb1a",
    "percentualValue": 5.5,
    "externalReference": "teste0002",
    "cancellationReason": null,
    "destinationAccountId": "6bbdd5f3-e224-4a0a-b9fc-330815117f0a"
  }
}
🚧

Split cancellation during validation

The Split is canceled when your application returns REFUSED, does not return a valid status, or the Webhook fails three consecutive times. In this case, the amount returns to the Split's origin account.

The cancellation reason can be checked in the cancellationReason field through the split query endpoints, such as List paid splits and List received splits:

  • for the Split's origin account (the one that created the Split), the reason is EXTERNAL_AUTHORIZATION_REFUSED;
  • for the Split's destination account (the recipient account), the cancellation is shown generically as PAYMENT_SPLIT_VALIDATION_FAILED, without specifying that the cause was the external authorization.

No Webhook is sent to report the cancellation, and the PAYMENT_SPLIT_CANCELLED event is not triggered. The refuseReason provided in the response is also not shown on the Split.

4. Respond to the validation

After analyzing the payload, respond to the POST itself with one of the following statuses:

StatusResult
APPROVEDThe operation was recognized and can proceed
REFUSEDThe operation must be refused

Approve an operation

{
  "status": "APPROVED"
}

Refuse an operation

You can also provide the reason for the refusal in the refuseReason field:

{
  "status": "REFUSED",
  "refuseReason": "Transfer not found in our database"
}

How to confirm the result

When your application returns APPROVED, Asaas proceeds with processing the operation.

The operation will be canceled when:

  • your application returns REFUSED;
  • the response does not contain APPROVED or REFUSED;
  • the Webhook fails three consecutive times.

Implementation precautions

  • register the operation before receiving the validation;
  • use the ID to avoid duplicate approvals;
  • validate the token received in asaas-access-token;
  • do not approve unknown operations;
  • keep logs of the decisions made;
  • monitor failures on the configured endpoint;
  • respond only after completing all necessary validations.

Did this page help you?