External Account
CorePro allows customers to transfer funds to/from their existing checking and savings accounts at any financial institution within the US and its territories. These are referred to as "externalAccount" objects in CorePro vernacular.
There is a limit to the number of external accounts that may be created for a given customer. This limit is defined by the perUserExternalAccountCountMax
property returned from /program/get.
The total number of external accounts for a customer is calculated as follows:
- All with a status of
Unverified
,VerifyLocked
, orVerified
- All with a status of
Archived
AND tied to at least one transaction that has settled in the past 90 calendar days
- If the limit has been reached, another external account cannot be added via the CorePro API. There must be human intervention (by a CSR) to validate the new external account, and it must be created via the CorePro Admin site. This is a fraud prevention mechanism.
A program can be configured to automatically create all external accounts in a Verified status. This is typically used when the client is in control of the external account itself -- e.g. prepaid card.
Otherwise a program can be configured to require customers to verify ownership of the external bank accounts prior to use via the following process:
If Verification Type is None
or Any
:
/externalAccount/create
is called - status of account isVerified
. No further action is needed.
If Verification Type is TrialDeposits
or Any
:
/externalAccount/initiate
is called - status of account isUnverified
(i.e. pending verification)- CorePro initiates two small deposits and a single offsetting withdrawal on the external account. Amounts are random, but will fall between $0.01 and $0.49 inclusive.
In the Sandbox environment, one amount is hardcoded to
0.18
and the other is0.28
. Since no ACH files are actually being sent to an external bank in the Sandbox environment, no funds are actually transferred. - At a later date, the customer logs onto your site and enters the amounts that were placed on the external account
/externalAccount/verify
is called with the amounts-
If the amounts are valid then the status of the account is set to
Verified
- If verification attempts fail 3 or more times, status of the account is set to
VerifyLocked
- If verification time limit has been exceeded, status of the account is set to
Expired
- If manual intervention by a CSR happens prior to verification, status of account may be set to
Denied
- If verification attempts fail 3 or more times, status of the account is set to
externalAccount Object
Represents a single externalAccount in CorePro.
details
Property | Data Type (length) |
Description |
---|---|---|
externalAccountId |
integer | The unique identifier for an externalAccount in CorePro. Will be returned on the /externalAccount/create or /externalAccount/initiate call. |
customerId |
integer | Customer who owns the external bank account |
tag |
string (50) | A caller-specified, immutable, unique identifier for this externalAccount. Must be unique within a given Program. Maximum length is 50 characters. |
name |
string (50) | Bank Name according to FDIC. If your program has ACH via NACHA enabled, the routingNumber will be used to retrieve the actual NACHA bank name (via the Federal Reserve data file). If your program does not have ACH via NACHA enabled, whatever value you provide here will be stored verbatim.
|
routingNumber |
string (50) | Routing Transit Number (RTN) is a nine-digit bank code used to identify a financial institution. |
routingNumberMasked |
string (10) | Last 4 digits of the routingNumber property value, preceded by 6 '*'. e.g.: ******1234 |
accountNumber |
string (17) | The account number of this account at the external bank. |
accountNumberMasked |
string (10) | Last 4 digits of the accountNumber property value, preceded by 6 '*'. e.g.: ******1234 |
type |
string (50) |
Possible values include:
|
nickName |
string (50) | A user-friendly name that can be displayed in place of the name property (which, if your program has ACH via NACHA enabled, will be automatically assigned the bank name returned by the Federal Reserve data file for the given routingNumber ). |
status |
string |
Possible values include:
|
statusDate |
datetime | The date the status last changed |
lastModifiedDate |
datetime | Date when the object was last altered in any way |
nocCode |
string (10) | Notification of Change code. |
isActive |
boolean | Deprecated. Replaced by |
isLocked |
boolean | Denotes if this externalAccount is locked, typically caused by fraud prevention mechanisms or manual intervention via the Admin console. Note other flags such as Status=Verified must also be set before a customer can perform any functions. |
lockedDate |
datetime | Denotes the last time isLocked was set to true. Example format: 2014-01-01T00:00:00.000+00:00 |
lockedReason |
string (255) | The reason isLocked was set to true. Freeform. |
customField1 |
string (50) | A property for holding client-defined data. There is no business logic in CorePro for a custom field. |
customField2 |
string (50) | A property for holding client-defined data. There is no business logic in CorePro for a custom field. |
customField3 |
string (50) | A property for holding client-defined data. There is no business logic in CorePro for a custom field. |
customField4 |
string (50) | A property for holding client-defined data. There is no business logic in CorePro for a custom field. |
customField5 |
string (50) | A property for holding client-defined data. There is no business logic in CorePro for a custom field. |
archive
Archives an external account, meaning it can not be used in future transfers. An external account cannot be archived while it has pending transactions.
Note: This is a one-way function; once an external account is archived, it cannot be "unarchived". Also, there is a limit of 3 external accounts that can be archived per customer, per day. This limit resets to 0 daily between midnight and 5:00 AM in the corresponding Time Zone of your Bank of Record.
POST /externalAccount/archive
Request Body Parameters
customerId |
Required | Customer ID (returned when customer originally created) |
externalAccountId |
Required | External Account ID (returned when external account was originally created) |
Response Data
externalAccountId |
ExternalAccount ID of the external account. |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
62501 | Invalid external account id '{0}'. | |
62502 | Unable to deactivate an external account that is not in a Verified status. | |
62503 | Unable to deactivate an external account for a customer who has a pending transaction or any account with a non-zero balance. | |
62505 | Unable to archive as there are outstanding transactions. | |
62506 | Unable to archive an external account whose status is {0}. |
Example
Request
POST /externalAccount/archive Authorization: Basic PutBase64TokenHere
{ "customerId": 859918, "externalAccountId": 943856 }
Response
200
{ "data": { "customerId": 859918, "externalAccountId": 943856, "status": "Archived" }, "errors": [], "requestId": "3338b624-0d8c-4114-a5b9-5e0140ed6450", "status": 200 }
create
Creates a new external account. Functions properly only if your Program is configured with External Account Verification Type set to None
or Any
.
Note: This route returns a 200 upon success. If you use a Q2 provided SDK, this route returns a 201 upon success instead.
POST /externalAccount/create
Request Body Parameters
customerId |
Required | Customer ID (returned when customer originally created) |
routingNumber |
Required unless type is Prepaid |
The routing number of the external account. If you have NACHA enabled, the name property (i.e. bank name for this routing number) will be automatically assigned the value return by the Federal Reserve data file.
NOTE for Sandbox Environment: If you have NACHA enabled, a "magic value" of |
accountNumber |
Required unless type is Prepaid |
The account number of the external account |
firstName |
Required unless type is Prepaid OR lastName has been specified |
The first name of the person associated with the external account |
lastName |
Required unless type is Prepaid OR firstName has been specified |
The last name of the person associated with the external account |
type |
Required |
Accepted values are:
* - Your program must be configured to allow these values. Only programs that vet the external account via an approved mechanism outside of CorePro will be allowed to do this. If your program is not, you must follow the "External Account Verification is enabled" flow outlined above. If in doubt of the proper value to pass for the |
name |
Optional |
If your program has ACH via NACHA enabled, the routingNumber provided will be used to retrieve the actual NACHA bank name (via the Federal Reserve data file). If your program does not have ACH via NACHA enabled, whatever value you provide here will be stored verbatim.
NOTE for Sandbox Environment: If you have NACHA enabled, a "magic value" of |
nickName |
Optional | If not supplied, will assume the same value as the name parameter. |
tag |
Optional | A program-wide unique identifier defined by the caller that is associated with this external account. |
customField1 |
Optional | Any value up to 50 characters in length |
customField2 |
Optional | Any value up to 50 characters in length |
customField3 |
Optional | Any value up to 50 characters in length |
customField4 |
Optional | Any value up to 50 characters in length |
customField5 |
Optional | Any value up to 50 characters in length |
NOTE: There is a limit to the number of external accounts that may be created for a given customer. This limit is defined by the perUserExternalAccountCountMax
property returned from /program/get. If the limit has been reached, another external account cannot be added via the CorePro API. There must be human intervention to validate the new external account, and it must be created via the CorePro Admin site. This is a fraud prevention mechanism.
The total number of external accounts for a customer is calculated as follows:
- All with a status of
Unverified
,VerifyLocked
, orVerified
- All with a status of
Archived
AND tied to at least one transaction that has settled in the past 90 calendar days
Response Data
An externalAccount Object |
This external account will be in a Verified status upon success of this call. |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
62001 | At most {0} external account(s) may be added. | |
62002 | Invalid Type: '{0}'. Valid values are 'Prepaid', 'Checking', or 'Savings'. | |
62003 | Tag {0} is already associated with another external account. | |
62004 | External account archival limit reached for today. | |
62005 | Either FirstName or LastName must be provided, preferrably both. | |
62006 | Routing number is a required field. | |
62007 | Account number is a required field. | |
62008 | Account number must contain only digits 0-9. | |
62009 | Account number must be no more than 17 digits in length. | |
69203 | Routing number is a required field. |
Example
Request
POST /externalAccount/create Authorization: Basic PutBase64TokenHere
{ "accountNumber": "3464971", "customerId": 859918, "firstName": "John", "lastName": "Smith", "routingNumber": "123456789", "tag": "859918account", "type": "Checking" }
Response
200
{ "data": { "accountNumberMasked": "*************4971", "customerId": 859918, "customField1": "", "customField2": "", "customField3": "", "customField4": "", "customField5": "", "externalAccountId": 943856, "firstName": "John", "isActive": true, "isLocked": false, "lastModifiedDate": "2019-03-20T13:10:05.454-05:00", "lastName": "Smith", "lockedReason": "", "name": "COREPRO SANDBOX BANK", "nickName": "", "nocCode": "", "routingNumberMasked": "*****6789", "status": "Verified", "statusDate": "2019-03-20T13:10:05.454-05:00", "tag": "859918account", "type": "Checking" }, "errors": [], "requestId": "802c6b01-c31b-4d79-bd13-4a9b4de57c44", "status": 200 }
get
Retrieve externalAccount information by the given customerId and externalAccountId
Note: When you provide an invalid identifier (id,tag, or emailAddress), all routes ending with /get
returns 400 (Bad Request).
GET /externalAccount/get/{customerId}/{externalAccountId}
Request Parameters
customerId |
Required | Customer ID (returned when customer originally created) |
externalAccountId |
Required | External Account ID (returned when external account was originally created) |
Response Data
An externalAccount Object |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
66201 | Invalid external account id '{0}'. |
Example
Request
GET /externalAccount/get/231/253 Authorization: Basic PutBase64TokenHere
Response
200
{ "data": { "accountNumberMasked": "******9873", "customerId": 231, "customField1": "98723ASDF", "externalAccountId": 253, "firstName": "Brock", "isActive": true, "isLocked": false, "lastName": "Weaver", "lockedDate": "9999-12-31T23:59:59.999+00:00", "name": "PrepaidAbc", "nickName": "pp1", "routingNumberMasked": "******1234", "status": "Unverified", "statusDate": "2014-02-25T15:21:16.152-06:00", "tag": "tag12345", "type": "Savings" }, "errors": [], "status": 200 }
getByTag
Retrieve externalAccount information by the given customerId and tag
Note: When you provide an invalid identifier (id,tag, or emailAddress), all routes ending with /getByTag
returns 400 (Bad Request).
GET /externalAccount/getByTag/{customerId}/{tag}
Request Parameters
customerId |
Required | Customer ID (returned when customer originally created) |
tag |
Optional | A program-wide unique identifier defined by the caller that is associated with this external account. |
Response Data
An externalAccount Object |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
66301 | Tag '{0}' does not exist or is not tied to customer {1}. |
Example
Request
GET /externalAccount/getByTag/231/tag12345 Authorization: Basic PutBase64TokenHere
Response
200
{ "data": { "accountNumberMasked": "******9873", "customerId": 231, "customField1": "98723ASDF", "externalAccountId": 253, "firstName": "Brock", "isActive": true, "isLocked": false, "lastName": "Weaver", "lockedDate": "9999-12-31T23:59:59.999+00:00", "name": "PrepaidAbc", "nickName": "pp1", "routingNumberMasked": "******1234", "status": "Unverified", "statusDate": "2014-02-25T15:21:16.152-06:00", "tag": "tag12345", "type": "Savings" }, "errors": [], "status": 200 }
initiate
Initiates a new external account. Functions properly only if your Program is configured with External Account Verification Type set to TrialDeposits
or Any
.
In the sandbox environment, if you have NACHA enabled, a "magic value" of 123456789
for the routingNumber
property may be used for testing purposes. This will set the name
to COREPRO SANDBOX BANK
.
POST /externalAccount/initiate
Request Body Parameters
customerId |
Required | Customer ID (returned when customer originally created) |
routingNumber |
Required |
The routing number of the external account. If your program has ACH via NACHA enabled, the name property (i.e. the NACHA bank name for this routing number) will be automatically assigned the value return by the Federal Reserve data file.
NOTE for Sandbox Environment: If you have NACHA enabled, a "magic value" of |
accountNumber |
Required | The account number of the external account |
firstName |
Required | The first name of the person associated with the external account |
lastName |
Required | The last name of the person associated with the external account |
type |
Required | Accepted values are:
|
name |
Optional | If your program has ACH via NACHA enabled, the routingNumber provided will be used to retrieve the actual NACHA bank name (via the Federal Reserve data file). If your program does not have ACH via NACHA enabled, whatever value you provide here will be stored verbatim.
NOTE for Sandbox Environment: If you have NACHA enabled, a "magic value" of |
nickName |
Optional | If not supplied, will assume the same value as the name parameter. |
tag |
Optional | A program-wide unique identifier defined by the caller that is associated with this external account. |
customField1 |
Optional | Any value up to 50 characters in length |
customField2 |
Optional | Any value up to 50 characters in length |
customField3 |
Optional | Any value up to 50 characters in length |
customField4 |
Optional | Any value up to 50 characters in length |
customField5 |
Optional | Any value up to 50 characters in length |
NOTE: Only one external account may be created. If it is then deactivated, another external account still cannot be added via the CorePro API. There must be human intervention to validate the customer again and the second external account must be created via the CorePro Admin site. This is a fraud prevention mechanism.
NOTE FOR SANDBOX ONLY: To enable easier testing, all trial deposit amounts in the Sandbox environment will be 0.18
and 0.28
, and /externalAccount/verify
can be called immediately. However, in production, a request to /externalAccount/verify
must be sent at a later date to allow time for the ACH process to happen at the external bank.
Response Data
An externalAccount Object |
Upon success, two trial deposits will have been made to the external account. Those deposits are performed via ACH, so the customer will be unable to verify them immediately. You will need to allow the customer to visit at a later date and supply the verification amounts, then call /externalAccount/verify . This external account will be in a Unverified status upon success of this call. |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
62601 | Invalid Type: '{0}'. Valid values are 'Checking' or 'Savings'. | |
62602 | An external bank account with nickname '{0}' already exists. | |
62603 | Name is a required field. | |
62604 | FirstName is a required field. | |
62605 | LastName is a required field. | |
62606 | Routing number is a required field. | |
62607 | Account number is a required field. | |
62608 | Tag {0} is already associated with another external account. | |
62609 | At most {0} external account(s) may be added. | |
62610 | Routing Number '{0}' is invalid. | |
62611 | External account archival limit reached for today. | |
62612 | Account number must contain only digits 0-9. | |
62613 | Account number must be no more than 17 digits in length. | |
69203 | Routing number is a required field. | |
69205 | Routing number lookup failed. {0} | |
69206 | Routing number {0} must be numeric. |
Example
Request
POST /externalAccount/initiate Authorization: Basic PutBase64TokenHere
{ "accountNumber": "641967", "customerId": 864630, "firstName": "John", "lastName": "Smith", "routingNumber": "123456789", "tag": "My Account", "type": "Checking" }
Response
200
{ "data": { "accountNumberMasked": "*************1967", "customerId": 864630, "customField1": "", "customField2": "", "customField3": "", "customField4": "", "customField5": "", "externalAccountId": 943881, "firstName": "John", "isActive": true, "isLocked": false, "lastModifiedDate": "2019-03-20T13:30:46.157-05:00", "lastName": "Smith", "lastVerifyExpiredDate": "2019-03-22T13:30:46.161-05:00", "lastVerifySentDate": "2019-03-20T13:30:46.161-05:00", "lockedReason": "", "name": "COREPRO SANDBOX BANK", "nickName": "", "nocCode": "", "routingNumberMasked": "*****6789", "status": "Unverified", "statusDate": "2019-03-20T13:30:46.157-05:00", "tag": "My Account", "type": "Checking" }, "errors": [], "requestId": "a16eeebb-60bf-498b-8a94-18c895d69222", "status": 200 }
list
List all external accounts for a given customer
GET /externalAccount/list/{customerId}
Request Parameters
customerId |
Required | Customer ID (returned when customer was created) |
Response Data
A list of externalAccount Objects |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
Example
Request
GET /externalAccount/list/231 Authorization: Basic PutBase64TokenHere
Response
200
{ "data": [ { "accountNumberMasked": "******9873", "customerId": 231, "customField1": "234ASDF", "externalAccountId": 253, "firstName": "Brock", "isActive": true, "isLocked": false, "lastName": "Weaver", "lockedDate": "9999-12-31T23:59:59.999+00:00", "name": "PrepaidAbc", "nickName": "pp1", "routingNumberMasked": "******1234", "status": "Unverified", "statusDate": "2014-02-25T15:21:16.152-06:00", "tag": "tag12345", "type": "Savings" } ], "errors": [], "status": 200 }
update
Update externalAccount information
POST /externalAccount/update
Request Body Parameters
customerId |
Required | Customer ID (returned when customer originally created) |
externalAccountId |
Required | External Account ID (returned when external account was originally created) |
nickname |
Optional | New nickname for the external account. |
tag |
Optional | New tag for the external account. |
customField1 |
Optional | Any value up to 50 characters in length |
customField2 |
Optional | Any value up to 50 characters in length |
customField3 |
Optional | Any value up to 50 characters in length |
customField4 |
Optional | Any value up to 50 characters in length |
customField5 |
Optional | Any value up to 50 characters in length |
NOTE: No other values may be updated on an external account.
Response Data
An externalAccount Object |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
62401 | Another external account already exists with the nickname of '{0}'. | |
62402 | Invalid external account id '{0}'. | |
62403 | Tag '{0}' is already associated with another external account. |
Example
Request
POST /externalAccount/update Authorization: Basic PutBase64TokenHere
{ "customerId": 859918, "externalAccountId": 943856, "nickName": "My Bank" }
Response
200
{ "data": { "accountNumberMasked": "*************4971", "customerId": 859918, "customField1": "", "customField2": "", "customField3": "", "customField4": "", "customField5": "", "externalAccountId": 943856, "firstName": "John", "isActive": true, "isLocked": false, "lastModifiedDate": "2019-03-20T13:21:10.712-05:00", "lastName": "Smith", "lockedReason": "", "name": "COREPRO SANDBOX BANK", "nickName": "My Bank", "nocCode": "", "routingNumberMasked": "*****6789", "status": "Verified", "statusDate": "2019-03-20T13:10:05.454-05:00", "tag": "", "type": "Checking" }, "errors": [], "requestId": "0fe41c0d-57a5-4396-a59d-33a7fa869e97", "status": 200 }
verify
Verify an external account
POST /externalAccount/verify
Request Body Parameters
customerId |
Required | Customer ID (returned when customer originally created) |
externalAccountId |
Required | External Account ID (returned when external account was originally created) |
amount1 |
Required | Value of one of the trial deposit amounts automatically performed at external account create time |
amount2 |
Required | Value of the other trial deposit amount automatically performed at external account create time |
Response Data
An externalAccount Object |
The external account will be in a status of Verified upon successful completion of this call. Transfers may then be made using this external account. |
Error Codes
Code | Message (en-US) | Notes |
1-60000 | Any "Common Error Code" may occur. | See Common Error Codes |
62201 | Invalid ExternalAccountId '{0}'. | |
62202 | External account is in a Locked status. Unable to verify. | |
62203 | External account is in a Denied status. Unable to verify. | |
62204 | External account has already been verified. | |
62205 | Verification period expired on '{0}'. | |
62206 | Maximum number of failed attempts exceeded. Verification has been locked. | |
62207 | Given amounts do not match what is on record. {0} attempt(s) remaining. | |
62301 | Another external account already exists with the nickname of '{0}'. | |
62302 | Invalid external account id '{0}'. |
Example
Request
POST /externalAccount/verify Authorization: Basic PutBase64TokenHere
{ "amount1": 0.18, "amount2": 0.28, "customerId": 864630, "externalAccountId": 943881 }
Response
200
{ "data": { "accountNumberMasked": "*************1967", "customerId": 864630, "customField1": "", "customField2": "", "customField3": "", "customField4": "", "customField5": "", "externalAccountId": 943881, "firstName": "John", "isActive": true, "isLocked": false, "lastModifiedDate": "2019-03-20T13:40:16.165-05:00", "lastName": "Smith", "lastVerifyExpiredDate": "2019-03-22T13:30:46.161-05:00", "lastVerifySentDate": "2019-03-20T13:30:46.161-05:00", "lockedReason": "", "name": "COREPRO SANDBOX BANK", "nickName": "", "nocCode": "", "routingNumberMasked": "*****6789", "status": "Verified", "statusDate": "2019-03-20T13:40:16.165-05:00", "tag": "My Account", "type": "Checking" }, "errors": [], "requestId": "49947ad3-15e1-4973-bdf3-0c7301cb7ec6", "status": 200 }