Sandbox
Test Console
Prior to diving in with development work, we recommend familiarizing yourself with Link in our Test Console. The Link Test Console lives in the developer dashboard and will allow you to create Link tokens and launch Pinwheel Link. The Test Console mimics Link token creation and allows you to see how different configurations affect the front-end UI. If you don't have access to the Developer Dashboard, please contact [email protected].
In Sandbox mode, you must use our Sandbox credentials. Live credentials will not work in Sandbox. In order to test with live payroll credentials, you can use our Development Environment.
Sandbox Credentials
In Sandbox mode, you can use the following credentials to test Link:
Field | Value |
---|---|
Company ID | company_good |
Username | user_good * |
[email protected] | |
Password | pass_good |
SSN | 123456789 |
Last 4 of SSN | 1234 |
MFA code | mfa_code |
What street did you grow up on? | pinwheel drive |
*For USPS ONLY: Username value is "12345678"
For providers that support optional multifactor authentication (MFA), use the following credentials to test the MFA flow:
Field | Value |
---|---|
Username | user_mfa |
Email | [email protected] |
To test Direct Deposit Forms use the following credentials:
Field | Value |
---|---|
Username | user_dd_form |
To test jobs with an outcome
of error
, use the following credentials. Additional error cases are covered in the section below.
Field | Value |
---|---|
Username | user_error |
Email | [email protected] |
To test jobs with an outcome
of pending
, use the following credentials:
Field | Value |
---|---|
Username | user_pending |
Email | [email protected] |
In sandbox mode, jobs with a pending
outcome will transition to an error
outcome 60 seconds after the Link flow is completed. If you are subscribed to webhook events in Sandbox mode, you will first get an event with a pending
outcome, followed by an event with an error
outcome.
In Sandbox mode, the errors returned will be specific to the Sandbox mode. The full list of job errors can be viewed here.
*Note that in production mode, jobs may remain pending
until they are resolved for up to 24 hours.
On Demand Updates
On Demand Updates may require user re-authentication before I&E data can be refreshed or a direct deposit switch is performed. The monitoring_status
of an account will indicate whether a user re-authentication is needed or not. For the sandbox experience, we will focus on active
and user_action_required
states.
Getting started
An existing sandbox account initially connected with one of the following usernames is required before performing an On Demand Update. Each username corresponds to a re-authentication flow.
Re-authentication flow to simulate | Sandbox username |
---|---|
MFA required | user_mfa |
Credentials required | user_good |
Credentials and MFA required | user_credentials_and_mfa |
Updating monitoring_status of an Account
The PATCH /v1/sandbox/accounts/{account_id}
sandbox-only endpoint can be used to simulate an account going into the user_action_required
state by forcing an account with monitoring_status = active
to monitoring_status = user_action_required
When the monitoring_status
changes for an account, you will receive an account.monitoring_status.updated webhook event as you would in production. Once an account is in monitoring_status = user_action_required
, re-authentication is required to get the account back to the monitoring_status = active
state.
Simulating On Demand Update Re-authentication
Once the account is in the user_action_required
state, you can launch Link with an On Demand Update and the experience will simulate what users will see when re-authentication is required for the account.
*Note that an account in the active
state will not require re-authentication for On Demand Updates.
Limitation
Sandbox payroll accounts older than 7 days will default to requiring MFA and not follow the behavior associated with their username.
Earnings Stream
Earnings Stream can be tested in sandbox by leveraging user credentials to trigger specific scenarios.
Getting Started
The first step is to register a webhook with the earnings_stream.payouts.refreshed
webhook event. For an introduction to webhooks, please read this.
Next, use the Developer Test Console to create a Link Token.
end_user_id
must be provided to use Earnings Stream. Read the User Model documentation for details.
Select paystubs
in required_jobs
and provide a User Model end_user_id
.
Create a Link Token, launch the Link Modal and select ADP as the payroll provider.
You will provide different User IDs to trigger different endpoint and webhook event scenarios. Use the password pass_good
for all of the scenarios below.
Trigger an available state with:
User ID | Behavior |
---|---|
earnings_stream_payouts_available | This represents a hourly worker with shifts. The endpoint will be populated with valid estimated payout information and processed payout records going back to around one year. A webhook event will be sent with payload.availability set to available for all earnings_accrued subfields. |
earnings_stream_payouts_available_salaried | This represents a salaried worker with no shifts. The endpoint will be populated with valid estimated payout information and processed payout records going back to around January 1st, 2022. A webhook event will be sent with payload.availability set to available for payouts_estimated.earnings_accrued and payouts_processed.earnings_unknown subfields. |
earnings_stream_payouts_available_snp | This represents a new hourly worker with shifts and no paystubs. The endpoint will be populated with valid estimated payout information and processed payout records going back to around January 1st, 2022. A webhook event will be sent with payload.availability set to available for payouts_estimated.earnings_accrued and unavailable for payouts.processed subfields. |
You can trigger different unavailable states, which will have empty responses in the endpoint and the following payload.unavailable_reasons
in the webhook event:
User ID | payload.unavailable_reason |
---|---|
payouts_unavailable_temporary_outage | temporary_outage |
payouts_unavailable_employer_not_supported | employer_not_supported |
payouts_unavailable_waiting_for_work | user_action_waiting_for_work |
payouts_unavailable_new_employee | user_action_new_employee |
payouts_unavailable_undetermined | user_action_undetermined |
Refreshing Data
Once a user is connected, you can refresh their data by triggering an On Demand Update. Once the user is re-authenticated, we will send another earnings_stream.payouts.refreshed
webhook event to let you know how the user's payouts have changed. The refreshed_at
field in the payload will show when we last refreshed the payouts data, while the updated_at
field will show when the payouts last changed.
Verification Reports
Verification Reports can be tested in sandbox by leveraging user credentials to trigger specific scenarios.
Getting Started
The first step is to register a webhook with the verification_reports.refreshed
webhook event. For an introduction to webhooks, please read this.
Next, use the Developer Test Console to create a Link Token.
end_user_id
must be provided to use Verification Reports. Read the User Model documentation for details.
Select income
and employment
in required_jobs
and provide an end_user_id
.
Create a Link Token, launch the Link Modal and select ADP as the payroll provider.
You will provide different User IDs to trigger different endpoint and webhook event scenarios. Use the password pass_good
for all of the scenarios below.
Trigger an available state with:
User ID | Behavior |
---|---|
voe_and_voie_available | Both the Verification of Employment and Verification of Income & Employment reports are available. Both the VOE and VOIE endpoints will return the full set of data including paystubs for VOIE. A webhook event will be sent with voe and voie availability set to available . |
voe_and_voie_available_no_paystubs | This represents a user with identity, employment, and income details but no paystubs. The user could have recently started work with this employer and hasn't received a paystub yet. Both the Verification of Employment and Verification of Income & Employment reports are available. The VOIE report will be missing paystubs data. Both the VOE and VOIE endpoints will return data. A webhook event will be sent with voe and voie availability set to available . |
voe_available_voie_unavailable | This represents a user with identity and employment data but no income or paystubs data. Only the Verification of Employment report is available. The VOE endpoint will return data while the VOIE endpoint will return a 404 error. A webhook event will be sent with voe availability set to available and voie availability set to unavailable . |
voe_and_voie_unavailable | This represents a user with required data missing to generate both reports (at minimum, identity and employment data is required to generate a report). Both the VOE and VOIE endpoints will return a 404 error. A webhook event will be sent with voe and voie availability set to unavailable . |
Additional Error Cases
If you would like to test specific Job Errors, use the credentials below. Errors that are job-specific will have a note called out in the description.
Login errors
Note
A few errors here (marked with
*
) can only be raised within platforms that have native support. We recommend testing withADP
as your platform.
changePasswordRequired
changePasswordRequired
This error indicates that the user must update their password before logging in.
Field | Value |
---|---|
Username | user_change_password_required |
[email protected] | |
Password | pass_good |
accountNotActive
accountNotActive
This error is thrown when a user attempts to login to an inactive account (e.g. if they've been terminated and have lost access).
Field | Value |
---|---|
Username | user_account_not_active |
[email protected] | |
Password | pass_good |
accountLoggedIn
accountLoggedIn
This error is thrown when the platform detects that the user is logged in via another mechanism.
Field | Value |
---|---|
Username | user_account_logged_in |
[email protected] | |
Password | pass_good |
mfaSetupRequired
mfaSetupRequired
This error is thrown when MFA needs to be set up (e.g. on first time login).
Field | Value |
---|---|
Username | user_mfa_setup_required |
[email protected] | |
Password | pass_good |
locationRestricted
locationRestricted
This error is thrown when the platform cannot be accessed at the user's current location (e.g. some employers restrict access to corporate networks, or from specific IPs or locations).
Field | Value |
---|---|
Username | user_location_restricted |
[email protected] | |
Password | pass_good |
invalidCredentials
invalidCredentials
The user has entered invalid credentials. Sandbox will always raise this error when an unknown / invalid username, email or password were used (e.g. if some_password
was used instead of pass_good
).
Field | Value |
---|---|
Username | user_invalid_credentials |
[email protected] | |
Password | pass_good |
emailNotRegistered
emailNotRegistered
This error is thrown when the email address provided by the user has not been registered with the payroll platform. This error can relate to both Username
or Email
being invalid. Unlike the invalidCredentials
error, where a platform could recognize the user but their credentials could be invalid for login, this error represents instances when a user cannot be recognized by the platform at all.
Field | Value |
---|---|
Username | user_email_not_registered |
[email protected] | |
Password | pass_good |
maxFailedAttempts
*
maxFailedAttempts
*This error is thrown when a user reaches the maximum number of login attempts (e.g. when entering MFA code). Prior to seeing this error in Sandbox, you will be prompted to enter an MFA code 3 times (invalidMfaCode
failure will be returned each time).
Field | Value |
---|---|
Username | user_max_failed_attempts |
[email protected] | |
Password | pass_good |
MFA code | mfa_code or any valid string |
challengeAnswerIncorrect
*
challengeAnswerIncorrect
*This error is thrown when the answer provided for the challenge question was invalid (e.g. during an MFA step). Sandbox will raise this error 3 times while prompting you to enter an answer to the security question. Note that after 3 failed attempts (they are all set to fail no matter what), maxFailedAttempts
error is returned.
Field | Value |
---|---|
Username | user_challenge_answer_incorrect |
[email protected] | |
Password | pass_good |
Security question answer | security_answer_good or pinwheel drive |
passwordsNotEqual
*
passwordsNotEqual
*This error is thrown in the password reset flow, when a password and its confirmation do not match. To mimic the behavior we see natively in platforms, changePasswordRequired
error will be raised first, then you will be prompted to reset the password 3 times, each time passwordsNotEqual
error will be raised. Note that after 3 failed attempts (they are all set to fail as long as passwords don't match), maxFailedAttempts
error is returned.
Field | Value |
---|---|
Username | user_passwords_not_equal |
[email protected] | |
Password | pass_good |
Confirm password | any valid string, but cannot match Password |
Direct Deposit Switch errors
Note
A few errors here (marked with
*
) can appear in both Login and Direct Deposit Switch flows. In Sandbox mode, these will be raised during the Direct Deposit Switch job.
systemError
*
systemError
*An unhandled error when a payroll integration behaves in an unexpected manner. We have internal processes to triage and fix these errors such that subsequent users do not trigger them.
Field | Value |
---|---|
Username | user_system_error |
[email protected] | |
Password | pass_good |
accountLocked
*
accountLocked
*This error is thrown when the user's account has been locked. Generally, users will need to reach out to their HR Admin to proceed.
Field | Value |
---|---|
Username | user_account_locked |
[email protected] | |
Password | pass_good |
contactHelpDesk
*
contactHelpDesk
*This error is thrown when the user needs to contact their payroll admin in order to continue.
Field | Value |
---|---|
Username | user_contact_help_desk |
[email protected] | |
Password | pass_good |
directDepositDisabled
directDepositDisabled
This error is thrown when the account does not support any updates to direct deposit settings (e.g. the employer has disabled the ability to update settings within the online portal).
Field | Value |
---|---|
Username | user_direct_deposit_disabled |
[email protected] | |
Password | pass_good |
directDepositAllocationsDisabled
directDepositAllocationsDisabled
This error is thrown when the account does not support the ability to read its allocations settings. Accounts that exhibit this behavior are also unable to support allocations updates.
Field | Value |
---|---|
Username | user_direct_deposit_allocations_disabled |
[email protected] | |
Password | pass_good |
sessionTimeout
*
sessionTimeout
*This error occurs when the session closes after a period of inactivity (e.g. due to lack of user action).
Field | Value |
---|---|
Username | user_session_timeout |
[email protected] | |
Password | pass_good |
platformError
*
platformError
*This error is thrown when there is an issue with the underlying payroll platform. Although our connection is behaving as expected, the platform itself is not working as expected.
Field | Value |
---|---|
Username | user_platform_error |
[email protected] | |
Password | pass_good |
platformUnavailable
*
platformUnavailable
*This error is thrown when the platform is unavailable (e.g. some platforms will go offline during routine maintenance).
Field | Value |
---|---|
Username | user_platform_unavailable |
[email protected] | |
Password | pass_good |
routingNumberRejected
routingNumberRejected
This error is thrown when the routing number provided in the Link token is rejected by the platform's validation logic.
Field | Value |
---|---|
Username | user_routing_number_rejected |
[email protected] | |
Password | pass_good |
invalidExistingSplit
invalidExistingSplit
This error is thrown when the user's account does not support the requested change (e.g. a user attempts to add a fixed amount allocation to an account that has an existing percentage allocation). Validation rules vary from platform to platform.
Field | Value |
---|---|
Username | user_invalid_existing_split |
[email protected] | |
Password | pass_good |
changesTemporarilyDisabled
changesTemporarilyDisabled
This error is thrown when a change is rejected due to existing changes that are still pending on the account (e.g. a direct deposit switch has been submitted and is pending processing).
Field | Value |
---|---|
Username | user_changes_temporarily_disabled |
[email protected] | |
Password | pass_good |
maxAccounts
maxAccounts
This error is thrown when a user has reached the maximum number of permitted direct deposit allocations, such that a new one cannot be added.
Field | Value |
---|---|
Username | user_max_accounts |
[email protected] | |
Password | pass_good |
mfaTimeExceeded
*
mfaTimeExceeded
*This error is thrown when the MFA token expires.
Field | Value |
---|---|
Username | user_mfa_time_exceeded |
[email protected] | |
Password | pass_good |
invalidMfaCode
*
invalidMfaCode
*The MFA code that was entered was invalid.
Field | Value |
---|---|
Username | user_invalid_mfa_code |
[email protected] | |
Password | pass_good |
validationFailed
validationFailed
This is a catch-all error that is thrown to capture account data validation issues.
Field | Value |
---|---|
Username | user_validation_failed |
[email protected] | |
Password | pass_good |
invalidInput
*
invalidInput
*This is a catch-all error that is thrown to capture generic input errors.
Field | Value |
---|---|
Username | user_invalid_input |
[email protected] | |
Password | pass_good |
Income and Employment job errors
dataNotAvailable
dataNotAvailable
This error occurs only for Income and Employment jobs. It occurs when the user's payroll platform does not surface the data requested. The availability of data varies within platform, employer, and employee combinations.
Field | Value |
---|---|
Username | user_data_not_available |
[email protected] | |
Password | pass_good |
dataNotRefreshable
dataNotRefreshable
This error occurs only for Income and Employment jobs. It is raised when the user's payroll platform is able to surface the data requested when the user starts a new link session, but not when the job is run via refresh. The availability of data sometimes requires user action, such as an MFA code input, in order retrieve the requested data.
Field | Value |
---|---|
Username | user_data_not_refreshable |
[email protected] | |
Password | pass_good |
directDepositAllocationsDisabled
directDepositAllocationsDisabled
This error is raised when the account does not support direct deposit switches through the online portal. For this set of credentials, this error will be thrown for the Direct Deposit Allocations job, along with directDepositDisabled
for the Direct Deposit Switch job.
Field | Value |
---|---|
Username | user_direct_deposit_allocations_disabled |
[email protected] | |
Password | pass_good |
Please contact [email protected] for access to our Developer Dashboard.
Updated over 1 year ago