These docs are for v2023-09-01. Click to read the latest docs for v2024-04-01.

Payroll Submission Blockers & Unblock Options

1. Overview

Running ACH payroll on a customerโ€™s behalf is an inherent risk. A payroll runner may not receive confirmation of a debit (withdrawal from employer account) failure until credits are sent out to employee accounts. This risk is mainly a factor for fast payments (<=2 days between debit and check date), though even 4-day payments carry this risk. The implications: bad actors can intentionally payout โ€œemployeesโ€ knowing that the withdrawal to pay them will fail.

Gusto Embedded employs various methods to identify and mitigate high-risk payments before they are run. These blockers and unblock options aim to maintain faster payment speeds without needing to secure funds before paying employees.

Concepts:

Earned Fast ACH Access: This requires a company to be on the platform a fixed number of days and run a fixed number of payrolls to qualify for faster ACH

Fast ACH Threshold: The limit at which a customer can process payroll using fast ACH. Payrolls that exceed this threshold will automatically be moved to 4-day ACH.

Submission blockers: These are blockers calculated after a payment calculation step, where Gustoโ€™s Risk team assesses the payment based on various factors. Submission blockers will have relevant unblock options that the employer will eventually be required to choose in order to submit the payment.

Unblock Options: Possible ways to satisfy a calculated blocker. The set of options can differ depending on the type of blocker.

Credit Blockers: Blockers for issuing credits out to employees. This is currently relevant to selected unblock options (for example for a wire_in type) The employer needs to record they sent the wire to our system using the Wire In Request API endpoint. Once our system verifies that the wire has been received by Gusto, the payroll blocker will be marked as resolved.

๐Ÿ“˜

To enable these features, please contact your Partner Growth Manager and Technical Solutions representatives.

2. Calculate & Get Payroll

If a customer attempts to process a payroll exceeding your specified Fast ACH Threshold, the payroll will include a submission_blockers object after calculating and retrieving the payroll.

{
    "submission_blockers": [
        {
            "blocker_type": "fast_ach_threshold_exceeded",
            "blocker_name": "Fast ACH Threshold Exceeded",
            "unblock_options": [
                {
                    "unblock_type": "wire_in",
                    "check_date": "2024-09-23",
                    "metadata": {
                        "wire_in_deadline": "2024-09-23T18:00:00Z",
                        "wire_in_amount": "315238.56"
                    }
                },
                {
                    "unblock_type": "move_to_four_day",
                    "check_date": "2024-09-25",
                    "metadata": {}
                }
            ],
            "selected_option": null,
            "status": "unresolved"
        }
    ]
}

3. Submit Payroll

When the submission blocker is triggered, the customer has three options to remove the blocker.

  1. The customer can move the payroll to a slower payment speed: "unblock_type": "move_to_four_day"
  2. The customer can update the payment method for each employee from Direct Deposit to Check: "payment_method": "Check"
  3. The customer can submit a wire transfer to preserve their current payment speed (2-day or Next day). "unblock_type": "wire_in"

You can submit the payroll via the Submit Payroll endpoint, but in this blocked state, you must also include the customerโ€™s submission_blockers election.

Option 1.

If the customer chooses to process the payroll at a slower payroll speed, you need to submit the payroll and include the following body param:

{
  "submission_blockers": [
    {
      "blocker_type": "fast_ach_threshold_exceeded",
      "selected_option": "move_to_four_day"
    }
  ]
}

Upon success, when you retrieve the payroll you will see the status has been resolved and the payroll will be on 4-day ACH instead of the customerโ€™s regular faster ACH speed.

{
    "submission_blockers": [
        {
            "blocker_type": "fast_ach_threshold_exceeded",
            "blocker_name": "Fast ACH Threshold Exceeded",
            "unblock_options": [
                {
                    "unblock_type": "wire_in",
                    "check_date": "2024-09-25",
                    "metadata": {
                        "wire_in_deadline": "2024-09-25T18:00:00Z",
                        "wire_in_amount": "315238.56"
                    }
                },
                {
                    "unblock_type": "move_to_four_day",
                    "check_date": "2024-09-26",
                    "metadata": {}
                }
            ],
            "selected_option": "move_to_four_day",
            "status": "resolved"
        }
    ]
}

Option 2.

The customer can update each employeeโ€™s payment method to Check. Gusto would no longer debit the net_pay_debit and reimbursement_debit, which reduces the overall company_debit. When updating the payroll, the following inclusion should be added for each employee in the employee_compensations array:

{  
  "employee_compensations": [  
    {  
      "employee_uuid": "187412e1-3dbe-491a-bb2f-2f40323a7067",  
      "payment_method": "Check"  
    }  
  ]  
}

Option 3.

If the customer chooses to preserve their faster payment speed, you need to submit the payroll and include the following body param:

{  
  "submission_blockers": [  
    {  
      "blocker_type": "fast_ach_threshold_exceeded",  
      "selected_option": "wire_in"  
    }  
  ]  
}

After submitting the payroll, it will be "processed": true however the customer will have to address the credit_blocker before Gusto issues credits to employees. After retrieving the payroll, the credit_blocker array will contain the wire_in_request_uuid required for the following step.

{
    "credit_blockers": [
        {
            "blocker_type": "waiting_for_wire_in",
            "blocker_name": "Waiting for Wire In",
            "unblock_options": [
                {
                    "unblock_type": "submit_wire",
                    "check_date": "2024-09-25",
                    "metadata": {
                        "wire_in_deadline": "2024-10-23T18:00:00Z",
                        "wire_in_amount": "315238.56",
                        "wire_in_request_uuid": "4cb59feb-fa96-481f-8477-0d0b8c61f4d2"
                    }
                }
            ],
            "selected_option": "submit_wire",
            "status": "unresolved"
        }
    ]
}

4. Get the Wire In Request

Call the Get a Single Wire In Request endpoint using the wire_in_request_uuid in the credit_blocker array from the previous step. The response will include key information such as the status, requested_amount, and wire_in_deadline.

[
    {
        "status": "awaiting_funds",
        "uuid": "4cb59feb-fa96-481f-8477-0d0b8c61f4d2",
        "origination_bank": "JP Morgan Chase",
        "origination_bank_address": "1 Chase Plaza, New York, NY 10081",
        "recipient_name": "Gusto, Inc",
        "recipient_address": "525 20th Street, San Francisco, CA 94107",
        "recipient_account_number": "813369829",
        "recipient_routing_number": "322271627",
        "additional_notes": null,
        "bank_name": null,
        "date_sent": null,
        "unique_tracking_code": "1trvxwgpe5bc",
        "payment_type": "Payroll",
        "payment_uuid": "f691942f-d475-42e6-b807-d2c2306217a1",
        "amount_sent": null,
        "requested_amount": "315237.55",
        "wire_in_deadline": "2024-09-24T18:00:00Z"
    }
]

5. Submit a Wire In Request

After the user has submitted the wire transfer through their bank, call the Submit a Wire In Request endpoint using the uuid from the previous response. Required fields for this request include date_sent, bank_name, and amount_sent.

curl --request PUT \
     --url https://api.gusto-demo.com/v1/wire_in_requests/{{wire_request_uuid}} \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '{
  "date_sent": "2024-09-20",
  "bank_name": "JP Morgan Chase",
  "amount_sent": "315237.55",
  "additional_notes": "Wire for 2024-09-24 payroll."
}'

Example Response:

{
    "status": "pending_review",
    "uuid": "4cb59feb-fa96-481f-8477-0d0b8c61f4d2",
    "origination_bank": "JP Morgan Chase",
    "origination_bank_address": "1 Chase Plaza, New York, NY 10081",
    "recipient_name": "Gusto, Inc",
    "recipient_address": "525 20th Street, San Francisco, CA 94107",
    "recipient_account_number": "813369829",
    "recipient_routing_number": "322271627",
    "additional_notes": "Wire for 2024-09-24 payroll.",
    "bank_name": "JP Morgan Chase",
    "date_sent": "2024-09-20",
    "unique_tracking_code": "1trvxwgpe5bc",
    "payment_type": "Payroll",
    "payment_uuid": "f691942f-d475-42e6-b807-d2c2306217a1",
    "amount_sent": "315237.55",
    "requested_amount": "315237.55",
    "wire_in_deadline": "2024-09-24T18:00:00Z"
}

After submission, the wire in request is internally reviewed. If approved, the payroll is processed on time and automatically updated to paid to complete the process. You can call the Get a Single Wire In Request endpoint anytime to check the status of the request.

When a company submits a payroll with submission blockers and selects the wire_in option, a wire_in.confirm_wire_in_transfer partner notification event will be generated. When the payment date to fund a payroll through a wire in has passed, a wire_in.deadline_passed_payroll partner notification event will be generated.