Worker payment returns
When a payroll run is confirmed, Salsa starts the process of transferring the calculated pay amounts from an employer bank account to worker bank accounts. This money movement process encompasses two main ACH transactions:
- Employer Funding (ACH debit) – Withdraws funds from the employer's bank account.
- Payouts (ACH credits) – Pushes funds into the workers' bank accounts.
ACH transactions typically have a lead time for processing. To ensure timely payment to workers, payouts are initiated 2 to 4 business days before the employer funding is fully processed. This helps to reduce the time between initiating the transaction and completing the worker payment.
How it works
Worker payments can fail for various reasons, such as insufficient funds in the employer's account or a blocked bank account. When this happens, Salsa uses the following process to manage the returned payment.
- Salsa automatically puts employer payouts and any associated tax transfers temporarily on hold to ensure that no further transactions are processed until funding issues are resolved.
- Salsa attempts to identify and categorize the root cause of the failure using our payment return codes. After determining the reason for the failed payment, Salsa attempts to rectify the situation and successfully re-debit the employer's account.
- Salsa sends real-time webhook event notifications to the webhook endpoint you registered during the onboarding process. By mapping these notifications to our email templates based on the payment return code, you can automatically send targeted and informative emails to employees and employers throughout the process.
Payment return lifecycles
Option 1: Two day processing
With the two-day payment processing option, an employer can initiate funding two days before the scheduled payday.

Here is a breakdown of the process:
- Payroll Run confirmation. Once a payroll run is confirmed in Salsa, the fund transfer process begins.
- Initiation of Employer Funding. Two days prior to payday, Salsa initiates the
Employer Funding
process to withdraw funds from the employer's designated bank account. - Payout Initiation. The day before payday,
Payouts
are initiated to push the funds into workers bank accounts. - Employer Funding Return. Upon encountering a failed
Employer Funding
transaction, the employer's account is automatically placed in aRESTRICTED
status. This status prevents the employer from initiating any additional payroll runs until the issue is resolved. Simultaneously, theNotification.Payment.employerFundingFailed
event is sent to the webhook endpoint you registered during the onboarding process, providing a real-time notification of the failed funding attempt and all subsequent events. - Re-Debit Attempt. Salsa initiates the process to re-debit the employer's account in an effort to recover the failed funding. Simultaneously, the
Notification.Payment.employerFundingRescheduled
event is sent to your webhook endpoint, indicating that Salsa is attempting a re-debit.- Successful Re-Debit. If the re-debit attempt is successful, the
Notification.Payment.employerFundingCleared
event is sent to your webhook endpoint, indicating that funds were successfully withdrawn from the employer’s account. Subsequently, the employer's account status is restored toACTIVE
, allowing them to resume payroll runs. - Failed Re-Debit Recovery Attempt. If the re-debit attempt fails, Salsa automatically retries the re-debit process up to three times. If all re-debit attempts fail to clear, Salsa considers the recovery to be unsuccessful. At this stage, we recommend promptly initiating efforts to recover the outstanding funds by involving your customer experience team. Depending on the terms of your contract with Salsa, either your organization or the Salsa Customer Success team should reach out to the employer to discuss a repayment plan.
- Successful Re-Debit. If the re-debit attempt is successful, the
Option 2: Four day processing
With the four-day payment processing option, an employer can initiate funding four days before the scheduled payday.

Here is a breakdown of the process:
- Payroll Run confirmation. Once a payroll run is confirmed in Salsa, the process of fund transfer begins.
- Initiation of Employer Funding. Four days prior to payday, Salsa initiates the
Employer Funding
process to withdraw funds from the employer's designated bank account. - Employer Funding Return. Upon encountering a failed
Employer Funding
transaction, the employer's account is automatically placed in aRESTRICTED
status. This status prevents the employer from initiating any additional payroll runs until the issue is resolved. Simultaneously, theNotification.Payment.employerFundingFailed
event is sent to the webhook endpoint you registered during the onboarding process, providing a real-time notification of the failed funding attempt and all subsequent events. - Payout Initiation. The day before payday,
Payouts
are initiated. At this stage, theEmployer Funding
should have settled. Salsa initiates the process to re-debit the employer's account in an effort to recover the failed funding. Subsequently, theNotification.Payment.employerFundingRescheduled
event is sent to your webhook endpoint, indicating that Salsa is attempting a re-debit.
Payment return codes
When payments are returned, use the following return codes to categorize the specific reason for the return. By mapping your webhook endpoint to our email templates corresponding to these codes, your payroll application can dynamically send personalized emails to the employer, addressing the specific reason for the employer funding failure.
Return Code | Description |
---|---|
R01 | Insufficient funds |
R02(*) | Account closed |
R03(*) | No account/unable to locate account |
R04(*) | Invalid account number |
R05(*) | Unauthorized debit to consumer account using corporate SEC code |
R06 | Returned per ODFI's request |
R07(*) | Authorization revoked by customer |
R08 | Payment stopped |
R09(*) | Uncollected funds. Account may have a Pending balance that the issuing bank has not yet paid |
R10(*) | Customer advises unauthorized, improper, ineligible, or part of an incomplete transaction |
R11 | Check truncation early return |
R12(*) | Account sold to another DFI |
R13(*) | Invalid ACH routing number |
R14(*) | Representative payee deceased or unable to continue in that capacity |
R15(*) | Beneficiary or account holder (other than a representative payee) deceased |
R16(*) | Account frozen/entry returned per OFAC instruction |
R17(*) | File record edit criteria |
R18(*) | Improper effective entry date |
R19(*) | Amount field error |
R20(*) | Non-transaction account |
R21(*) | Invalid company identification |
R22(*) | Invalid individual ID number |
R23(*) | Credit entry refused by receiver |
R24 | Duplicate entry |
R25 | Addenda error |
R26 | Mandatory field error |
R27(*) | Trace number error |
R28(*) | Routing number check digit error |
R29(*) | Corporate customer advises not authorized |
R30(*) | RDFI not participant in check truncation program |
R31(*) | Permissible return entry (CCD and CTX only) |
R32(*) | RDFI non-settlement |
R33(*) | Return of XCK entry |
R34(*) | Limited participation DFI |
R35 | Return of improper debit entry |
R36 | Return of improper credit entry |
R37 | Source document presented for payment |
R38 | Stop payment on source document |
R39 | Improper source document/source document presented for payment |
R45 | Invalid individual / company name |
(*) These error codes should not be disclosed to end users as fraudulent users can exploit them to extract valuable information from the funding failure. Handle these sensitive return codes internally and show users a generic error message. More details below.
Why certain return codes aren’t exposed to users
Some ACH return codes (e.g., R13, R20, R28) should not be shown directly to end-users because they reveal specific reasons for failure that could aid fraudsters. Exposing these codes can help attackers:
- Validate Bank Details: Codes like R13 (invalid routing number) or R28 (routing number check digit error clearly indicate an invalid bank routing number. Attackers can use this information to test and find valid routing numbers by trial and error.
- Confirm Account Existence: A code such as R20 (non-transaction account implies the bank account exists but isn’t allowed to transact. This clue can be abused to verify if a guessed account number is real (even if it’s not usable for payments).
- Enable Enumeration Attacks: Hackers may systematically try different routing/account combinations and leverage distinctive error codes as confirmation of valid details. Revealing the exact return code gives them a clear signal on which part of the input was wrong, simplifying their iterative guessing process.
Mitigation
Handle these sensitive return codes internally and show users a generic error message (one that doesn’t specify which detail was incorrect), e.g. “Payroll run funding failed”. This way, you avoid leaking hints about which bank detail was invalid, reducing the risk of fraud or abuse.
Updated 5 days ago