In your marketplace, you can set up a schedule to automatically transfer funds between balance accounts. In addition to or instead of that, you can transfer funds between balance accounts on-demand.
Requirements
- Make sure that your server can receive and accept webhooks, and that you subscribed to the Transfer webhooks in your Customer Area.
- Ask our Support Team to enable transfers for the balance account that initiates the transfer request.
- If the balance accounts involved in the transfer do not belong to the same account holder, check the capabilities of the account holders:
- The account holder of the balance account that sends the the transfer request must have the sendToBalanceAccount capability.
- The account holder of the balance account that receives the transfer request must have the receiveFromBalanceAccount capability.
Initiate an internal transfer
Select the following tabs to learn how to initiate transfers between balance accounts using your Customer Area, or using an API call.
To move funds between balance accounts, make a POST /transfers request.
In the body of the request, specify the following fields:
Parameter | Required | Description |
---|---|---|
amount | ![]() |
An object containing the currency and value of the transfer. |
balanceAccountId | ![]() |
The unique identifier of the source balance account: the balance account that initiates the transfer request. |
counterparty.balanceAccountId | ![]() |
The unique identifier of the target balance account: the balance account that receives the transfer. The funds are credited to this balance account. |
category | ![]() |
Set to internal. |
description | Your description of the transfer. You can use this to identify the transfer in the webhooks that you receive. | |
reference | Your unique reference for the transfer. You can use this to identify the transfer in the webhooks that you receive. | |
referenceForBeneficiary | Text to inform the recipient about the push or pull transfer. This reference is also included in all webhooks. Supported characters: a-z, A-Z, 0-9. |
The following example shows how to push EUR 100 from your liable balance account to your user's balance account.
curl https://balanceplatform-api-test.adyen.com/btl/v4/transfers \ -H 'x-api-key: ADYEN_BALANCE_PLATFORM_API_KEY' \ -H 'content-type: application/json' \ -X POST \ -d '{ "amount": { "currency": "EUR", "value": 10000 }, "balanceAccountId": "BA00000000000000000000001", "counterparty": { "balanceAccountId": "BA00000000000000000000002" }, "category" : "internal", "referenceForBeneficiary": "Your-reference-sent-to-the-counterparty", "description": "YOUR_DESCRIPTION_OF_THE_TRANSFER", "reference": "YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER" }'
In the response, note the following:
id
: the unique ID of the transfer.status
: the result of the transfer.reason
: an explanation of the status. Check this field if the status is not authorised.
For example, the reason for a refused status can be notEnoughBalance.
{ "creationDate": "2023-08-08T13:52:08+02:00", "id": "48NJIB9TWQJ6L7U7", "accountHolder": { "description": "Your account holder description", "id": "AH00000000000000000000001", "reference": "Your account holder reference" }, "amount": { "currency": "EUR", "value": 10000 }, "balanceAccount": { "description": "Your balance account description", "id": "BA00000000000000000000001", "reference": "Your balance account reference" }, "category" : "internal", "categoryData": { "type": "internal" }, "counterparty": { "balanceAccountId": "BA00000000000000000000002" }, "description": "YOUR_DESCRIPTION_OF_THE_TRANSFER", "direction": "outgoing", "reason": "approved", "reference": "YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER", "referenceForBeneficiary": "Your-reference-sent-to-the-counterparty", "status": "authorised", "type": "internalTransfer" }
- Wait for the transfer webhooks to confirm that the transfer has been booked.
To better control money movement in your marketplace, you can trigger additional reviews for transfers. Additional reviews require a member of your team to verify a transfer before Adyen processes it.
You can trigger an additional review by including the review object in the POST /transfers request. In the object, specify the following parameter:
Parameter name | Required | Description | |
---|---|---|---|
review.numberOfApprovalsRequired | ![]() |
Specifies the number of approvals required to process the transfer. Possible values: 1. Currently, it is possible to request only one additional review per transfer. |
The following code sample shows how to include include the review
object.
curl https://balanceplatform-api-test.adyen.com/btl/v4/transfers \ -H 'x-api-key: YOUR_BALANCE_PLATFORM_API_KEY' \ -H 'content-type: application/json' \ -X POST \ -d '{ "amount": { "value": 60000, "currency": "EUR" }, "balanceAccountId": "BA00000000000000000000001", "category": "internal", "counterparty": { "balanceAccountId": "BA00000000000000000000002" }, "description": "Your-description-for-the-transfer", "reference": "YOUR_INTERNAL_REFERENCE", "referenceForBeneficiary": "Your-reference-for-the-beneficiary", "review": { "numberOfApprovalsRequired": 1 } }'
If the transfer request is successful, you receive a response containing the following parameters:
Parameter name | Description |
---|---|
review.numberOfApprovalsRequired | Shows the number of approvals required to process the transfer. |
After triggering the review, a member of your team must approve the transfer before Adyen continues processing it.
Troubleshooting
If an internal fund transfer fails, verify if there are enough funds in the source balance account:
- Make a GET /balanceAccounts/{id} request, specifying the source balance account's ID in the path.
- Check the available balance.
- If the amount is lower than the transfer amount, you can:
- Ask your user to top up their balance account.
- Make an internal transfer from your liable balance account to your user's balance account.
If there are enough funds in the balance account, but the transfer still fails, contact our Support Team.
Get updates on the status of the transfer
For every internal transfer request, Adyen sends multiple webhooks to your server: a series of webhooks for the balance account where the transfer is an outgoing request, and a series of webhooks for the balance account where the transfer is an incoming request.
Using these webhooks, you can track the status of the transfer: received, then authorised, and finally booked. The webhooks also inform you if the transfer failed.
You can also view the transfer details in your Customer Area. Each transfer of funds between balance accounts appears in the Customer Area as two transfer entries: one for the balance account that is credited, and one for the balance account that is debited.