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

  1. Debit payments used to fund payrolls
  2. 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:

  1. [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.
  2. 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 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


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.


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 NameEmployee NameResult
NSF Co. or No Account Co.Anything other than Barry BadAccountPayroll debit fails due to INSUFFICIENT_FUNDS, employee credit succeeds
NSF Co. or No Account Co.Barry BadAccountPayroll debit NSF, employee credit fails due to ACCOUNT_CLOSED
Anything other than NSF Co. or No Account Co.Barry BadAccountPayroll debit succeeds, employee credit fails due to ACCOUNT_CLOSED