Skip to main content
BVNK

Refund Payments

When a payment exception occurs, BVNK offers automatic cryptocurrency refunds for partners who do not wish to hold these assets due to compliance concerns or who prefer not to process payments outside agreed payment rules.

important

This refund flow generates a payout link that must be forwarded to the end user, allowing them to provide their wallet address and accept the refund.

If you want funds returned directly to the sender's wallet address with no end-user action required, see Refund to source address.

How a refund works​

Refunds are automatically generated payout requests that must be sent to the end user for completion. The user enters their preferred wallet address and confirms the payout.

note

Contact your Merchant Support or Integration Manager to enable the refund options.

Refund exception scenarios​

There are three payment exception scenarios to consider:

  • Overpayments
  • Underpayments
  • Late payments

Each scenario processes refunds differently, as explained below.

warning

If you use walletID in the request that triggers the webhook, you will also receive this field in the webhook response. You can ignore merchantID, as it will be discontinued soon.

When an overpayment occurs, the transaction status updates from PROCESSING to COMPLETE. Treat this COMPLETE status as a standard successful payment.

The original invoice amount is credited to the merchant's wallet as usual. The excess overpaid amount is deposited into a holding account, ensuring the merchant's wallet balance is unaffected.

This additional amount is returned to the sender as an automatically generated payout.

Refund flow​

The typical flow for an automatically generated refund is as follows:

  1. The merchant creates the payment request for an end user.
  2. The merchant forwards the payment link returned from BVNK to the end user.
  3. The end user completes the payment by sending funds to the given address.
  4. The total funds amount is too low, too high, or received late, triggering the appropriate refund.
  5. BVNK sends a webhook notification to the merchant, specifying the amount to refund and the URL where it can be claimed.
  6. The merchant notifies the end user about the URL.
  7. The end user navigates to the URL and enters their wallet address.
  8. Once BVNK receives this address, the displayed amount of cryptocurrency is sent through, less the fees.
  9. The merchant receives a relevant webhook that updates the success of the refund payout.
  10. The process is complete.

Expired refund​

If the end user does not enter their wallet address and confirm the refund within the expiry limit:

  1. The refund status changes to EXPIRED. The default expiry limit is three months.
  2. When the limit is reached, the refund amount is transferred from the holding account to the merchant's MID wallet.
  3. A further webhook is sent to the merchant to indicate that the refund has expired and the amounts have been credited to the appropriate wallet.

Refund webhook​

BVNK automatically initiates the refund process, which functions as a payout transaction.

You will receive a refundInitiated event webhook. Review the following webhook fields:

Webhook fieldDescription
event: refundIntiatedEvent type indicating that the refund has been initiated.
data.uuid: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxUUID of the refund, different to the linked incoming payment.
data.type: OUTType. For a refund, it is always set to OUT.
data.subType: merchantRefundSubtype indicating it is a Merchant refund.
data.status: PENDINGStatus of a refund. Possible options: EXPIRED or COMPLETE.
data.redirectUrl: https://pay.bvnk.com/payout?uuid=URL to send to the end user, allowing them to enter their address and claim the refund.

If the refund is not claimed and expires, a statusChanged event webhook is sent to the merchant. The key fields in this webhook are:

Webhook fieldDescription
event: statusChangedEvent type indicating that the refund has had its status changed.
data.uuid: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxMatching UUID of the refund.
data.subType: merchantRefundSubtype indicating it is a Merchant refund.
data.status: EXPIREDFinal state of the expired payment.

For more details, see the Refund webhook reference.

Auto-refund to source address​

Auto-refund to source address enables eligible transactions to be automatically refunded directly to the originating source address. This eliminates the need for refund links that end users must open and claim, helping resolve LATE, OVERPAID, or UNDERPAID payments more quickly.

Enable auto-refund to source address​

Contact your Account Manager to enable this feature. It can be configured per wallet and activated for any combination of exception types:

How it works​

When auto-refund to source address is enabled and a payment exception occurs, funds are sent back to the blockchain address that originated the payment.

The process depends on the type of wallet used by the end user:

Wallet typeBehaviour
Self-hosted walletFunds immediately appear back in the end user's original wallet. No further action is needed.
Centralised exchange (CEX)The refund is sent to the exchange's pooled account. The end user must submit the transaction hash to their exchange to have the funds credited to their account.

Supported currencies​

Auto-refund to source address is supported for the following currencies:

  • ETH
  • USDT
  • USDC
  • BNB
  • PYUSD
  • XRP
  • SOL
  • POL
  • TRX
BTC is not supported

Bitcoin uses a UTXO-based model where transactions can have multiple inputs, making the source address ambiguous. For BTC payments, the standard refund process (refund link) still applies.

For unsupported currencies, the standard refund link flow described above applies.

Webhook notifications​

When a payment exception occurs and auto-refund to source address is enabled, you receive webhook notifications for both the exception event and the refund event.

Late payment webhook:

{
"event": "statusChanged",
"data": {
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "EXPIRED",
"type": "IN",
"subType": "merchantPayIn"
}
}

Auto-refund initiated webhook:

{
"event": "refundInitiated",
"data": {
"uuid": "f9e8d7c6-b5a4-3210-fedc-ba0987654321",
"type": "OUT",
"subType": "merchantRefund",
"status": "PROCESSING"
}
}

When the refund completes, a statusChanged webhook is sent with "status": "COMPLETE".

Was this page helpful?