Bank Account validation is a crucial aspect of a company’s risk assessment. Understanding their customers’ banking status will allow our Clients to significantly mitigate fraud and payment acceptance risk.
With credit cards, companies can authorize or decline a transaction based on the credit limit at the time of payment and can set aside funds to cover the payments. However, for ACH or electronic checks, we currently do not have an authorization process as with credit cards. And with ACH returns costing money to Companies, there is an urgent need for a solution that does bank and identity verification. This will also help ensure that the payments we push through will not be returned.
Bank Account Validation is available within EBPP as part of your bill pay setup. This function should not be used by EBPP Clients unless you need to validate bank accounts outside of your EBPP setup, and a separate license must be purchased to make use of this standalone service.
The HTTP Authorization request header is used to provide authentication information. This header looks like the following.
Authorization : OPAY1-HMAC-SHA256 Credential=...,Signature=...
The constituents of the authorization header are explained in the table below.
Item | Description |
---|---|
OPAY1-HMAC-SHA256 | The algorithm that is used to calculate the signature. |
Credential | The api key |
Signature | The Base 64 encoded value of the signature bytes. Calculating the signature bytes is explained below. |
Signature Calculation
Signature is calculated as follows.
Base64(HMAC-SHA256(secret,input))
The calculation is explained in detail below.
Item | Description |
---|---|
Base64() | The encoding of the signature bytes. |
HMAC-SHA256() | The cryptographic function that computes the HMAC by using the SHA256 algorithm with the client secret provided. |
secret | The secret key specific to the client that is shared with the client during onboarding. |
input | The string value of the canonicalized transform of request data that includes the HTTP method, URL, headers, query parameters and body. The details of computing the input is explained below. |
The string input is computed as follows.
input = method():path():queryString():headers():payload()
Each of the substrings is explained below.
Item | Description |
---|---|
method() | The HTTP method for the given request and evaluates to one of GET, PUT, POST or DELETE. |
path() | The absolute path component of the URI—everything starting with the "/" that follows the domain name and up to the end of the string or to the question mark character ("?") if the given URL has query string parameters. |
queryString() | A string in the format param1=value1¶m2=value2&…, where the query parameters are sorted in alphabetical order of the parameter names. In case multiple values are present for a parameter, the query parameters are sorted in alphabetical order of the parameter names and subsequently by the parameter values for each such paramter. Both the parameter names and their values should be trimmed for leading and trailing whitespaces, should be in their normal pre-encoded format. Only parameters with non-empty values, after trimming the leading and trailing whitespaces, should be included. If there are no query parameters at all, the queryString() should evaluate to an empty string (“”). |
headers() | A string in the format header1=value1&header2=value2&.......&headerN=valueN. The headers are to be sorted alphabetically. Both the header names and their values must be trimmed for leading and trailing white-space, and in their normal pre-encoded format . Only the headers listed by the application and those that are non-empty, after trimming the leading and trailing whitespaces, are to be included. |
payload() | The raw HTTP body |
The HTTP Authorization request header is used to provide authentication information. This header looks like the following.
Authorization : OPAY2-HMAC-SHA256 Credential=...,Signature=...
The constituents of the authorization header are explained in the table below.
Item | Description |
---|---|
OPAY2-HMAC-SHA256 | The algorithm that is used to calculate the signature. |
Credential | The api_key |
Signature | The Base 64 encoded value of the signature bytes. Calculating the signature bytes is explained below. |
Signature Calculation
Signature is calculated as follows.
Base64(HMAC-SHA256(secret,input))
The calculation is explained in detail below.
Item | Description |
---|---|
Base64() | The encoding of the signature bytes. |
HMAC-SHA256() | The cryptographic function that computes the HMAC by using the SHA256 algorithm with the client secret provided. |
secret | The secret key specific to the client that is shared with the client during onboarding. |
input | The string value of the canonicalized transform of client_key, api_key, secret_ket,timestamp. The details of computing the input is explained below. |
The string input is computed as follows.
input = client_key:api_key:secret_key:timestamp
The HTTP Authorization request header is used to provide authentication information. This header looks like the following.
Authorization : OPAY3-HMAC-SHA256 Credential=...
The constituents of the authorization header are explained in the table below.
Item | Description |
---|---|
OPAY3-HMAC-SHA256 | The algorithm that is used to calculate the signature. |
Credential | The api_key |
Account Validation uses standard HTTP response codes to return the status of an API call. Additional information, such as errors, may be useful to a caller. An HTTP response code of 2xx indicates success. In this case, additional information pertaining to the request is sent back in the header parameters. An HTTP response code of 4xx indicates a client error and 5xx indicates a processing error. In these cases, Account Validation also returns a list of errors in the response body in JSON. Each error has a code, message, and specifics on which field the error pertains to (if applicable.)
Http Response Codes
Code | Reason |
---|---|
200 - OK | Successfully processed the request |
400 - Bad Request | The request was rejected, most likely due to invalid parameters |
401, 403 - Unauthorized, Forbidden | Unauthorized or forbidden request |
500 - Internal Server Error | Something went wrong with Account Validation and the request could not be processed. |
An HTTP response code of 4xx indicates a client error and 5xx indicates a processing error. In these cases, Account Validation also returns a list of errors in the response body in JSON. Each error has a code, message, and specifics on which field the error pertains to (if applicable). The Account Validation API specific error codes are described here.
code | message |
---|---|
error_field | The error returned if a mandatory field is missing value or if the value is invalid. This is accompanied by the field that caused the error. |
error_provider_reason_code_unknown | The request cannot be processed due to unknown reason code received from provider. |
The set of rules that define the risk level and the recommended decision corresponding to each of the underlying reason codes returned by the provider. There are 3 standard rulesets available to the client. In addition to these, clients can define their own rulesets. The following list captures the default ruleset definition.
The code for the underlying reason that the account validation provider returns. This is available in the additional data section of the Account Validation API response. The following is the complete list of provider reason codes and the corresponding descriptions.
Code | Description | Decision | Risk Level |
---|---|---|---|
1 | Invalid Bank Routing # | DECLINE | 900 |
2 | Invalid Account # or Account # format is suspicious | DECLINE | 900 |
3 | OFAC Warning / Error - Misc. errors | ACCEPT | 300 |
3a | Requested Merchant Stop – rVd Customer has requested processing turned off for merchant. | DECLINE | 900 |
3b | Customer MICR Stop – rVd customer has requested this bank routing and account number be declined. This will only decline for requesting rVd customer and not throughout the database. | DECLINE | 900 |
10a | Invalid DL format | ACCEPT | 300 |
10b | DL Required | DECLINE | 300 |
11a | Invalid Telephone Number | ACCEPT | 300 |
11b | Phone # Required | ACCEPT | 300 |
12 | Amount exceeds limits set in rule set | ACCEPT | 200 |
13 | # or $ amount exceeds limits set in rule set for the last 24 hours | ACCEPT | 200 |
14 | # or $ amount exceeds limits set in rule set for the window of days. | ACCEPT | 200 |
15 | Check # is lower than the minimum check number allowed in the rule set | DECLINE | 200 |
16 | Duplicate transaction detected | ACCEPT | 100 |
4 | Customer has unpaid item(s) with at least one item reported as R02 (Account Closed), R03 (No Account) or R04 (Invalid Account #) | DECLINE | 900 |
5 | Customer has unpaid item(s) with at least one item reported as R05 (Reserved) R07 (Authorization Revoked), R10 (Not Authorized), R29 (Corporate- Not Authorized), or R51 (Item Ineligible) | DECLINE | 900 |
6 | Customer has recent unpaid return item(s). The reason for the return is suspicious. | DECLINE | 900 |
7 | Customer has unpaid return item(s). Returns are not recent but the reason for the return is suspicious. | DECLINE | 900 |
8 | Customer has 1 known unpaid item, other history is positive. Account is not known to be closed | DECLINE | 900 |
9 | Customer has multiple unpaid items. Account is not known to be closed. | ACCEPT | 100 |
17 | Reported history of R02 (Account Closed) | ACCEPT | 100 |
18 | Reported history of R03 (No Account) in the last 12 months | ACCEPT | 100 |
19 | Reported history of R04 (Invalid Account #) in the last 12 months | ACCEPT | 100 |
20 | Reported history of R05 (Reserved) in the last 12 months | ACCEPT | 100 |
21 | Reported history of R07 Authorization Revoked) in the last 12 months | ACCEPT | 100 |
22 | Reported history of R10 (Not Authorized) in the last 12 months | ACCEPT | 100 |
23 | Reported history of R29 (Corporate- Not Authorized) in the last 12 months | ACCEPT | 100 |
24 | Reported history of R51 (Item Ineligible) in the last 12 months | ACCEPT | 100 |
25 | History of Returns. No current unpaid items | ACCEPT | 100 |
26 | Possible NON DDA account | ACCEPT | 100 |
27 | Customer has no unpaid returns. Account is not known to be closed. | ACCEPT | 100 |
28 | Customer has recently paid an item and is no longer has an unpaid debt in the database | ACCEPT | 100 |
29 | Customer has no unpaid items with limited positive history | ACCEPT | 100 |
30 | Customer has no unpaid items with strong positive history | ACCEPT | 100 |
There are cases where Account Validation wants to indicate to the account holder that they could contact the underlying provider to enquire about the account validation response. This happens when Account Validation declines the account on the basis of certain reason codes that provider returns. The idea is to allow the consumer to contact the provider in order to give clarifications and possibly correct the account validation status for subsequent requests, if they disagree with the provider's response.
This can be used for storing additional or contextual information. Account Validation supports upto 5 metadata fields, namely, context_attr_1, context_attr_2, context_attr_3, context_attr_4 and context_attr_5.
We support idempotency for the HTTP methods POST, PUT, DELETE and PATCH using the header parameter, namely, idempotent_request_key.
In other words, any POST, PUT, DELETE and PATCH request will be considered as a duplicate request or retry and not reprocessed by Account Validation if all the request parameters, including the path and query parameters, the request headers (excluding the timestamp header) and the request body, match with an earlier request. In case of duplicate requests or retries, the API response will be that of the original request.The only exceptions to this are the Retrieve API even though they may use HTTP POST.
The idempotent_request_key is valid only for a duration of one hour from the time of the original request. Any duplicate request or retries after a gap of one hour from the original request will be considered as a fresh request and reprocessed by Account Validation.
Account Validation does not support retry of GET requests and these are processed every time, irrespective of the idempotent_request_key.
Prescreen ACH/check payments to reduce the risk of fraud and returns. This service will process a submitted Routing and Account Number against provider's database containing positive and negative ACH/check writing history.
client_key required | string [ 0 .. 50 ] characters [a-zA-Z0-9_-]{1,50} The unique identifier assigned by Account Validation to the client. |
timestamp required | string The timestamp for the moment when the API call is made, in the format, yyyy-MM-dd HH:mm:ss.SSSZ For e.g., 2018-07-13 11:41:17.422+00:00 Please ensure that consecutive spaces are not used in the timestamp. |
idempotent_request_key required | string [ 0 .. 50 ] characters [a-zA-Z0-9]{1,50} The unique token that clients can generate and maintain in order to identify an API request. This is used by Account Validation to identify duplicate requests and retrials. Please refer to the "Duplicate Requests & Retrials" section for more details. |
product | string Enum: "orbipay_payments" "orbipay_ibav" The product identifier corresponding to the API. |
requestor | string [ 0 .. 50 ] characters [a-zA-Z0-9]{1,50} The identifier for the requestor of the API, in Account Validation. The value to be passed in the requestor field would depend on the requestor type. For customer, it would be the Account Validation generated customer id, for user, it would be the Account Validation user login id and for external user, it would be the client's external agent id. In the case of self registration, where there is no external identifier, the requestor can be set to 'guest'. |
requestor_type | string Enum: "customer" "client_agent" "external_user" Type of the requestor of the API. |
X-OPAY-Headers | string Intended for the future use. |
This JSON contains all the attributes of funding source
account_number required | string [ 1 .. 32 ] characters [a-zA-Z0-9]+ The number or reference that a customer uses to identify the bank account. |
routing_number required | string 9 characters [0-9]{9} The Routing number of the bank account. |
rule_set | string [ 1 .. 9 ] characters [G,L][0-9]{1,9} The identifier of the rule set to be used for the bank account validation. |
first_name | string [ 1 .. 60 ] characters '[0-9a-zA-Z #,.\'&/\-@!$%*()_+={}|:;`\[\]\^\~\\"]+' The first name of the customer. |
last_name | string [ 1 .. 60 ] characters '[0-9a-zA-Z #,.\'&/\-@!$%*()_+={}|:;`\[\]\^\~\\"]+' The last name of the customer. |
metadata | object Attributes used to capture contextual information. These are available in the Account Validation reports. |
request successful
Bad Request
Unauthorized
Forbidden
Internal server error
{- "account_number": "1001001234",
- "routing_number": "012345678",
- "rule_set": "G1",
- "first_name": "Michael",
- "last_name": "Smith",
- "metadata": {
- "context_attr_1": "addfundsrc",
- "context_attr_2": "onetime",
- "context_attr_3": "another context attribute if exist",
- "context_attr_4": "another context attribute if exist",
- "context_attr_5": "another context attribute if exist"
}
}
The DECLINE scenario.
{- "recommended_decision": "decline",
- "first_name_match": "yes",
- "last_name_match": "no",
- "additional_data": {
- "provider_reason_code": "D"
}
}
This service is used to reduce ACH/check fraud and returns by processing a submitted Routing and Account Number against an extended network of ACH/check databases containing positive and negative ACH/check writing history
client_key required | string [ 0 .. 50 ] characters [a-zA-Z0-9_-]{1,50} The unique identifier assigned by Account Validation to the client. |
timestamp required | string The timestamp for the moment when the API call is made, in the format, yyyy-MM-dd HH:mm:ss.SSSZ For e.g., 2018-07-13 11:41:17.422+00:00 Please ensure that consecutive spaces are not used in the timestamp. |
idempotent_request_key required | string [ 0 .. 50 ] characters [a-zA-Z0-9]{1,50} The unique token that clients can generate and maintain in order to identify an API request. This is used by Account Validation to identify duplicate requests and retrials. Please refer to the "Duplicate Requests & Retrials" section for more details. |
product | string Enum: "orbipay_payments" "orbipay_ibav" The product identifier corresponding to the API. |
requestor | string [ 0 .. 50 ] characters [a-zA-Z0-9]{1,50} The identifier for the requestor of the API, in Account Validation. The value to be passed in the requestor field would depend on the requestor type. For customer, it would be the Account Validation generated customer id, for user, it would be the Account Validation user login id and for external user, it would be the client's external agent id. In the case of self registration, where there is no external identifier, the requestor can be set to 'guest'. |
requestor_type | string Enum: "customer" "client_agent" "external_user" Type of the requestor of the API. |
X-OPAY-Headers | string Intended for the future use. |
This JSON contains all the attributes of funding source
account_number required | string [ 1 .. 32 ] characters [a-zA-Z0-9]+ The number or reference that a customer uses to identify the bank account. |
routing_number required | string 9 characters [0-9]{9} The Routing number of the bank account. |
rule_set | string [ 1 .. 9 ] characters [G,L][0-9]{1,9} The identifier of the rule set to be used for the bank account validation. |
first_name | string [ 1 .. 60 ] characters '[0-9a-zA-Z #,.\'&/\-@!$%*()_+={}|:;`\[\]\^\~\\"]+' The first name of the customer. |
last_name | string [ 1 .. 60 ] characters '[0-9a-zA-Z #,.\'&/\-@!$%*()_+={}|:;`\[\]\^\~\\"]+' The last name of the customer. |
metadata | object Attributes used to capture contextual information. These are available in the Account Validation reports. |
request successful
Bad Request
Unauthorized
Forbidden
Internal server error
{- "account_number": "1001001234",
- "routing_number": "012345678",
- "rule_set": "G1",
- "first_name": "Michael",
- "last_name": "Smith",
- "metadata": {
- "context_attr_1": "addfundsrc",
- "context_attr_2": "onetime",
- "context_attr_3": "another context attribute if exist",
- "context_attr_4": "another context attribute if exist",
- "context_attr_5": "another context attribute if exist"
}
}
The DECLINE scenario.
{- "recommended_decision": "decline",
- "risk_level": 900,
- "first_name_match": "yes",
- "last_name_match": "no",
- "additional_data": {
- "notify_consumer": "yes",
- "notify_consumer_text": "Please contact consumer Affairs 888-222-7621 for any corrections.",
- "provider_reason_code": "10"
}
}