Calculating Payroll Taxes
Part 3 of 3
We've found the taxes that we need to set up, but we'll need to make sure we have a few final pieces of information to calculate Olivia's payroll taxes:
- How often does Olivia's employer run payroll? For our example, let's assume her employer runs payroll every two weeks, which means they have 26 pay periods in a year.
- What's the payroll date? As stated in the previous section, Olivia's company is running payroll on January 13, 2023. We don't want to run payroll using a different date from the one we used to retrieve the taxes!
- How much is Olivia earning this payroll? Let's say that Olivia earns $65,000 per year. Given that there's 26 pay periods per year, she'll have gross wages of $2,500 ($65,000 / 26) for each pay period.
- What's Olivia's employee ID? Let's give Olivia the easy-to-remember employee ID of 12345.
With all of this information on hand, we can now make a request ("PayCalcRequest"
) to the the payCalc endpoint:
https://ste-staging.symmetry.com/ste-hosted/v1/payCalc
Sample PayCalcRequest
The following request will compute all of the federal and Arizona taxes listed above:
{
"PayCalcRequest": {
"payCalc": [
{
"employeeID": "12345",
"payrollRunParameters": {
"payDate": "2023-01-13",
"payPeriodsPerYear": 26,
"payPeriodNumber": 1
},
"wages": [
{
"locationCode": "00-000-0000",
"wageType": "Regular",
"calcMethodRegularWages": "Annualized",
"calcMethodSupplementalWages": "None",
"hours": 80,
"grossWages": 2500,
"mtdWages": 0,
"qtdWages": 0,
"ytdWages": 0
},
{
"locationCode": "04-013-11029",
"wageType": "Regular",
"calcMethodRegularWages": "Annualized",
"calcMethodSupplementalWages": "None",
"hours": 80,
"grossWages": 2500,
"mtdWages": 0,
"qtdWages": 0,
"ytdWages": 0
}
],
"taxJurisdictionParms": [
{
"uniqueTaxID": "00-000-0000-FIT-000",
"locationCode": "00-000-0000",
"isExempt": false,
"isResident": true,
"mtdWH": 0.0,
"qtdWH": 0.0,
"ytdWH": 0.0,
"miscParameters": [
{
"parmName": "2020_W4",
"parmValue": "TRUE"
},
{
"parmName": "FILINGSTATUS",
"parmValue": "S"
},
{
"parmName": "TWO_JOBS",
"parmValue": "FALSE"
},
{
"parmName": "DEPENDENTS_AMT",
"parmValue": "0.0"
},
{
"parmName": "DEDUCTIONS",
"parmValue": "0.0"
},
{
"parmName": "OTHER_INCOME",
"parmValue": "0.0"
}
]
},
{
"uniqueTaxID": "00-000-0000-FICA-000",
"locationCode": "00-000-0000",
"isExempt": false,
"isResident": true,
"mtdWH": 0.0,
"qtdWH": 0.0,
"ytdWH": 0.0
},
{
"uniqueTaxID": "00-000-0000-MEDI-000",
"locationCode": "00-000-0000",
"isExempt": false,
"isResident": true,
"mtdWH": 0.0,
"qtdWH": 0.0,
"ytdWH": 0.0
},
{
"uniqueTaxID": "00-000-0000-MEDI2-000",
"locationCode": "00-000-0000",
"isExempt": false,
"isResident": true,
"mtdWH": 0.0,
"qtdWH": 0.0,
"ytdWH": 0.0
},
{
"uniqueTaxID": "04-000-0000-SIT-000",
"locationCode": "04-013-11029",
"isExempt": false,
"isResident": true,
"mtdWH": 0.0,
"qtdWH": 0.0,
"ytdWH": 0.0,
"miscParameters": [
{
"parmName": "PERCENTSTATE",
"parmValue": "2.5"
}
]
}
]
}
]
}
}
PayCalcRequest breakdown
Let's go over what we set for the various parts of that request.
"employeeID"
"employeeID"
The calculation results will be returned with the same ID that you entered. If you're running multiple payroll calculations in a single request, then this will allow you to easily track which calculation results belong to which employee.
As stated above, Olivia has an employee ID of "12345"
.
"payrollRunParameters"
"payrollRunParameters"
This object is used to enter information related to the timing of the employer's payroll schedule. It contains the following three properties:
"payDate"
: The actual date of the payroll in YYYY-MM-DD format. We've use the same date as in the previous section —"2023-01-13"
."payPeriodsPerYear"
: The number of payroll periods in the year. Since Olivia's company runs payroll biweekly, we've entered26
."payPeriodNumber"
: Out of those 26 pay periods, which number is the current one? In our example, we've entered1
because this is the first pay period of the year.
"wages"
"wages"
The "wages" array contains one or more objects, each representing gross wages earned by the employee. Generally, you will set up one wage object for each location where wages were earned (with only the gross wages earned in that location) and one wage object for federal regular wages (with the combined total wages earned).
Since Olivia is only earning wages at one location in Arizona, we will have one "Arizona regular wages" object of $2,500 and one "federal regular wages" object of $2,500.
Each object in "wages" has the following properties:
"locationCode"
: The location code representing where wages were earned. Here we've entered the unique federal location code of"00-000-0000"
for the federal wages and"04-000-0001"
for the Arizona wages."wageType"
: The STE supports many different wage types, but for this initial example, we're only concerned with regular wages ("Regular"
). If you're a currently licensed STE client, please see Wage Types in the STE in our Client Support Center for additional details on other types of wages."calcMethodRegularWages"
,"calcMethodSupplementalWages"
: These properties tell the engine how you want the taxes calculated for the regular and supplemental wages earned in that location. For most regular payroll without any bonuses, this will be"Annualized"
for regular wages and"None"
for supplemental wages. If you're a currently licensed STE client, please see Calculation Methods in our Client Support Center for additional info on the possible calculation methods in the STE."hours"
: The number of hours worked by the employee for the current pay period. Since Olivia works 40 hours per week and this payroll period covers a two-week timespan, we've entered80
for each wage object."grossWages"
: The gross wages earned by the employee for the current pay period. Olivia is earning $2,500 this pay period, so we've entered2500
."mtdWages"
,"qtdWages"
,"ytdWages"
: These represent the month-to-date, quarter-to-date, and year-to-date gross wages earned by the employee. Since this is our first payroll of the year (and because this is Olivia's first paycheck), we've entered0
for all three of these.
As a reminder, the STE is stateless and does not store any information! You will need to track and calculate the employee's month-to-date, quarter-to-date, and year-to-date gross wages within your system.
"taxJurisdictionParms"
"taxJurisdictionParms"
The "taxJurisdictionParms"
array contains one or more objects, each representing one tax to be calculated for this pay period for this employee.
"uniqueTaxID"
: The ID for the tax that you want to calculate."locationCode"
: The location code to be used for this tax. Usually this will match the location code where wages are earned. For this payroll, we've used a location code of"00-000-0000"
for all federal taxes and"04-013-11029"
(Olivia's work location code) for all Arizona taxes."isExempt"
: If you set this to true, the tax will be treated as exempt for this calculation and will return $0 tax withheld. We want all of these taxes to be withheld, so we've set this to false for all taxes in the request."isResident"
: When calculating this tax, should the employee be considered a resident or not? Since Olivia lives in the U.S., we've set the residency status for all federal taxes to true. Since she lives in Arizona, we've also set residency to true for all Arizona taxes.- Generally, this will match the
"isResident"
value returned with the tax in the response from the setTaxList endpoint (that we called in the previous section of this guide).
- Generally, this will match the
"mtdWH"
,"qtdWH"
,"ytdWH"
: The month-to-date, quarter-to-date, and year-to-date amounts withheld for this tax for this employee. Since this is our first payroll of the year (and Olivia's first paycheck), we've entered0
for all three of these properties for every tax in the request."roundResult"
: Whether to round the tax to the nearest dollar ("Yes"
), not round the tax ("No"
), or to let the STE determine whether the tax should be rounded or not ("Default"
). Recommended to set to"Default"
— the STE internally tracks which taxes should be rounded."miscParameters"
: This array is where we set all of the miscellaneous parameter values that we determined earlier. Each object in this array has the following two properties:"parmName"
: The name of the parameter — this corresponds to the"parameterName"
property returned in our earlier response from the setTaxList endpoint"parmValue"
: The value that of the miscellaneous parameter. Note that all values are passed in as strings (for example,"2.5"
,"true"
, etc.). When calculating, the STE translates the values into other data types to determine if they've been set correctly.
Sample PayCalcResponse
Once we send this request, we'll get a response that looks like this:
{
"PayCalcResponse": {
"payCalc": [
{
"employeeID": "12345",
"taxCalculation": [
{
"locationCode": "00-000-0000",
"uniqueTaxID": "00-000-0000-FICA-000",
"isResident": true,
"wageType": "Combined",
"description": "FICA",
"taxAmount": 155.0,
"grossWages": 2500.0,
"subjectWages": 2500.0,
"grossSubjectWages": 2500.0,
"isUnemploymentTax": false,
"rate": 0.0,
"wageBase": 0.0,
"subjectWagesCTD": 0.0,
"excessWagesCTD": 0.0,
"subjectWagesQTD": 0.0,
"excessWagesQTD": 0.0,
"subjectWagesYTD": 0.0,
"excessWagesYTD": 0.0
},
{
"locationCode": "00-000-0000",
"uniqueTaxID": "00-000-0000-FIT-000",
"isResident": true,
"wageType": "Regular",
"description": "Federal Income Tax",
"taxAmount": 252.33,
"grossWages": 2500.0,
"subjectWages": 2500.0,
"grossSubjectWages": 2500.0,
"isUnemploymentTax": false,
"rate": 0.0,
"wageBase": 0.0,
"subjectWagesCTD": 0.0,
"excessWagesCTD": 0.0,
"subjectWagesQTD": 0.0,
"excessWagesQTD": 0.0,
"subjectWagesYTD": 0.0,
"excessWagesYTD": 0.0
},
{
"locationCode": "00-000-0000",
"uniqueTaxID": "00-000-0000-MEDI-000",
"isResident": true,
"wageType": "Combined",
"description": "Medicare",
"taxAmount": 36.25,
"grossWages": 2500.0,
"subjectWages": 2500.0,
"grossSubjectWages": 2500.0,
"isUnemploymentTax": false,
"rate": 0.0,
"wageBase": 0.0,
"subjectWagesCTD": 0.0,
"excessWagesCTD": 0.0,
"subjectWagesQTD": 0.0,
"excessWagesQTD": 0.0,
"subjectWagesYTD": 0.0,
"excessWagesYTD": 0.0
},
{
"locationCode": "00-000-0000",
"uniqueTaxID": "00-000-0000-MEDI2-000",
"isResident": true,
"wageType": "Combined",
"description": "Additional Medicare",
"taxAmount": 0.0,
"grossWages": 2500.0,
"subjectWages": 0.0,
"grossSubjectWages": 2500.0,
"isUnemploymentTax": false,
"rate": 0.0,
"wageBase": 0.0,
"subjectWagesCTD": 0.0,
"excessWagesCTD": 0.0,
"subjectWagesQTD": 0.0,
"excessWagesQTD": 0.0,
"subjectWagesYTD": 0.0,
"excessWagesYTD": 0.0
},
{
"locationCode": "04-000-0001",
"uniqueTaxID": "04-000-0000-SIT-000",
"isResident": true,
"wageType": "Regular",
"description": "Arizona State Tax",
"taxAmount": 62.5,
"grossWages": 2500.0,
"subjectWages": 2500.0,
"grossSubjectWages": 2500.0,
"isUnemploymentTax": false,
"rate": 0.0,
"wageBase": 0.0,
"subjectWagesCTD": 0.0,
"excessWagesCTD": 0.0,
"subjectWagesQTD": 0.0,
"excessWagesQTD": 0.0,
"subjectWagesYTD": 0.0,
"excessWagesYTD": 0.0
}
],
"errorStatus": {
"errorCode": 0,
"errorMessage": "No Error"
}
}
],
"transactionStamp": {
"calcDateTime": "2023-04-03T02:19:44Z",
"steVersion": "2023-R4",
"schemaVersion": "v1",
"totalTransactions": 1,
"failedTransactions": 0,
"transactionType": "PayCalc"
},
"errorStatus": {
"errorCode": 0,
"errorMessage": "No error"
}
}
}
PayCalcResponse breakdown
Each object within the "payCalc"
array represents a payroll calculation for each employee. Three properties will be returned for each employee:
"employeeID"
: This will match the"employeeID"
set in the request."taxCalculation"
: The array of taxes calculated for this payroll."errorStatus"
: If there were any errors in the calculation, they will be returned here.
Since we are only running a single payroll request for Olivia, we only have one object returned in the "payCalc"
array.
Within the "taxCalculation"
array, each object represents a separate tax and the withholding amount for that tax. For calculating Olivia's net pay, we'll focus on the following properties for this example:
"uniqueTaxID"
"uniqueTaxID"
The unique ID for the tax.
"locationCode"
"locationCode"
The location code matching the code used when you set up the tax.
"description"
"description"
The "user friendly" name of the tax.
"taxAmount"
"taxAmount"
The tax amount to be withheld.
Calculating employee net pay
Now that you have the tax amounts for each tax, we can compute Olivia's net pay, as well as the amounts that the employer will owe as the result of Olivia's paycheck.
As a reminder, Olivia has $2,500.00 in gross pay. From that, you'll subtract each employee tax in your payroll system:
- 00-000-0000-FIT-000 (Federal Income Tax): $252.33
- 00-000-0000-FICA-000 (FICA/Social Security): $155.00
- 00-000-0000-MEDI-000 (Medicare): $36.25
- 00-000-0000-MEDI2-000 (Additional Medicare): $0.00
- 04-000-0000-SIT-000 (Arizona State Tax): $62.50
This will result in net pay of $1,993.92!
In summary, we've run a full payroll request through the STE and found that Olivia will have a total of $506.08 withheld from her paycheck, for a final net pay of $1,993.92!
Updated over 1 year ago