Handling Failed Payments

Routable's mission is to make payments as simple as possible, and most of the time, things go off without a hitch. However, in the world of banking and finance, there are dozens of handoffs and several potential issues that crop up during a payment's journey from your bank account to your vendor's. When the rare failure occurs, getting the issue resolved in a timely fashion is critical to make sure your vendor gets their funds when they expect to.

So, let's automate it!

First things first: Failures can happen at three points in the process: at creation time, during the setup process, and during transit. Each shows up differently, and should be reacted to differently as well.

Failures at Creation Time

A Payable that fails at creation time will return a 4xx error in response to your Create a Payable API call. These types of failures are usually the result of a malformed payload, issues with the vendor Company or the target PaymentMethod, or your Routable workspace. The body of the response will provide guidance as to what has gone wrong.

📘

Routable strongly recommends that you log all error responses, including timestamps and the Request-ID header. This will help us guide you through potential solutions if you need to reach out to Routable's Developer Experience Team for support.

Routable's error messages will never repeat sensitive data like payment information, so they should be safe to log.

Failures During Setup

If you get back a 201 Created response to your Create a Payable call, the Payable is now in Routable's database (and your integrated accounting software). However, sometimes, a delay in connecting to your accounting software or other external services will impact creation of the Payable. In that case, you'll receive a 202 Accepted response to your Create a Payable call instead. This means our system is still trying to finish the creation process in all of those external systems, and those processes can sometimes fail. When this happens, you will receive a WebhookEvent with an event of payable.creation_failed. These Payables are safe to recreate (with a new Idempotency Key), and will likely succeed on retry, as most of them are caused by transient issues with the handoff between Routable and your accounting software or ERP.

Failures While in Flight

Once your Payable hits the processing status, Routable has initiated the process of moving funds out of your account and along the requested rails until they reach their destination. Failures can occur at any point in this process. When they do, you'll receive a payable.status_changed WebhookEvent, and when querying the Payable, you'll note that it has a status of failed. If you do nothing else, these Payables will not be retried; the money just didn't move, and if it was already withdrawn from your account, it would be refunded. However, that's not usually what you want; you wanted the vendor to actually get their funds! So, let's try to figure out what went wrong and see what we can do about it programmatically.

If you Retrieve a Payable that is in a status of failed, you will find a failure_detail object in the response. It has a human-readable description, which will be useful if you need to reach out for help. But, the nine potential values of type are going to be much more useful for our automated responses. Inspect the type field, and take the following actions. Once the actions are completed, it will be safe to reinitiate a new Payable to the vendor.

compliance_failure

Some countries have additional legal requirements for the data that must be provided about your vendors in order to send them funds, such as government IDs or dates of birth. If one of those required fields is missing, or the data cannot be validated by the receiving bank, you will receive a compliance_failure error. The description of the failure_detail will describe what field(s) had issues. You should check the Supported Countries and Territories tool to determine what fields are required for the particular country, currency, and Company type being used. (If you're implementing a dynamic form builder in your app, you may wish to use the Retrieve a Country endpoint to get these requirements programmatically.) If you're providing all of the requested data, it may be inaccurate, and your team (or your code) should reach out to the vendor to obtain updated data.

funding_failure

The funding_failure error type occurs when Routable was unable to withdraw the necessary funds from your withdraw_from_account Account to complete the Payable.

  • If that Account is a bank, you may need to make a deposit to the account by transferring funds or with a call to your bank's API.
  • If the Account is your Routable balance, you can call the Deposit Funds into Routable Balance endpoint to make a deposit. Note that this can take a few days for funds to transfer. If you need faster balance deposits, reach out to your Routable customer success manager to learn about our VAN instant deposit option.
  • Of course, you can also just choose a new withdraw_from_account that has enough funds available to complete the transaction when you recreate the Payable.

invalid_bank_account_currency

This error occurs when you've tried to put a dollar-shaped peg in a Euro-shaped hole. If you look at the currency_code_receiver of the Payable, it will need to match the currency_code you'll see when you call Retrieve a Payment Method on the vendor's pay_to_payment_method. If it doesn't, the vendor's bank is unable to accept funds in the currency we sent them in, and this error will occur. In the reinitiated Payable, change the currency_code_receiver to match the PaymentMethod's currency.

invalid_bank_account_inactive

This one's pretty self-explanatory; the bank account referenced in pay_to_payment_method is invalid or inactive, so we'll need a new bank account to pay. Call the Re-Invite a Company endpoint, which will prompt the vendor to add new payment details. Once the vendor has added new payment information, you'll receive a payment_method.created WebhookEvent, notifying you that it is now safe to recreate the Payable with the provided ID as the new pay_to_payment_method. Alternatively, you can create a new Payable with a type of vendor_choice, and the vendor will be prompted to enter new bank information and then immediately receive the funds there once they do so without further intervention from you.

invalid_company_name

Some countries and banking systems require a match of the beneficiary name with the one provided. You may need to Update a Company to alter its business_name (for business Companies) or the business_contact_first_name and business_contact_last_name (for personal Companies). Some countries also require the beneficiary's name to be attached to the PaymentMethod. If the Supported Countries and Territories tool (or its programmatic equivalent, Retrieve a Country) indicates that owner_name is required, populate it with the updated value (in type_details.beneficiary_details.owner_name) as well.

other_unknown

This is a tough one to automate, because it's effectively our "miscellaneous" category. You can try to Create a Payable and try to resend the payment, as many of these "miscellaneous" errors are transient and subsequent efforts will succeed. If the retry also fails, you may need to inspect the description of the error and contact your Routable customer success manager to resolve the issue.

rejected_refused

This happens when the Company, or their bank, refused the payment. If you're certain that the vendor is expecting payment, the source was likely their bank, and so the best way to avoid the issue on retry is to send the payment to a different bank. Call the Re-Invite a Company endpoint, which will prompt the vendor to add new payment details. Once the vendor has added new payment information, you'll receive a payment_method.created WebhookEvent, notifying you that it is now safe to recreate the Payable with the provided ID as the new pay_to_payment_method. Alternatively, you can create a new Payable with a type of vendor_choice, and the vendor will be prompted to enter new bank information and then immediately receive the funds there once they do so without further intervention from you.

technical_error

This error most often happens when there are network or communication issues preventing every step of the chain to complete. These errors are nearly always transient, and you can simply recreate the Payable and try again; in the overwhelming majority of cases, the retry will succeed.