Language

Bank transfer workflow

Transfer failures

There are several reasons bank transfers can fail, a few of which are outlined below. When a transfer fails it is usually a result of an ACH failure which is assigned an ACH return code after being rejected from the financial institution. A few common failure cases include:

  • Insufficient Funds (R01): Pending transfers can fail due to insufficient funds from the source bank account.
  • No Account/Unable to Locate Account (R03): The recipient of a transfer has closed their bank account or has incorrectly entered their bank account/routing number when attaching their funding source.
  • Customer Advises Not Authorized (R10): The owner of a bank account has told their bank that this transfer was unauthorized.

What occurs in the Dwolla system when a bank transfer fails?

Bank accounts will automatically be removed from the Dwolla system for all ACH return codes except an R01. If subscribed to webhooks, your application will receieve a webhook with the funding_source_removed event along with the transfer_failed event.

When a bank transfer fails from a verified account (e.g. Traditional CIP Verified or Access API Verified Customer to a recipient), funds will return to the sending account’s Dwolla balance. For other transfer scenarios, funds will return to the source bank account.

Retrieving the reason for a failed bank transfer

When a bank transfer fails its status will be updated to failed. If your application is subscribed to webhooks, you’ll receive either the transfer_failed event if the transfer belongs to a Dwolla account or the customer_transfer_failed event if the transfer belongs to an Access API Customer. The event contains a links to the associated account as well as the transfer resource. To get the return code and reason for the transfer failure you’ll first retrieve the transfer by its ID.

Request and response (view schema in ‘raw’)

GET https://api.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...

{
  "_links": {
    "self": {
      "href": "https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    },
    "source": {
      "href": "https://api-uat.dwolla.com/funding-sources/71afa37f-17ca-4132-9646-fd3ab83fc8b5",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    },
    "destination": {
      "href": "https://api-uat.dwolla.com/customers/99dd22de-6ec6-4ba1-a0d1-09eb169a4bb1",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "customer"
    },
    "failure": {
      "href": "https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388/failure",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "failure"
    }
  },
  "id": "8997ebed-69be-e611-80ea-0aa34a9b2388",
  "status": "failed",
  "amount": {
    "value": "442.00",
    "currency": "usd"
  },
  "created": "2016-12-09T23:48:11.910Z",
  "clearing": {
    "source": "standard"
  }
}
transfer_url = 'https://api.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388'

# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
# For Access API applications, an app_token can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
transfer = account_token.get transfer_url
transfer.status # => "failed"

# Using DwollaSwagger - https://github.com/Dwolla/dwolla-swagger-ruby
transfer = DwollaSwagger::TransfersApi.by_id(transfer_url)
transfer.status # => "failed"

transfer = DwollaSwagger::TransfersApi.by_id('https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388')
var transferUrl = 'https://api.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388';

// For Access API applications, an appToken can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
accountToken
  .get(transferUrl)
  .then(res => res.body.status); // => 'failed'
transfer_url = 'https://api.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388'

# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
# For Access API applications, an app_token can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
fees = account_token.get(transfer_url)
fees.body['status'] # => 'failed'

# Using dwollaswagger - https://github.com/Dwolla/dwolla-swagger-python
transfers_api = dwollaswagger.TransfersApi(client)
transfer = transfers_api.by_id(transfer_url)
transfer.status # => 'failed'
<?php
$transferUrl = 'https://api.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388';

$transfersApi = new DwollaSwagger\TransfersApi($apiClient);

$transfer = $transfersApi->byId($transferUrl);
$transfer->status; # => "failed"
?>

Dwolla returns a failure link within the response that can be used to lookup the ACH return code and corresponding description.

GET https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388/failure
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

{
  "_links": {
    "self": {
      "href": "https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388/failure"
    }
  },
  "code": "R1",
  "description": "Insufficient Funds"
}
transfer_url = 'https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388'

# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby
# For Access API applications, an app_token can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
failure = account_token.get "#{transfer_url}/failure"
failure.code # => "R1"
<?php
$transfer = '8997ebed-69be-e611-80ea-0aa34a9b2388';

$TransfersApi = DwollaSwagger\TransfersApi($apiClient);

$failureReason = $TransfersApi->failureById($transfer);
print($failureReason->status); # => "R01"
?>
transfer_url = 'https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388'

# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python (Recommended)
# For Access API applications, an app_token can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
failure = account_token.get('%s/failure' % transfer_url)
failure.body['code'] # => 'R1'
var transferUrl = 'https://api-uat.dwolla.com/transfers/8997ebed-69be-e611-80ea-0aa34a9b2388';

// For Access API applications, an appToken can be used for this endpoint. (https://docsv2.dwolla.com/#application-access-token)
accountToken
  .get(`${transferUrl}/failure`)
  .then(res => res.body.code); // => 'R1'

List of possible return codes and descriptions

Return CodeDescription
R01Insufficient Funds
R02Account Closed
R03No Account/Unable to Locate Account
R04Invalid Account Number Structure
R05Unauthorized Debit to Consumer Account Using Corporate SEC Code
R06Returned per ODFI’s Request
R07Authorization Revoked by Customer
R08Payment Stopped
R09Uncollected Funds
R10Customer Advises Not Authorized, Improper, or Ineligible
R11Check Truncation Entry Returned
R12Account Sold to Another DFI
R13Invalid ACH Routing Number
R14Representative Payee Deceased or Unable to Continue in that Capacity
R15Beneficiary or Account Holder (Other Than a Representative Payee) Deceased
R16Account Frozen
R17File Record Edit Criteria
R18Improper Effective Entry Date
R19Amount Field Error
R20Non-Transaction Account
R21Invalid Company Identification
R22Invalid Individual ID Number
R23Credit Entry Refused by Receiver
R24Duplicate Entry
R25Addenda Error
R26Mandatory Field Error
R27Trace Number Error
R28Routing Number Check Digit Error
R29Corporate Customer Advises Not Authorized
R30RDFI Not Participant in Check Truncation Program
R31Permissible Return Entry (CCD and CTX only)
R32RDFI Non-Settlement
R33Return of XCK Entry
R34Limited Participation DFI
R35Return of Improper Debit Entry
R36Return of Improper Credit Entry
R37Source Document Presented for Payment
R38Stop Payment on Source Document
R39Improper Source Document/Source Document Presented for Payment
R40Return of ENR Entry by Federal Government Agency
R41Invalid Transaction Code
R42Routing Number/Check Digit Error
R43Invalid DFI Account Number
R44Invalid Individual ID Number/Identification Number
R45Invalid Individual Name/Company Name
R46Invalid Representative Payee Indicator
R47Duplicate Enrollment
R50State Law Affecting RCK Acceptance
R51Item Related to RCK Entry is Ineligible or RCK Entry is Improper
R52Stop Payment on Item Related to RCK Entry
R53Item and RCK Entry Presented for Payment
R61Misrouted Return
R67Duplicate Return
R68Untimely Return
R69Field Error(s)
R70Permissible Return Entry Not Accepted/Return Not Requested by ODFI
R71Misrouted Dishonored Return
R72Untimely Dishonored Return
R73Timely Original Return
R74Corrected Return
R75Return Not a Duplicate
R76No Errors Found
R80IAT Entry Coding Error
R81Non-Particpant in IAT Program
R82Invalid Foreign Receiving DFI Identification
R83Foreign Receiving DFI Unable to Settle
R84Entry Not Processed by Gateway

Financial institutions play an important role in the Dwolla network.

Dwolla, Inc. is an agent of Veridian Credit Union and Compass Bank and all funds associated with your account in the Dwolla network are held in pooled accounts at Veridian Credit Union and Compass Bank. These funds are not eligible for individual insurance, including FDIC insurance and may not be eligible for share insurance by the National Credit Union Share Insurance Fund. Dwolla, Inc. is the operator of a software platform that communicates user instructions for funds transfers to Veridian Credit Union and Compass Bank.