--- title: "Initiate on-demand internal funds transfers" description: "Send funds or initiate an internal direct debit between balance accounts within your marketplace." url: "https://docs.adyen.com/marketplaces/internal-fund-transfers/on-demand-fund-transfers" source_url: "https://docs.adyen.com/marketplaces/internal-fund-transfers/on-demand-fund-transfers.md" canonical: "https://docs.adyen.com/marketplaces/internal-fund-transfers/on-demand-fund-transfers" last_modified: "2020-09-11T17:20:00+02:00" language: "en" --- # Initiate on-demand internal funds transfers Send funds or initiate an internal direct debit between balance accounts within your marketplace. [View source](/marketplaces/internal-fund-transfers/on-demand-fund-transfers.md) In your marketplace, you can set up a [schedule](/marketplaces/internal-fund-transfers/scheduled-fund-transfers) to automatically transfer funds between balance accounts. In addition to or instead of that, you can transfer funds between balance accounts on-demand. ## Requirements Before you begin, take into account the following requirements and preparations: | Requirement | Description | | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Integration type** | You need an [Adyen for Platforms](/adyen-for-platforms-model) integration. | | **[API credentials](/marketplaces/manage-access/api-credentials-web-service)** | Your API credential for the [Transfers API](https://docs.adyen.com/api-explorer/transfers/latest/overview) must have the following [role](/marketplaces/manage-access/webservice-roles?tab=transfers_2): - **TransferService Webservice Initiate role** | | **[Customer Area roles](/account/user-roles)** | You need the following roles: - **Initiate internal transfers** - **Balance platform base role** | | **[Webhooks](/development-resources/webhooks/configure-and-manage)** | 1. Make sure that your server receives and accepts webhooks. 2. In your Customer Area, subscribe to [Transfer webhooks](/marketplaces/webhook-types#transfer-webhooks). | | **[Capabilities](/marketplaces/verification-overview/capabilities)** | If the balance accounts involved in the transfer *do not belong to the same account holder*, check the [capabilities](/marketplaces/verification-overview/capabilities#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. | | **Setup steps** | Before you begin your integration, contact our [Support Team](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other) to enable transfers for the source balance account. | ## 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. ### Tab: Customer Area In your Customer Area, initiate the transfer as follows: 1. Go to **Transactions** > **Transfers**. 2. In the **Balance platform** dropdown, select the balance platform. You can view transfers from one balance platform at a time. 3. Select **Transfer funds**. 4. In the **Source balance account** field, enter the ID of the [balance account](/marketplaces/account-structure-resources) where the funds will be debited. 5. In the **Counterparty Type** field, select **balanceAccount**. 6. Select the **Counterparty balance account ID**. This is where the funds will be credited. 7. Select the currency and enter the amount to be transferred. 8. Optional. Enter the following information: * **Reference**: your reference for the transfer, used internally within your platform. If you do not provide this, Adyen generates a unique reference. Maximum 80 characters. * **Description**: a description of the transfer that is sent to the recipient of the transfer request. Supported characters: `[a-z][A-Z][0-9]/ - ? : ( ) . , ' + Space`. We recommend a maximum of 140 characters. * **Reference for beneficiary**: a reference that is sent to the recipient of the transfer request. It is also sent in all the webhooks related to the transfer. Supported characters: `[a-z][A-Z][0-9]`. Maximum 80 characters. 9. Select **Transfer funds** > **Yes, Transfer**. The transfer request is now created. On the **Transactions** > **Transfers** tab you can confirm if the transfer has been booked. ** ### Example fund transfer between balance accounts You want to send EUR 150 from your liable balance account to the balance account of your user. The following table shows the details you need to enter to initiate the transfer: | Field | Details | | ---------------------------------------- | ----------------------------------------------------------- | | **Source balance account** | **BA00000000000000000000001** (your liable balance account) | | **Counterparty Type** | **balanceAccount** | | **Counterparty balance account ID** | **BA00000000000000000000002** (your user's balance account) | | **Amount** | **EUR** **150** | | **Reference (optional)** | Your internal reference for the transfer | | **Description (optional)** | Your description of the transfer | | **Reference for beneficiary (optional)** | Your reference for the recipient of the transfer request | ### Tab: API 1. To move funds between balance accounts, make a POST [/transfers](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers) request. In the body of the request, specify the following fields: | Parameter | Required | Description | | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | [amount](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-amount) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | An object containing the currency and value of the transfer. | | [balanceAccountId](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-balanceAccountId) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The unique identifier of the source balance account: the balance account that initiates the transfer request. | | [counterparty.balanceAccountId](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-counterparty-balanceAccountId) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The unique identifier of the target balance account: the balance account that receives the transfer. The funds are credited to this balance account. | | [category](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-category) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Set to **internal**. | | [description](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-description) | | Your description of the transfer. You can use this to identify the transfer in the webhooks that you receive. | | [reference](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-reference) | | Your unique reference for the transfer. You can use this to identify the transfer in the webhooks that you receive. | | [referenceForBeneficiary](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-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.00** from your liable balance account to your user's balance account. **Push funds to another balance account** #### curl ```bash 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" }' ``` #### Java ```java // Adyen Java API Library v33.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.transfers.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.transfers.*; Client client = new Client("ADYEN_BALANCE_PLATFORM_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(10000L); CounterpartyInfoV3 counterpartyInfoV3 = new CounterpartyInfoV3() .balanceAccountId("BA00000000000000000000002"); TransferInfo transferInfo = new TransferInfo() .balanceAccountId("BA00000000000000000000001") .reference("YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER") .amount(amount) .referenceForBeneficiary("Your-reference-sent-to-the-counterparty") .counterparty(counterpartyInfoV3) .description("YOUR_DESCRIPTION_OF_THE_TRANSFER") .category(TransferInfo.CategoryEnum.INTERNAL); // Send the request TransfersApi service = new TransfersApi(client); Transfer response = service.transferFunds(transferInfo, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_BALANCE_PLATFORM_API_KEY"); $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(10000); $counterpartyInfoV3 = new CounterpartyInfoV3(); $counterpartyInfoV3 ->setBalanceAccountId("BA00000000000000000000002"); $transferInfo = new TransferInfo(); $transferInfo ->setBalanceAccountId("BA00000000000000000000001") ->setReference("YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER") ->setAmount($amount) ->setReferenceForBeneficiary("Your-reference-sent-to-the-counterparty") ->setCounterparty($counterpartyInfoV3) ->setDescription("YOUR_DESCRIPTION_OF_THE_TRANSFER") ->setCategory("internal"); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new TransfersApi($client); $response = $service->transferFunds($transferInfo, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v28.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Transfers; using Adyen.Service.Transfers; var config = new Config() { XApiKey = "ADYEN_BALANCE_PLATFORM_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 10000 }; CounterpartyInfoV3 counterpartyInfoV3 = new CounterpartyInfoV3 { BalanceAccountId = "BA00000000000000000000002" }; TransferInfo transferInfo = new TransferInfo { BalanceAccountId = "BA00000000000000000000001", Reference = "YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER", Amount = amount, ReferenceForBeneficiary = "Your-reference-sent-to-the-counterparty", Counterparty = counterpartyInfoV3, Description = "YOUR_DESCRIPTION_OF_THE_TRANSFER", Category = TransferInfo.CategoryEnum.Internal }; // Send the request var service = new TransfersService(client); var response = service.TransferFunds(transferInfo, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v23.3.0 const { Client, TransfersAPI } = require('@adyen/api-library'); const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Create the request object(s) const transferInfo = { 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" } // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransfersApi.transferFunds(transferInfo, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v17.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v17/src/common" "github.com/adyen/adyen-go-api-library/v17/src/adyen" "github.com/adyen/adyen-go-api-library/v17/src/transfers" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := transfers.Amount{ Currency: "EUR", Value: 10000, } counterpartyInfoV3 := transfers.CounterpartyInfoV3{ BalanceAccountId: common.PtrString("BA00000000000000000000002"), } transferInfo := transfers.TransferInfo{ BalanceAccountId: common.PtrString("BA00000000000000000000001"), Reference: common.PtrString("YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER"), Amount: amount, ReferenceForBeneficiary: common.PtrString("Your-reference-sent-to-the-counterparty"), Counterparty: counterpartyInfoV3, Description: common.PtrString("YOUR_DESCRIPTION_OF_THE_TRANSFER"), Category: "internal", } // Send the request service := client.Transfers() req := service.TransfersApi.TransferFundsInput().IdempotencyKey("UUID").TransferInfo(transferInfo) res, httpRes, err := service.TransfersApi.TransferFunds(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.3.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_BALANCE_PLATFORM_API_KEY" adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "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" } # Send the request result = adyen.transfers.transfers_api.transfer_funds(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.1.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_BALANCE_PLATFORM_API_KEY' adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :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' } # Send the request result = adyen.transfers.transfers_api.transfer_funds(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v23.3.0 import { Client, TransfersAPI, Types } from "@adyen/api-library"; const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Create the request object(s) const amount: Types.transfers.Amount = { currency: "EUR", value: 10000 }; const counterpartyInfoV3: Types.transfers.CounterpartyInfoV3 = { balanceAccountId: "BA00000000000000000000002" }; const transferInfo: Types.transfers.TransferInfo = { balanceAccountId: "BA00000000000000000000001", reference: "YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER", amount: amount, referenceForBeneficiary: "Your-reference-sent-to-the-counterparty", counterparty: counterpartyInfoV3, description: "YOUR_DESCRIPTION_OF_THE_TRANSFER", category: Types.transfers.TransferInfo.CategoryEnum.Internal }; // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransfersApi.transferFunds(transferInfo, { idempotencyKey: "UUID" }); ``` 2. 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.\ For example, the reason for a **refused** status can be **notEnoughBalance**. **Response** ```json { "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": "pending", "reference": "YOUR_UNIQUE_REFERENCE_FOR_THE_TRANSFER", "referenceForBeneficiary": "Your-reference-sent-to-the-counterparty", "status": "received", "type": "internalTransfer" } ``` 3. Wait for the [transfer webhooks](/marketplaces/internal-fund-transfers/internal-transfer-webhooks) to confirm that the transfer has been booked. ** ### Trigger additional reviews 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. 1. You can trigger an additional review by including the [review](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-review) object in the POST [/transfers](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers) request. In the object, specify the following parameter: | Parameter name | Required | Description | | | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | | [review.numberOfApprovalsRequired](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-review-numberOfApprovalsRequired) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | 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 the `review` object. **Trigger an additional review** #### curl ```bash 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 } }' ``` #### Java ```java // Adyen Java API Library v33.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.transfers.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.transfers.*; Client client = new Client("YOUR_BALANCE_PLATFORM_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(60000L); TransferRequestReview transferRequestReview = new TransferRequestReview() .numberOfApprovalsRequired(1); CounterpartyInfoV3 counterpartyInfoV3 = new CounterpartyInfoV3() .balanceAccountId("BA00000000000000000000002"); TransferInfo transferInfo = new TransferInfo() .balanceAccountId("BA00000000000000000000001") .reference("YOUR_INTERNAL_REFERENCE") .amount(amount) .referenceForBeneficiary("Your-reference-for-the-beneficiary") .review(transferRequestReview) .counterparty(counterpartyInfoV3) .description("Your-description-for-the-transfer") .category(TransferInfo.CategoryEnum.INTERNAL); // Send the request TransfersApi service = new TransfersApi(client); Transfer response = service.transferFunds(transferInfo, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("YOUR_BALANCE_PLATFORM_API_KEY"); $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(60000); $transferRequestReview = new TransferRequestReview(); $transferRequestReview ->setNumberOfApprovalsRequired(1); $counterpartyInfoV3 = new CounterpartyInfoV3(); $counterpartyInfoV3 ->setBalanceAccountId("BA00000000000000000000002"); $transferInfo = new TransferInfo(); $transferInfo ->setBalanceAccountId("BA00000000000000000000001") ->setReference("YOUR_INTERNAL_REFERENCE") ->setAmount($amount) ->setReferenceForBeneficiary("Your-reference-for-the-beneficiary") ->setReview($transferRequestReview) ->setCounterparty($counterpartyInfoV3) ->setDescription("Your-description-for-the-transfer") ->setCategory("internal"); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new TransfersApi($client); $response = $service->transferFunds($transferInfo, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v28.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Transfers; using Adyen.Service.Transfers; var config = new Config() { XApiKey = "YOUR_BALANCE_PLATFORM_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 60000 }; TransferRequestReview transferRequestReview = new TransferRequestReview { NumberOfApprovalsRequired = 1 }; CounterpartyInfoV3 counterpartyInfoV3 = new CounterpartyInfoV3 { BalanceAccountId = "BA00000000000000000000002" }; TransferInfo transferInfo = new TransferInfo { BalanceAccountId = "BA00000000000000000000001", Reference = "YOUR_INTERNAL_REFERENCE", Amount = amount, ReferenceForBeneficiary = "Your-reference-for-the-beneficiary", Review = transferRequestReview, Counterparty = counterpartyInfoV3, Description = "Your-description-for-the-transfer", Category = TransferInfo.CategoryEnum.Internal }; // Send the request var service = new TransfersService(client); var response = service.TransferFunds(transferInfo, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v23.3.0 const { Client, TransfersAPI } = require('@adyen/api-library'); const client = new Client({ apiKey: "YOUR_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Create the request object(s) const transferInfo = { 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 } } // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransfersApi.transferFunds(transferInfo, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v17.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v17/src/common" "github.com/adyen/adyen-go-api-library/v17/src/adyen" "github.com/adyen/adyen-go-api-library/v17/src/transfers" ) client := adyen.NewClient(&common.Config{ ApiKey: "YOUR_BALANCE_PLATFORM_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := transfers.Amount{ Currency: "EUR", Value: 60000, } transferRequestReview := transfers.TransferRequestReview{ NumberOfApprovalsRequired: common.PtrInt32(1), } counterpartyInfoV3 := transfers.CounterpartyInfoV3{ BalanceAccountId: common.PtrString("BA00000000000000000000002"), } transferInfo := transfers.TransferInfo{ BalanceAccountId: common.PtrString("BA00000000000000000000001"), Reference: common.PtrString("YOUR_INTERNAL_REFERENCE"), Amount: amount, ReferenceForBeneficiary: common.PtrString("Your-reference-for-the-beneficiary"), Review: &transferRequestReview, Counterparty: counterpartyInfoV3, Description: common.PtrString("Your-description-for-the-transfer"), Category: "internal", } // Send the request service := client.Transfers() req := service.TransfersApi.TransferFundsInput().IdempotencyKey("UUID").TransferInfo(transferInfo) res, httpRes, err := service.TransfersApi.TransferFunds(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.3.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "YOUR_BALANCE_PLATFORM_API_KEY" adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "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 } } # Send the request result = adyen.transfers.transfers_api.transfer_funds(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v10.1.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'YOUR_BALANCE_PLATFORM_API_KEY' adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :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 } } # Send the request result = adyen.transfers.transfers_api.transfer_funds(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v23.3.0 import { Client, TransfersAPI, Types } from "@adyen/api-library"; const client = new Client({ apiKey: "YOUR_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Create the request object(s) const amount: Types.transfers.Amount = { currency: "EUR", value: 60000 }; const transferRequestReview: Types.transfers.TransferRequestReview = { numberOfApprovalsRequired: 1 }; const counterpartyInfoV3: Types.transfers.CounterpartyInfoV3 = { balanceAccountId: "BA00000000000000000000002" }; const transferInfo: Types.transfers.TransferInfo = { balanceAccountId: "BA00000000000000000000001", reference: "YOUR_INTERNAL_REFERENCE", amount: amount, referenceForBeneficiary: "Your-reference-for-the-beneficiary", review: transferRequestReview, counterparty: counterpartyInfoV3, description: "Your-description-for-the-transfer", category: Types.transfers.TransferInfo.CategoryEnum.Internal }; // Send the request const transfersAPI = new TransfersAPI(client); const response = transfersAPI.TransfersApi.transferFunds(transferInfo, { idempotencyKey: "UUID" }); ``` 2. If the transfer request is successful, you receive an **HTTP 2XX** response containing transfer details, including the following parameters: | Parameter name | Description | | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | | [review.numberOfApprovalsRequired](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#responses-202-review-numberOfApprovalsRequired) | Shows the number of approvals required to process the transfer. | After triggering the review, a member of your team must [approve](/marketplaces/internal-fund-transfers/approve-cancel-transfers) the transfer before Adyen continues processing it. ** ### Process a transfer in a future date 1. When you make a transfer request, you can specify a future date when you want Adyen to process the transfer. You can do this by including the [executionDate](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-executionDate) object in the POST [/transfers](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers) request. If your transfer request is successful, the transfer remains in `status` **received** with `reason` **pending** until the execution date. On the execution date, between 00:00 and 03:00 - based on the time zone configured on the Balance Platform by default - Adyen verifies that: * The source balance account has enough funds. * The transfer was approved by a member of your team, if you triggered an additional review. If all previous conditions are satisfied, Adyen processes the transfer request. Adyen attempts to process the transfer only one time. In case of any errors, such as having insufficient funds in the balance account, the transfer request ends with `status` **failed**. If this happens, Adyen sends a [webhook](#get-status-updates) with details about the failure. To specify a future execution date, specify the following parameters: | Parameter name | Required | Description | | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [executionDate.date](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-executionDate-date) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The date when the transfer will be processed. This date must:- Be within 30 days of the current date. - Be in the [ISO 8601 format](https://www.iso.org/iso-8601-date-and-time-format.html) **YYYY-MM-DD**. For example: 2025-01-31. | | [executionDate.timezone](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-executionDate-timezone) | | The timezone that applies to the execution date. Use a timezone identifier from the [tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). For example: **America/Los\_Angeles**. Default value: **Europe/Amsterdam**. | The following code sample shows how to include the [executionDate](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#request-executionDate) object in a transfer request. **Specify an execution date in the future** ```bash 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": 80000, "currency": "EUR" }, "balanceAccountId": "BA00000000000000000000001", "category": "internal", "counterparty": { "balanceAccountId": "BA00000000000000000000002" }, "executionDate": { "date": "2025-04-18", "timezone": "America/Los_Angeles" }, "referenceForBeneficiary": "Your-reference-sent-to-the-beneficiary", "reference": "Your internal reference for the transfer", "description": "Your description for the transfer" }' ``` 2. If the transfer request is successful, you receive an **HTTP 2XX** response with the transfer details and the [executionDate](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers#responses-200-executionDate) object. 3. Before the execution date, you can [cancel the transfer](/marketplaces/internal-fund-transfers/approve-cancel-transfers) by making a POST [/transfers/cancel](https://docs.adyen.com/api-explorer/transfers/latest/post/transfers/cancel) request. ## Troubleshooting If an internal fund transfer fails, verify if there are enough funds in the source balance account: 1. Make a GET [/balanceAccounts/{id}](https://docs.adyen.com/api-explorer/balanceplatform/latest/get/balanceAccounts/\(id\)) request, specifying the source balance account's ID in the path. 2. Check the [available](https://docs.adyen.com/api-explorer/balanceplatform/latest/get/balanceAccounts/\(id\)#responses-200-balances-available) balance. 3. If the amount is lower than the transfer amount, you can: * Ask your user to [top up](/marketplaces/top-up-balance-account) 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](https://ca-test.adyen.com/ca/ca/contactUs/support.shtml?form=other). ## Get updates on the status of the transfer For every internal transfer request, Adyen sends multiple [webhooks](/marketplaces/internal-fund-transfers/internal-transfer-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](/marketplaces/view-transfers-details). 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. ## See also * [Internal funds transfer webhooks](/marketplaces/internal-fund-transfers/internal-transfer-webhooks/) * [View transfer details](/marketplaces/view-transfers-details) * [Schedule automatic internal funds transfers](/marketplaces/internal-fund-transfers/scheduled-fund-transfers)