Transfer Money Between Users - Dwolla Developer Portal
Overview
The most common scenario for this guide is to facilitate marketplace or peer-to-peer transfers between your customers.
In this guide, we’ll cover the key points of transferring money:
Create a Verified Customer who will receive the transfer
Create a Verified Customer in your application to act as the recipient of the funds.Create an Unverified Customer who will send the transfer
Create an Unverified Customer who will initiate and send the funds.Associate a verified funding source with the sender
Link and verify a bank or credit union account to the sender’s profile to enable sending funds.Associate an unverified funding source with recipient
Link a bank or credit union account to the recipient’s profile (verification not required for receiving funds).Transfer funds from the sender's funding source to the recipient's funding source
Initiate a transfer from the sender’s verified funding source to the recipient’s funding source using the Dwolla API.
Certain use cases involving transfers between users, such as peer-to-peer payments, may require additional review to ensure alignment with Dwolla’s risk policies. Before you start building, contact our Sales team to confirm that your use case is supported.
Before you begin
You need to have a Sandbox account already set up.
Verified and Unverified Customers
Here are some rules to keep in mind:
- With a transfer of money, at least one party must complete the identity verification process, either the sender or the receiver. It’s your decision about which party completes this process, based on your business model, and you may want to have both parties complete the identity verification process.
- The sender must have a verified funding source. Unverified funding sources can only receive money, not send.
In this guide, we’ll create two Customers: one to represent a seller and one to represent a buyer. In this scenario, the seller, Jane Merchant, is a Verified Customer with an unverified funding source. The buyer, Joe Buyer, is an Unverified Customer with a verified funding source.
This is a suggested approach and there are other ways you can implement your marketplace transfers. For instance, both the sender and the receiver (or buyer and seller) could be Verified Customers, and both could have verified funding sources. Or, you could have the sender undergo identity verification but not the recipient.
Looking to learn more about each Customer type and how it relates to your funds flow? Take a look at our Customer types article for more information.
Step 1 - Create a Verified Customer
First, we’ll create a Verified Customer for Jane Merchant. There are two types of Verified Customers you can create; Personal Verified Customers and Business Verified Customers. In this example, we use Business Verified Customers (sole proprietorship) to represent the merchant who will be receiving funds.
HTTP
POST https://api-sandbox.dwolla.com/customers
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer 0Sn0W6kzNic+oWhDbQcVSKLRUpGjIdl/YyrHqrDDoRnQwE7Q
{
"firstName": "Jane",
"lastName": "Merchant",
"email": "solePropBusiness@email.com",
"ipAddress": "143.156.7.8",
"type": "business",
"dateOfBirth": "1980-01-31",
"ssn": "6789",
"address1": "99-99 33rd St",
"city": "Some City",
"state": "NY",
"postalCode": "11101",
"businessClassification": "9ed3f670-7d6f-11e3-b1ce-5404a6144203",
"businessType": "soleProprietorship",
"businessName":"Jane Corp",
"ein":"00-0000000"
}
HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/customers/62c3aa1b-3a1b-46d0-ae90-17304d60c3d5
Creating Verified Customer in Code (PHP)
<?php
$customersApi = new DwollaSwagger\CustomersApi($apiClient);
$new_customer = 'https://api-sandbox.dwolla.com/customers/b70c3194-35fa-49e8-9243-d55a30e06d1e';
$new_customer = $customersApi->create([
'firstName' => 'Jane',
'lastName' => 'Merchant',
'email' => 'solePropBusiness@email.com',
'ipAddress' => '143.156.7.8',
'type' => 'business',
'dateOfBirth' => '1980-01-31',
'ssn' => '6789',
'address1' => '99-99 33rd St',
'city' => 'Some City',
'state' => 'NY',
'postalCode' => '11101',
'businessClassification' => '9ed3f670-7d6f-11e3-b1ce-5404a6144203',
'businessType' => 'soleProprietorship',
'businessName' => 'Jane Corp',
'ein' => '00-0000000']);
?>
Using DwollaV2 - Ruby Version
request_body = {
:firstName => 'Jane',
:lastName => 'Merchant',
:email => 'solePropBusiness@email.com',
:ipAddress => '143.156.7.8',
:type => 'business',
:dateOfBirth => '1980-01-31',
:ssn => '6789',
:address1 => '99-99 33rd St',
:city => 'Some City',
:state => 'NY',
:postalCode => '11101',
:businessClassification => '9ed3f670-7d6f-11e3-b1ce-5404a6144203',
:businessType => 'soleProprietorship',
:businessName => 'Jane Corp',
:ein => '00-0000000'
}
customer = app_token.post "customers", request_body
customer.response_headers[:location] # => "https://api-sandbox.dwolla.com/customers/62c3aa1b-3a1b-46d0-ae90-17304d60c3d5"
Using DwollaV2 - Python Version
request_body = {
'firstName': 'Jane',
'lastName': 'Merchant',
'email': 'solePropBusiness@email.com',
'ipAddress': '143.156.7.8',
'type': 'business',
'dateOfBirth': '1980-01-31',
'ssn': '6789',
'address1': '99-99 33rd St',
'city': 'Some City',
'state': 'NY',
'postalCode': '11101',
'businessClassification': '9ed3f670-7d6f-11e3-b1ce-5404a6144203',
'businessType': 'soleProprietorship',
'businessName': 'Jane Corp',
'ein': '00-0000000'
}
customer = app_token.post('customers', request_body)
customer.headers['location'] # => 'https://api-sandbox.dwolla.com/customers/62c3aa1b-3a1b-46d0-ae90-17304d60c3d5'
Following Customer Creation
When the customer is created, you’ll receive the customer URL in the location header.
There are various reasons a Verified Customer will result in a status other than verified which you will want to account for after the Customer is created. Reference the Customer verification resource article for more information on handling verification statuses.
Step 2 - Create unverified funding source
Next, we’ll add Jane Merchant’s bank or credit union account as an unverified funding source. Unverified funding sources can only receive funds, not send. The example below shows sample bank information, but you will include actual bank name, routing, and account numbers after prompting your customer for this information within your application. Possible values for bankAccountType can be either “checking” or “savings”. More detail is available in API docs.
HTTP
POST https://api-sandbox.dwolla.com/customers/AB443D36-3757-44C1-A1B4-29727FB3111C/funding-sources
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdl/YyrHqrDDoRnQwE7Q
{
"routingNumber": "222222226",
"accountNumber": "123456789",
"bankAccountType": "checking",
"name": "Jane Merchant"
}
HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/funding-sources/375c6781-2a17-476c-84f7-db7d2f6ffb31
Creating Unverified Funding Source in Code (PHP)
customer_url = 'https://api-sandbox.dwolla.com/customers/62c3aa1b-3a1b-46d0-ae90-17304d60c3d5';
request_body = {
routingNumber: '222222226',
accountNumber: '123456789',
bankAccountType: 'checking',
name: 'Jane Merchant'
}
# Using DwollaV2 - Ruby Version
funding_source = app_token.post "#{customer_url}/funding-sources", request_body
funding_source.response_headers[:location] # => "https://api-sandbox.dwolla.com/funding-sources/375c6781-2a17-476c-84f7-db7d2f6ffb31"
Now that we’ve created a customer for Jane Merchant and associated a funding source, we’ll do the same for Joe Buyer, but this time we’ll create an Unverified Customer, and a verified funding source which is capable of sending money. Provide the user’s full name, email address, and IP address to create the Customer. More detail is available in API docs.
HTTP
POST https://api-sandbox.dwolla.com/customers
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdl/YyrHqrDDoRnQwE7Q
{
"firstName": "Joe",
"lastName": "Buyer",
"email": "jbuyer@mail.net"
}
HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/customers/247B1BD8-F5A0-4B71-A898-F62F67B8AE1C
Creating Unverified Customer in Code (PHP)
request_body = {
:firstName => 'Joe',
:lastName => 'Buyer',
:email => 'jbuyer@mail.net',
:ipAddress => '99.99.99.99'
}
# Using DwollaV2 - Ruby Version
customer = app_token.post "customers", request_body
customer.response_headers[:location] # => "https://api-sandbox.dwolla.com/customers/247B1BD8-F5A0-4B71-A898-F62F67B8AE1C"
Step 4 - Attach a verified funding source
Next, you will create and attach a verified funding source to Joe Buyer, which will be done using Dwolla’s Open Banking solution with Plaid, a leading Open Banking service provider that Dwolla partners with. This method will give Joe Buyer the ability to add and verify their bank account in a matter of seconds by authenticating using their online banking credentials. Once Joe Buyer reaches the page in your application to add a bank account, you will use Open Banking with Plaid to authenticate their bank account. This involves initiating an Exchange Session with Dwolla, guiding the user through the verification process with their bank, and then using the Exchange details to create a funding source in Dwolla.
For more information, consult our integration guide. Additionally, if you would like to see a working example that verifies a bank using Open Banking with Plaid and attaches it as a verified funding source to a Dwolla Customer, please check out our open-banking/plaid integration example on our GitHub profile.
Step 5 - Initiating a transfer
HTTP
POST https://api-sandbox.dwolla.com/transfers
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdl/YyrHqrDDoRnQwE7Q
{
"_links": {
"source": {
"href": "https://api-sandbox.dwolla.com/funding-sources/80275e83-1f9d-4bf7-8816-2ddcd5ffc197"
},
"destination": {
"href": "https://api-sandbox.dwolla.com/funding-sources/375c6781-2a17-476c-84f7-db7d2f6ffb31"
}
},
"amount": {
"currency": "USD",
"value": "225.00"
}
}
HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/transfers/d76265cd-0951-e511-80da-0aa34a9b2388
Initiating a Transfer in Code
request_body = {
:_links => {
:source => {
:href => "https://api-sandbox.dwolla.com/funding-sources/80275e83-1f9d-4bf7-8816-2ddcd5ffc197"
},
:destination => {
:href => "https://api-sandbox.dwolla.com/funding-sources/375c6781-2a17-476c-84f7-db7d2f6ffb31"
}
},
:amount => {
:currency => "USD",
:value => "225.00"
}
}
transfer = app_token.post "transfers", request_body
transfer.response_headers[:location] # => "https://api.dwolla.com/transfers/d76265cd-0951-e511-80da-0aa34a9b2388"
You can check the status of the newly created transfer by retrieving the transfer by its URL.