Refund Payments
Refunding payments automatically after a payment exception scenario occurs.
In the case where a payment exception scenario has taken place, BVNK provides the option to automatically refund the cryptocurrency for merchants who do not want to hold these cryptocurrencies, due to any compliance issues, or for merchants that do not want to internally process any payments that have fallen outside of the agreed upon payment rules.
Auto Refund does not automatically return the funds to the sender's address.Instead, it generates a payout and sends a URL via webhook. This URL should be forwarded to the end user, allowing them to provide their address and accept the refund.
How a refund works
Refunds function as an automatically generated payout request, which needs to be sent to the end user to complete. In this case, the user needs to enter their desired wallet address to which they want the funds sent and confirm the payout.
Refund exception scenarios
As stated on the previous pages, the three payment exception scenarios to consider are:
- Overpayments
- Underpayments
- Late payments
These three scenarios are handled separately on a Merchant ID (MID) level. It means that each created MID can be configured to automatically initiate the refund process for one or more of these scenarios. Each scenario handles the refund slightly differently, as explained below.
Contact your Merchant Support or Integration Manager to have the refund options enabled.
Overpayments
When an overpayment has occurred, the status of the transaction is updated from PROCESSING
to COMPLETE
. This COMPLETE
status should be seen as a standard successful payment on the merchant's side.
The original payment amount requested in the invoice is credited to the merchant's wallet as usual. Still, the additional amount of overpaid cryptocurrency is deposited into a holding account, ensuring no impact on the merchant's wallet balance.
This additional amount is then the total amount that will be returned to the sender as an automatically generated payout.
Underpayments
When an underpayment has occurred, the status of the transaction is updated from PROCESSING
to UNDERPAID
. This UNDERPAID
status should be marked as an unsuccessful payment on the merchant's side.
The entire payment amount is deposited into a holding account, ensuring it is not credited to the merchant's wallet.
The full payment amount of the underpayment is then the total amount that will be returned to the sender as an automatically generated payout.
Late payments
In the rare occurrence that a late payment has occurred, the status of the transaction is updated from PENDING
to EXPIRED
. This EXPIRED
status should be marked as an unsuccessful payment on the merchant's side.
The entire payment amount is deposited into a holding account, ensuring it is not credited to the merchant's wallet.
The full payment amount for the late payment is then the total amount that will be returned to the sender as an automatically generated payout.
Refund flow
The ideal flow of an automatically generated refund is given as follows:
- The merchant creates the payment request for an end user.
- The merchant forwards the payment link returned from BVNK to the end user.
- The end user completes the payment by sending funds to the given address.
- The total funds amount is too low, too high, or received late, triggering the appropriate refund.
- BVNK sends a webhook notification to the merchant, specifying the amount to refund and the URL where it can be claimed.
- The merchant notifies the end user about the URL.
- The end user navigates to the URL and enters their wallet address.
- Once BVNK receives this address, the displayed amount of cryptocurrency is sent through, less the fees.
- The merchant receives a relevant webhook that updates the success of the refund payout.
- The process is complete.
Expired refund
If the end user never entered their wallet address and confirms the refund within the expiry limit,
- The refund will become
EXPIRED
. The default expiry limit for a refund is set to three months. - When the limit is reached, the total refund amount will be transferred from the held account to the merchant's MID wallet.
- 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 webhooks
BVNK automatically initiates the refund process, which in effect acts as a payout transaction.
The merchant will receive a refundInitiated
event webhook. Pay attention to the following webhook fields:
Webhook field | Description |
---|---|
event: refundIntiated | Event type indicating that the refund has been initiated. |
data.uuid: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx | UUID of the refund, different to the linked incoming payment. |
data.type: OUT | Type. For a refund, it is always set to OUT . |
data.subType: merchantRefund | Subtype indicating it is a Merchant refund. |
data.status: PENDING | Status 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 has expired, a statusChanged
event webhook is sent to the merchant. The important fields in this webhook are the following:
Webhook field | Description |
---|---|
event: statusChanged | Event type indicating that the refund has had its status changed. |
data.uuid: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx | Matching UUID of the refund. |
data.subType: merchantRefund | Subtype indicating it is a Merchant refund. |
data.status: EXPIRED | Final state of the expired payment. |
{
"source": "payment",
"event": "refundInitiated",
"data": {
"uuid": "9485895b-c4a3-4885-bcdc-XXXXXXXXXX",
"merchantDisplayName": "Merchant Name",
"merchantId": "00a4af9d-ad4b-42d5-bec4-XXXXXXXXXX",
"dateCreated": 1689264437804,
"expiryDate": 1689869237804,
"quoteExpiryDate": null,
"acceptanceExpiryDate": null,
"quoteStatus": "TEMPLATE",
"reference": "REFUND-XXXXX",
"type": "OUT",
"subType": "merchantRefund",
"status": "PENDING",
"displayCurrency": {
"currency": "EUR",
"amount": 24.58,
"actual": 0
},
"walletCurrency": {
"currency": "ETH",
"amount": 0.01421,
"actual": 0
},
"paidCurrency": {
"currency": null,
"amount": 0,
"actual": 0
},
"feeCurrency": {
"currency": "EUR",
"amount": 0.49,
"actual": 0.49
},
"displayRate": null,
"exchangeRate": null,
"address": null,
"returnUrl": "",
"redirectUrl": "https://pay.sandbox.bvnk.com/payout?uuid=9485895b-c4a3-4885-bcdc-XXXXXXXXXX",
"transactions": [],
"refund": {
"uuid": "309d82fd-e1d4-4354-9015-XXXXXXXXXX",
"merchantDisplayName": "Merchant Name",
"merchantId": "00a4af9d-ad4b-42d5-bec4-XXXXXXXXXX",
"dateCreated": 1689264326000,
"expiryDate": 1689265526000,
"quoteExpiryDate": 1689265526000,
"acceptanceExpiryDate": 1689264363000,
"quoteStatus": "ACCEPTED",
"reference": "reference",
"type": "IN",
"subType": "merchantPayIn",
"status": "COMPLETE",
"displayCurrency": {
"currency": "EUR",
"amount": 10,
"actual": 10
},
"walletCurrency": {
"currency": "EUR",
"amount": 10,
"actual": 10
},
"paidCurrency": {
"currency": "ETH",
"amount": 0.00579,
"actual": 0.02
},
"feeCurrency": {
"currency": "EUR",
"amount": 0.1,
"actual": 0.1
},
"displayRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1727.070973981676
},
"exchangeRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1727.071668
},
"address": {
"address": "0x434c932fc5e324204c80c1fb15f3a7XXXXX",
"tag": null,
"protocol": "ETH",
"uri": "ethereum:0x434c932fc5e324204c80c1fb15f3a7XXXXX?value=5.79015E+15",
"alternatives": []
},
"returnUrl": "",
"redirectUrl": "https://pay.sandbox.bvnk.com/payin?uuid=309d82fd-e1d4-4354-9015-XXXXXXXXXX",
"transactions": [
{
"dateCreated": 1689264367000,
"dateConfirmed": 1689264429000,
"hash": "0x034612080ab226a5c3254b521f30dafd7df30dd1c1fc35723cf6XXXXX",
"amount": 0.02,
"risk": {
"level": "LOW",
"resourceName": "UNKNOWN",
"resourceCategory": "UNKNOWN",
"alerts": []
},
"networkFeeCurrency": "ETH",
"networkFeeAmount": 0.0000315,
"sources": [
"0x4b8b57aa7a92ea959c92aa32a72bbXXXXX3"
],
"displayRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1727.070973981676
},
"exchangeRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1727.071668
}
}
],
"refund": null,
"refunds": []
},
"refunds": []
}
}
{
"source": "payment",
"event": "statusChanged",
"data": {
"uuid": "9485895b-c4a3-4885-bcdc-XXXXXXXXXX",
"merchantDisplayName": "Merchant Name",
"merchantId": "00a4af9d-ad4b-42d5-bec4-XXXXXXXXXX",
"dateCreated": 1689264438000,
"expiryDate": 1689264510403,
"quoteExpiryDate": 1689275310395,
"acceptanceExpiryDate": 1689264540395,
"quoteStatus": "ACCEPTED",
"reference": "REFUND-XXXXX",
"type": "OUT",
"subType": "merchantRefund",
"status": "EXPIRED",
"displayCurrency": {
"currency": "EUR",
"amount": 24.58,
"actual": 0
},
"walletCurrency": {
"currency": "EUR",
"amount": 23.49968,
"actual": 23.49968
},
"paidCurrency": {
"currency": null,
"amount": 0,
"actual": 0
},
"feeCurrency": {
"currency": "EUR",
"amount": 0.49,
"actual": 0.49
},
"displayRate": null,
"exchangeRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1653.7602177875
},
"address": null,
"returnUrl": "",
"redirectUrl": "https://pay.sandbox.bvnk.com/payout?uuid=9485895b-c4a3-4885-bcdc-XXXXXXXXXX",
"transactions": [],
"refund": {
"uuid": "309d82fd-e1d4-4354-9015-XXXXXXXXXX",
"merchantDisplayName": "Metallica Inc",
"merchantId": "00a4af9d-ad4b-42d5-bec4-XXXXXXXXXX",
"dateCreated": 1689264326000,
"expiryDate": 1689265526000,
"quoteExpiryDate": null,
"acceptanceExpiryDate": null,
"quoteStatus": "TEMPLATE",
"reference": "XXXXXXXXXX",
"type": "IN",
"subType": "merchantPayIn",
"status": "COMPLETE",
"displayCurrency": {
"currency": "EUR",
"amount": 10,
"actual": 10
},
"walletCurrency": {
"currency": "EUR",
"amount": 10,
"actual": 10
},
"paidCurrency": {
"currency": "ETH",
"amount": 0.00579,
"actual": 0.02
},
"feeCurrency": {
"currency": "EUR",
"amount": 0.1,
"actual": 0.1
},
"displayRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1727.070973981676
},
"exchangeRate": null,
"address": null,
"returnUrl": "",
"redirectUrl": "https://pay.sandbox.bvnk.com/payin?uuid=309d82fd-e1d4-4354-9015-XXXXXXXXXX",
"transactions": [
{
"dateCreated": 1689264367000,
"dateConfirmed": 1689264429000,
"hash": "0x034612080ab226a5c3254b521f30dafd7df30dd1c1fc35723cf638XXXXX",
"amount": 0.02,
"risk": {
"level": "LOW",
"resourceName": "UNKNOWN",
"resourceCategory": "UNKNOWN",
"alerts": []
},
"networkFeeCurrency": "ETH",
"networkFeeAmount": 0.0000315,
"sources": [
"0x4b8b57aa7a92ea959c92aa32a72bb3dXXXXX7"
],
"displayRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1727.070973981676
},
"exchangeRate": {
"base": "ETH",
"counter": "EUR",
"rate": 1727.071668
}
}
],
"refund": null,
"refunds": []
},
"refunds": []
}
}
Updated 6 days ago