Integrating Payroll / EWA

This step-by-step guide will walk you through creating a payroll or EWA (Earned Wage Access) integration with 7shifts through the 7shifts REST API.

📘

MAPPING NOTE

This section requires an understanding of how to map locations, departments, and roles.

Upon completion of this guide, you will have created an integration that can interact with the 7shifts platform as follows:

  • Establish entity mapping between your payroll system & 7shifts
  • Read raw clock in/clock out data from 7shifts

What’s in it for the client?

  • Ability to set up integrated payroll processing flow where data is read automatically from 7shifts and brought into your payroll system.
  • Ensuring unpaid & paid breaks are separated when processing payroll.
  • Ensuring only approved punches are included for processing payroll.

Requirements

  • An API key for a test/sandbox 7shifts account
  • cURL or Postman to make test requests

Restrictions

  • You may only make 10 requests per second per token across all API endpoints.
  • This reading of time punch data from 7shifts must take place as a mass-read action.
    • This should ideally be done between 08:00:00 UTC and 15:00:00 UTC on the day of/the day before payroll gets processed to ensure any recent updates to time punches in 7shifts are being reflected in the payroll data as well.

Functionality Overview

The payroll integration involves reading raw time punch data such as clock in, clock out, break in & break out time, and using that data to calculate the total number of worked hours in your system.
You can then calculate the total worked hours data per employee on your side, multiply it by the employee’s assigned wages, and use the calculated earned wages as input for your payroll processing.

You will be interacting with the following 7shifts API endpoints for building this integration:

This section focuses on:

  • Structure of GET requests to the /time_punches endpoint:
    • Get familiar with the request you need to make to read a list of time punch data.
  • Narrowing the request scope:
    • Understand how you can read time punches by location, by department or by user, how to filter by time range and how to page through responses.
  • Understanding the response:
    • Extract relevant information on time punches and breaks from the response

GET Structure for /time_punches

Time punch data in 7shifts can be read through the /time_punches endpoint, either one punch at a time or by getting punch data in a list.

An example GET request to the /time_punches endpoint to list some time punch data looks as follows:

Request URL

GET https://api.7shifts.com/v1/time_punches

By default, without any additional URL query parameters, this request will return the 20 punches that were created the earliest in the account.

Filtering by Time

Since you will be reading time punch data from 7shifts in the context of a specific pay period, you will want to bind the request scope to a certain timeframe.

You can do this by limiting your request to only retrieve time punches that have a clock in start time that falls within the pay period you are looking for. This can be done with the help of the following URL query parameters:

Parameter

Type

Description

clocked_in[gte]

DateTime

Start time range (always in UTC, format: YYYY-MM-dd hh:mm:ss)

clocked_in[lte]

DateTime

End of time range (always in UTC, format: YYYY-MM-dd hh:mm:ss)

Filtering by Location, Department and/or User

It is also recommended that you retrieve time punches only for a specific location, department or user at a time to make it easier for you to process the response. This can be done with the help of following URL query parameters:

Parameter

Type

Description

location_id

Integer

ID of the location you want to retrieve time punches for.

department_id

Integer

ID of the department you want to retrieve time punches for.

user_id

Integer

ID of the user you want to retrieve time punches for.

All the above query parameters can also be used in combination. Here’s an example request on how to get all time punches for user ID 12345 that were created at location ID 98765 for department ID 24680, on & between Aug 16 2020 and Aug 31 2020 (UTC):

GET https://api.7shifts.com/v1/time_punches?user_id=12345&location_id=98765&department_id=24680&clocked_in[gte]=2020-08-16 00:00:00&clocked_in[lte]=2020-08-31 23:59:59

Retrieve in Location Timezone

While we recommend you retrieve time punches in UTC, if you wanted to retrieve the data in the location’s local timezone as specified in 7shifts, you can do so by using the following URL query parameter:

Parameter

Type

Description

localized

Boolean

Setting this to true will return punch times in the location’s timezone specified in 7shifts.

Paging through responses

Finally, in the response, you may notice that you only see the 20 time punches that match the filter criteria which were created the earliest. This is because our API supports “pagination” by using the offset & limit URL query parameters together to get the remaining results.

These parameters are described below:

Parameter

Type

Description

limit

Integer

Maximum number of objects you want in the response (default = 20, min = 1, max = 20).

offset

integer

Number of objects you want to offset the result by (default = 0).

For example,

If the request finds a total of 57 time punches matching the criteria, you can make the following request to get a list of the first 20 time punches created at the location (results #1-#20):

GET https://api.7shifts.com/v1/time_punches?location_id=98765&clocked_in[gte]=2020-08-16 00:00:00&clocked_in[lte]=2020-08-31 23:59:59&limit=20&offset=0

The following request will return the next 20 time punches (results #21-#40):

GET https://api.7shifts.com/v1/time_punches?location_id=98765&clocked_in[gte]=2020-08-16 00:00:00&clocked_in[lte]=2020-08-31 23:59:59&limit=20&offset=20

Finally, the following request will return the last 17 time punches (results #41-57):

GET https://api.7shifts.com/v1/time_punches?location_id=98765&clocked_in[gte]=2020-08-16 00:00:00&clocked_in[lte]=2020-08-31 23:59:59&limit=20&offset=40

When the number of returned time punch objects in the response is less than the limit, that’s how you can determine for certain that the end of the results list has been reached.

Understanding the response

Now that you know how to make a basic request to read time punch data and how to use certain filters with it, let’s explore the response. We’ll use this example response to understand what fields are important:

Example Response

{
    "status": "success",
    "total": 3,
    "offset": 0,
    "limit": 20,
    "data": [
        {
            "time_punch": {
                "id": 39132120,
                "user_id": 515743,
                "role_id": 157351,
                "location_id": 25691,
                "department_id": 49151,
                "approved": true,
                "clocked_in": "2020-08-28 14:00:00",
                "clocked_out": "2020-08-28 22:00:00",
                ...
            },
            "time_punch_break": [
                {
                    ...,
                    "paid": false,
                    "in": "2020-08-28 18:00:00",
                    "out": "2020-08-28 18:30:00",
                    ...
                },
                {
                    ...,
                    "paid": true,
                    "in": "2020-08-28 20:00:00",
                    "out": "2020-08-28 20:15:00",
                    ...
                }
            ]
        },
        {
            "time_punch": {
                "id": 39154049,
                ...
            },
            "time_punch_break": [
                {
                    "id": 134507940,
                    ...
                }
            ]
        }
    ]
}

A few things to note:

  • Within the response, every object in the data array represents one time punch.
  • Within each object, the time_punch object represents details on the actual punch itself, and every object the time_punch_break array would represent every individual break that was taken during the worked shift.
  • If the time_punch_break array is empty, that means that no breaks were taken.
Using the location_id, department_id, role_id & user_id fields and pairing that up with the respective mappings that were established through the mapping process, you should be able to determine who a certain time punch was for, and what location, department & role they were working for that shift.

Outside of those identifier fields, you will also need to look at these fields:

Parameter

Type

Description

clocked_in

DateTime

Timestamp denoting when the employee clocked in (UTC).

clocked_out

DateTime

Timestamp denoting when the employee clocked out (UTC).

approved

Boolean

Whether the punch was approved in 7shifts or not.

Here are some things to note on each of the above fields:

  • clocked_in & clocked_out
    • Subtracting the clocked_in time from the clocked_out time should give you the amount of time that the user worked (excluding breaks).
  • approved
    • Time punches have the approved field set to true if they were either manually approved by a manager in 7shifts, or were auto-approved since they aligned with the time punch rules, or the punches originated from a POS system that were then brought in through an integration.
    • In most cases, you want to ensure that this field is set to true before accounting it for payroll processing.

Parameter

Type

Description

paid

Boolean

Whether the break was a paid break or not.

in

DateTime

Timestamp denoting when this break started (UTC).

out

DateTime

Timestamp denoting when this break started (UTC).

Here are some things to note on each of the above fields:
  • paid
    • For every individual break, this boolean field determines whether the break is supposed to be a paid break or not.
  • in & out
    • For each break that has the paid field set to false, subtracting the in time from the out time should give you the amount of time that the user went on a break for.
    • Please ensure that breaks with the paid field set to true aren’t being subtracted as paid break time would account for the total hours worked.

Putting all the info from these three sub-sections together, the integration should be able to calculate how many hours an employee worked in total, excluding unpaid breaks, within the time range of the pay period you are looking to process payroll for.

You can then use this information with wage information that you may already have in your system to determine how much an employee has earned for their worked hours, which in turn can be used as an input for your payroll processing product.

Tip

You should provide a setting on the configuration page for this integration which would allow an admin to choose whether they wish to include all breaks, only paid breaks or no breaks at all for payroll processing.

You should also provide an option that allows the admin to choose to process only approved time punches in 7shifts for payroll. Changing this option should directly enable/disable the check for the approved field being set to true.

Different managers have different flows on how they approve time punches in 7shifts, and allowing them a setting to choose would help ensure that your payroll integration fits their flow regardless of how they handle time punch approval in 7shifts.


Did this page help you?