Payments
Gain visibility into payments and the ability to recover from failed payments
You can view the status of payments and recover from failed payments using the payments APIs.
Visible payments in the API include
- Debit payments used to fund payrolls
- Credit payments used to pay employees or contractors.
Payment Lifecycle
Payments in Check's API can carry a status
of one of the following:
draft
- Indicative of a payment for a payroll that has not yet been processed.processing
- Indicative of a payment that is "in-flight."paid
- Indicative of a payment that has completed and has been completed.failed
- Indicative of a payment that has failed to complete. Payments in this status can be recovered using the/retry
or/refund
endpoints.refunded
- Indicative of a payment that has been refunded. Once a payment has been refunded, it cannot be undone.
Failed Payments
Payments can fail for a variety of reasons - we give you visibility into the reason for the failure using the failure_code
on the payment object.
Two of the most common reasons for failure include
insufficient_funds
: This indicates a debit attempt failed due to a lack of available funds in the company's bank account. In this case, the company can add additional funds to their bank account and retry.account_closed
: This indicates a payment failed due to the closure of a bank account. In this case, a new bank account must be created to retry the payment. Refer to Bank Account Verification for additional information.
Retrying Failed Payments
Both failed credit and debit payments can be retried. Note that fetching the Payment object and reading its can_retry
field will guide whether a particular payment can be retried.
For debit payments, two options are available:
- [Recommended] Retrying with a wire payment. Using the
use_wire
retry method will provide the relevant wiring details so the company can fulfill their debt obligation by sending Check a wire. - Retrying with a new or existing bank account. Specifying a new
bank_account
id will initiate a new debit on the desired bank account.
Warning: Retrying using a new bank account likely results in employees not getting paid on payday due to limitations of the ACH network! After a re-debit attempt is initiated, we must wait 3 banking days to clear the ACH return window (period of time in which the payment could still fail). Additionally, since the debit failed once, there is an additional risk of a subsequent failure. For this reason, we highly recommend using wires to recover from failed debit payments, as they land within a matter of hours rather than days.
For credit payments, retrying is only possible by specifying a new bank account. Retried credit payments can be expected to settle within 1-2 banking days.
Refunding Failed Credit Payments
In some situations, refunding credit payments may be preferable to retrying. Refunding a credit payment means that the company will be refunded for the amount of the employee's net pay with the expectation they will pay the employee off-platform, usually by a check. Refunding a payment will also result in the payment method of the corresponding payroll_item
or contractor_payment
switching to manual
. The net pay funds will be returned to the company's bank account in 1-2 banking days. Given that funds would be returned to the company, we require that the company have funded its payroll in the first place - we won't refund a credit payment associated with an unfunded payroll.
Similar to the can_retry
field, we recommend leveraging the Payment object's can_refund
field to dictate whether a particular payment is eligible for refund.
Console
Console surfaces Payments as well as the ability to retry or refund payments.

Payment in Console

Console view of a failed Payment with the Retry button enabled
The retry panel shows the available means of retrying - using a wire or a new bank account

The retry panel
After a subsequent wire attempt has been created to recover from the failure, the "View Wire Details" button becomes available

Payments screen after a wire retry is attempted.

For failed employee payments, the refund option is available
API
Payments and payment attempts can be viewed using the API via the Payment and Payment Attempt objects. You can read or list these objects.
{
"id": "pyt_vIFHhvyGN47ej1upyIT8",
"status": "paid",
"amount": "4522.0400",
"type": "company_cash_requirement",
"parent_type": "payroll",
"parent_id": "pay_ENA4k8LMHbgpV07GLGSv",
"payment_attempts": [
{
"id": "pya_GaeJoEAzbqqc2D9GMfOF",
"created_at": "2022-02-18T21:32:44.957364Z",
"expected_completion_date": "2022-02-25",
"status": "paid",
"failure_code": null,
"payment_method": "wire",
"payment_instrument": null,
"wire_details": {
"account_number": "3302826020",
"routing_number": "121140399",
"bank_name": "Silicon Valley Bank",
"account_name": "SVB for benefit of CHECK TECHNOLOGIES",
"account_address": "3003 Tasman Drive, Santa Clara, CA 95054",
"amount": 4522.04
}
},
{
"id": "pya_Kgl6ERboridVSfv4XKdT",
"created_at": "2022-02-18T20:14:40.713837Z",
"expected_completion_date": "2022-02-23",
"status": "failed",
"failure_code": "insufficient_funds",
"payment_method": "ach",
"payment_instrument": "bnk_W7hjDGn6sU1d3U8dr9bq",
"wire_details": null
}
],
"can_retry": false,
"can_refund": false,
"direction": "debit"
}
Additionally, payments can be retried or refunded using the API.
Sandbox Testing
In the sandbox environment, payrolls transition to the next phase of payroll processing automatically. Every 5 minutes, an automated job moves payrolls from one phase to the next. To start the process, you just need to create and approve a payroll.
The phases are in the following order:
- Pending
- Processing
- Payments sent
Once payments are sent, any ACH payments are immediately shifted to a terminal status (completed
or failed
). Wire payments are reconciled and marked as completed
every 5 minutes.
Failure Scenarios
We provide a mechanism to incur and cause failed payments in our sandbox environment. Using designated company and employee names, you can simulate payrolls transitioning into a failed payment state.
NSF
To simulate a payroll that fails to due an NSF in sandbox, create a company with a trade_name
of NSF Co.
or No Account Co.
. The initial debit for payrolls on companies matching that trade name will immediately fail with a failure_code
of INSUFFICIENT_FUNDS
. Any retry attempts will immediately succeed.
Employee Closed Account
To simulate a failed credit due to an ACCOUNT_CLOSED
failure in sandbox, create an employee with first_name
set to Barry
and last_name
set to BadAccount
. The initial credit payment for payroll items matching that employee name will immediately fail with a failure_code
of ACCOUNT_CLOSED
. Any retry or refund attempts will immediately succeed.
Company Name | Employee Name | Result |
---|---|---|
NSF Co. or No Account Co. | Anything other than Barry BadAccount | Payroll debit fails due to INSUFFICIENT_FUNDS , employee credit succeeds |
NSF Co. or No Account Co. | Barry BadAccount | Payroll debit NSF, employee credit fails due to ACCOUNT_CLOSED |
Anything other than NSF Co. or No Account Co. | Barry BadAccount | Payroll debit succeeds, employee credit fails due to ACCOUNT_CLOSED |
Updated 3 months ago