Transfer Creation
Once a quote and recipient have been created, you are ready to create a transfer. Creating a transfer returns a complete transfer object, which includes the final details with all final details, including the final required pay in amount to process the transfer.
Different integration types will require different transfer types to be created. All transfers may require additional transfer requirements, which should be requested and captured before creation of the transfer.
Once ready to create a transfer, your application should use one of the following transfer creation types:
- Regular Transfer - Used for most integrations and for personal tokens
- Third Party Transfer - Used for only those partners that operate on a Third Party Infrastructure model.
- Partner License Transfer - Used for only those partners that operate on a partner license model
Each transfer can have additional requirements that are needed in order to process the transfer. To determine the transfer requirements needed, your application should use the transfer requirements endpoints to request the requirements for the transfer.
Requirements are returned in a dynamic form, with form types, restrictions, and validation included in a consistent method. This allows your application to present these to users in a consistent way.
Once all transfer requirements have been gathered, they should be added to the details section of the create transfer API call.
For a full reference, please see the request transfer requirements API reference.
It is important to update the quote before creating a transfer as fees and expected delivery time can change based on the recipient, payout method, or payment meta data.
For example, the fees and delivery estimate are different in the case of sending USD to a country other than the USA - we call this Global USD. Multiple factors can play into this, so it is important to complete this step.
Updating the quote ensures you can show the customer the correct final price and delivery estimate time before they commit to creating and funding the transfer.
Please see the update quote API reference for full details on how to complete this update.
POST /v1/transfers
Refund recipient account ID
Recipient account ID. You can create multiple transfers to same recipient account.
V2 quote ID. You can only create one transfer per one quote. You cannot use same quote ID to create multiple transfers.
This is required to perform idempotency check to avoid duplicate transfers in case of network failures or timeouts.
Recipient will see this reference text in their bank statement. Maximum allowed characters depends on the currency route. Business Payments Tips article has a full list.
For example when target currency is THB. See more about conditions at Transfers.Requirements
For example when target currency is CNY. See more about conditions at Transfers.Requirements
For example when target currency is INR. See more about conditions at Transfers.Requirements
For example when target currency is USD and transfer amount exceeds 80k. See more about conditions at Transfers.Requirements
There are two options to deal with conditionally required fields:
- Always call
transfer-requirements
endpoint and submit values only if indicated so. - Always provide values for these fields based on a dynamically retrieved list (transfer-requirements endpoint). It is possible these fields change over time so hard coding the options does create some risk of issues. Contact api@wise.com if you have questions about this property, especially if considering hardcoding a value.
Response
Returns a standard transfer object.
Avoiding duplicate transfers
We use customerTransactionId field to avoid duplicate transfer requests. If your initial call to create a transfer fails (error or timeout) then you should retry the call using the same value in the customerTransactionId field that you used in the original call. This way we can treat subsequent retry messages as repeat messages and will not create duplicate transfers to your account should one have succeeded before. You should not retry indefinitely but use a sensible limit, perhaps with a back-off approach.
Payment Approvals
If your business account has payment approvals, your application will run in to this error when attempting to create a transfer
Quote cannot be accepted with this request due to missing approval.
Consider removing the payment rule if you are going to use the API to create transfers.
curl -X POST https://api.sandbox.transferwise.tech/v1/transfers \-H 'Authorization: Bearer <your api token>' \-H 'Content-Type: application/json' \-d '{"sourceAccount": <refund recipient account ID>,"targetAccount": <recipient account ID>,"quoteUuid": <quote ID>,"customerTransactionId": "<the unique identifier you generated for the transfer attempt>","details" : {"reference" : "to my friend","transferPurpose": "verification.transfers.purpose.pay.bills","transferPurposeSubTransferPurpose": "verification.sub.transfers.purpose.pay.interpretation.service""sourceOfFunds": "verification.source.of.funds.other"}}'
POST /v2/profiles/{{profileId}}/third-party-transfers
This is very similar to Create transfers endpoint, but please note these differences:
- Originator datablock is additionally required
- Depending on the legal entity type of the originator (PRIVATE or BUSINESS), the required fields vary. Please refer the two sample request examples on the right.
- OriginalTransferId field is being used instead of customerTransactionId
Recipient account ID. You can create multiple transfers to same recipient account.
V2 quote ID. You can only create one transfer per one quote.
You cannot use same quote ID to create multiple transfers.
Unique transfer ID in your system. We use this field also to perform idempotency check to avoid duplicate transfers in case of network failures or timeouts. You can only submit one transfer with same originalTransferId.
Recipient will see this reference text in their bank statement. Maximum allowed characters depends on the currency route. Business Payments Tips article has a full list.
Data block to capture payment originator details.
PRIVATE or BUSINESS. Payment originator legal type.
Unique customer ID in your system. This allows us to uniquely identify each originator. Required.
Data block to capture the originator name details.
Depends on the type of legal entity (PRIVATE or BUSINESS), the required fields and inputs are different.
Payment originator first name. Required if legalEntityType = PRIVATE
.
Payment originator middle name(s). Used only if legalEntityType = PRIVATE
.
Payment originator family name. Required if legalEntityType = PRIVATE
.
Payment originator patronymic name. Used only if legalEntityType = PRIVATE
.
Payment originator full legal name. Required if legalEntityType = BUSINESS
.
Payment originator date of birth. Required if legalEntityType = PRIVATE
.
Payment originator business registry number / incorporation number. Required if legalEntityType = BUSINESS
.
Payment originator address first line. Required
Payment originator address city. Required
Payment originator address state code. Required if address country code in (US, CA, BR, AU). See Countries and states
Payment originator address first line. Required
Originator address zip code.
Response
Returns an originator transfer object.
You need to save the transfer ID for tracking its status later via webhooks.
Avoiding duplicate transfers
We use originalTransferId field to avoid duplicate transfer requests. When your first call fails (error or timeout) then you should use the same value in originalTransferId field that you used in the original call when you are submitting a retry message. This way we can treat subsequent retry messages as repeat messages and will not create duplicate transfers to your account.
curl -X POST https://api.sandbox.transferwise.tech/v2/profiles/{{profileId}}/third-party-transfers \-H 'Authorization: Bearer <your api token>' \-H 'Content-Type: application/json' \-d '{"targetAccount": <recipient account ID>,"quote": "<quote ID>","originalTransferId": "<unique transfer ID in your system>","details" : {"reference" : "Ski trip"},"originator" : {"legalEntityType" : "PRIVATE","reference" : "<unique customer ID in your system>","name" : {"givenName": "John","middleNames": ["Ryan"],"familyName": "Godspeed"},"dateOfBirth": "1977-07-01","address" : {"firstLine": "Salu tee 100, Apt 4B","city": "Tallinn","countryCode": "EE","postCode": "12112"}}}'
curl -X POST https://api.sandbox.transferwise.tech/v2/profiles/{{profileId}}/third-party-transfers \-H 'Authorization: Bearer <your api token>' \-H 'Content-Type: application/json' \-d '{"targetAccount": <recipient account ID>,"quote": "<quote ID>","originalTransferId": "<unique transfer ID in your system>","details" : {"reference" : "Payment for invoice 22092"},"originator" : {"legalEntityType" : "BUSINESS","reference" : "<originator customer ID in your system>","name" : {"fullName": "Hot Air Balloon Services Ltd"},"businessRegistrationCode": "1999212","address" : {"firstLine": "Aiandi tee 1431","city": "Tallinn","countryCode": "EE","postCode": "12112"}}}'
POST /v1/profiles/{{profileId}}/partner-licence-transfers
This is very similar to Create transfers endpoint, but please note these differences:
- originator datablock is additionally required
Refund recipient account ID.
Recipient account ID. You can create multiple transfers to same recipient account.
V2 quote ID. You can only create one transfer per one quote.
You cannot use same quote ID to create multiple transfers.
Unique transfer ID in your system. We use this field also to perform idempotency check to avoid duplicate transfers in case of network failures or timeouts. You can only submit one transfer with same customerTransactionId.
Recipient will see this reference text in their bank statement. Maximum allowed characters depends on the currency route. Business Payments Tips article has a full list.
Data block to capture payment originator details.
PRIVATE or BUSINESS. Payment originator legal type.
Unique customer ID in your system. This allows us to uniquely identify each originator. Required.
Payment originator first name. Required if legalEntityType = PRIVATE.
Payment originator middle name(s). Used only if legalEntityType = PRIVATE. Optional
Payment originator family name. Required if legalEntityType = PRIVATE.
Payment originator patronymic name. Used only if legalEntityType = PRIVATE. Optional
Payment originator full legal name. Required if legalEntityType = BUSINESS.
Payment originator date of birth. Required if legalEntityType = PRIVATE.
Payment originator business registry number / incorporation number. Required if legalEntityType = BUSINESS.
Payment originator address first line. Required
Payment originator address city. Required
Payment originator address state code. Required if address country code in (US, CA, BR, AU). See Countries and states
Payment originator address first line. Required
Originator address zip code. Optional
Response
Returns an originator transfer object.
You need to save the transfer ID for tracking its status later via webhooks.
Avoiding duplicate transfers
We use customerTransactionId field to avoid duplicate transfer requests. When your first call fails (error or timeout) then you should use the same value in customerTransactionId field that you used in the original call when you are submitting a retry message. This way we can treat subsequent retry messages as repeat messages and will not create duplicate transfers to your account.
curl -X POST https://api.sandbox.transferwise.tech/v1/profiles/{{profileId}}/partner-licence-transfers \-H 'Authorization: Bearer <your api token>' \-H 'Content-Type: application/json' \-d '{"sourceAccount": <refund recipient account ID>,"targetAccount": <recipient account ID>,"quote": "<quote ID>","customerTransactionId": "<unique transfer ID in your system>","details" : {"reference" : "Ski trip"},"originator" : {"legalEntityType" : "PRIVATE","reference" : "<unique customer ID in your system>","name" : {"givenName": "John","middleNames": ["Ryan"],"familyName": "Godspeed"},"dateOfBirth": "1977-07-01","address" : {"firstLine": "Salu tee 100, Apt 4B","city": "Tallinn","countryCode": "EE","postCode": "12112"}}}'
curl -X POST https://api.sandbox.transferwise.tech/v1/profiles/{{profileId}}/partner-licence-transfers \-H 'Authorization: Bearer <your api token>' \-H 'Content-Type: application/json' \-d '{"sourceAccount": <refund recipient account ID>,"targetAccount": <recipient account ID>,"quote": "<quote ID>","customerTransactionId": "<unique transfer ID in your system>","details" : {"reference" : "Payment for invoice 22092"},"originator" : {"legalEntityType" : "BUSINESS","reference" : "<originator customer ID in your system>","name" : {"fullName": "Hot Air Balloon Services Ltd"},"businessRegistrationCode": "1999212","address" : {"firstLine": "Aiandi tee 1431","city": "Tallinn","countryCode": "EE","postCode": "12112"}}}'
Testing in Sandbox
Because Sandbox is a test environment, there are some differences between Sandbox and Production. Please keep these in mind as you test.
We've outlined the differences between the Sandbox and Production environments for quotes, recipient creation, and funding in the relevant sections. For all other functionalities, including transfer creation, you can test in Sandbox using the same methods as in Production.
Speak with the Wise team if you have further questions about testing transfers in Sandbox.