GuidesAPI ReferenceChangelogAPI PolicyGusto Security
Guides

Payroll submission blockers and unblock options

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 result in a submission blocker.

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.

1. Calculate and 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"
        }
    ]
}

2. Submit payroll with selected unblock option

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.

Unblock options

Move to 4-day

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"
        }
    ]
}

Use Check as payment method for employees

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"  
    }  
  ]  
}

Use a wire in request

If the customer chooses to preserve their faster payment speed, you'll need to:

  1. Submit the payroll and include the a wire_in body param
  2. Retrieve the payroll and from the credit_blockers array, obtain the wire_in_request_uuid
  3. Get the wire in request using the wire_in_request_uuid
  4. Call the submit a wire in request endpoint after the customer has submitted the wire transfer through their bank

Unblocking using a wire in

  1. Call PUT companies/{company_id}/payrolls/{payroll_id}/submit passing in submission_blockers with wire_in as the selected option for unblocking:

    {  
      "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.

  2. Retrieve the payroll with GET companies/{company_id}/payrolls/{payroll_id}. The credit_blocker array in the response will contain the wire_in_request_uuid required for the next 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"
            }
        ]
    }
  3. After the company has submitted the wire transfer through their bank: call GET /wire_in_requests/{wire_in_request_uuid} using the wire_in_request_uuid 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"
        }
    ]
  4. Call PUT /wire_in_requests/{wire_in_request_uuid} 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 GET /wire_in_requests/{wire_in_request_uuid}to check the status of the request.

Partner notifications

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.