Skip to content

Instantly share code, notes, and snippets.

@azagniotov
Last active April 16, 2024 22:08
Show Gist options
  • Save azagniotov/210c31540712c10206484d5297616842 to your computer and use it in GitHub Desktop.
Save azagniotov/210c31540712c10206484d5297616842 to your computer and use it in GitHub Desktop.
Downloads all pay-slips from ADP website
/*
This has been tested in Chrome v55.0.2883.95 (64-bit)
1. Log into ADP website using the URL: https://my.adp.com/static/redbox/login.html (Make sure you are NOT in Incognito mode)
2. Open Developer Tools console
3. Run the following code in the console:
*/
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://my.adp.com/v1_0/O/A/payStatements?adjustments=yes&numberoflastpaydates=300');
xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); // CORS policy
xhr.onload = function() {
if (xhr.status === 200) {
var rawData = JSON.parse(xhr.responseText);
for (var index = rawData.payStatements.length - 1; index >= 0; --index) {
var entry = rawData.payStatements[index];
var url = "https://my.adp.com" + entry.statementImageUri.href.substring(3);
var a = document.createElement('a');
var trueIndex = (rawData.payStatements.length - index);
if (trueIndex < 10) {
trueIndex = "00" + trueIndex;
} else if (trueIndex < 100) {
trueIndex = "0" + trueIndex;
}
a.download = "payslip.no." + trueIndex + ".from." + entry.payDate + ".pdf";
a.href = url;
document.body.appendChild(a);
a.click();
delete a;
}
} else {
console.log('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
@cwlls
Copy link

cwlls commented Jan 6, 2022

This worked very nicely, thanks!

@pfoneill
Copy link

Works great after adding the sleep step - thank you!

@rcrocker
Copy link

rcrocker commented Jan 4, 2023

Thanks for this. I found that the Zip version didn't quite work if you had more than one paystub on the same day, so I made a small modification to the callback to append an index to the filename and now that works.

var zip = new JSZip();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://my.adp.com/v1_0/O/A/payStatements?adjustments=yes&numberoflastpaydates=300');
xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); // CORS policy
xhr.onload = async function() {
    if (xhr.status === 200) {
        var rawData = JSON.parse(xhr.responseText);
        var lastPaydate = ""
        var consecutiveEntries = 0
        for (var index = rawData.payStatements.length - 1; index >= 0; --index) {
            var entry = rawData.payStatements[index];
            var date = entry.payDate
            // Handle multiple paystubs on the same day
            var dateSuffix = ""
            if (date === lastPaydate) {
                consecutiveEntries++
                dateSuffix = `-${consecutiveEntries}`
            } else {
                lastPaydate = date
                consecutiveEntries = 0
            }
            var year = entry.payDate.split("-")[0]
            var url = "https://my.adp.com" + entry.statementImageUri.href.substring(3);

            var trueIndex = (rawData.payStatements.length - index);
            if (trueIndex < 10) {
                trueIndex = "00" + trueIndex;
            } else if (trueIndex < 100) {
                trueIndex = "0" + trueIndex;
            }

            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if(this.readyState == 4 && this.status == 200) {
                    zip.folder(year).file(date + dateSuffix + ".pdf", this.response)
                }
            };
            xhttp.open('GET', url, true);
            xhttp.responseType = "blob";
            xhttp.send();
            while (xhttp.readyState != 4) {
                console.log("Waiting for download " + trueIndex + " from " + date);
                await new Promise(r => setTimeout(r, 500));
            }
        }
    } else {
        console.log('Request failed.  Returned status of ' + xhr.status);
    }
};
xhr.send();

@FrankTaylorLieder
Copy link

Hi, I've just used the original script in Chrome and as before it stops after 10 downloads. I added a simple fix to sleep between downloads and it then was able to download all 159 of my payslips without any problems. (Note I also added some logging so I can see progress.)

Here is the updated code:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://my.adp.com/v1_0/O/A/payStatements?adjustments=yes&numberoflastpaydates=300');
xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); // CORS policy
xhr.onload = async function() {
    if (xhr.status === 200) {
        var rawData = JSON.parse(xhr.responseText);
        console.log('Number of items:', rawData.payStatements.length);
        for (var index = rawData.payStatements.length - 1; index >= 0; --index) {
            var entry = rawData.payStatements[index];
            var url = "https://my.adp.com" + entry.statementImageUri.href.substring(3);
            console.log("Downloading:", url);
            var a = document.createElement('a');

            var trueIndex = (rawData.payStatements.length - index);
            if (trueIndex < 10) {
                trueIndex = "00" + trueIndex;
            } else if (trueIndex < 100) {
                trueIndex = "0" + trueIndex;
            }

            a.download = "payslip.no." + trueIndex + ".from." + entry.payDate + ".pdf";
            a.href = url;
            document.body.appendChild(a);
            a.click();
            delete a;

            await new Promise(r => setTimeout(r, 1000));
        }
    } else {
        console.log('Request failed.  Returned status of ' + xhr.status);
    }
};
xhr.send();

@corymayer
Copy link

Updated version for 2024:

You need to get your OID by inspecting web requests, and replace YOUR_OID_HERE. I tried to make it generic by calling this API: https://my.adp.com/myadp_prefix/myadpapi/core/v1/version which returns the OID, but the API has some special CORs protection I couldn't figure out.

function sleep(ms) {
   return new Promise(resolve => setTimeout(resolve, ms));
}

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://my.adp.com/myadp_prefix/payroll/v1/workers/YOUR_OID_HERE/pay-statements?adjustments=yes&numberoflastpaydates=300');
xhr.setRequestHeader("Access-Control-Allow-Origin", "*"); // CORS policy
xhr.onload = async function() {
    if (xhr.status === 200) {
        var rawData = JSON.parse(xhr.responseText);
        var lastPaydate = ""
        var consecutiveEntries = 0
        for (var index = rawData.payStatements.length - 1; index >= 0; --index) {
            var entry = rawData.payStatements[index];
            var date = entry.payDate
            // Handle multiple paystubs on the same day
            var dateSuffix = ""
            if (date === lastPaydate) {
                consecutiveEntries++
                dateSuffix = `-${consecutiveEntries}`
            } else {
                lastPaydate = date
                consecutiveEntries = 0
            }
            var year = entry.payDate.split("-")[0]
            var url = "https://my.adp.com/myadp_prefix" + entry.statementImageUri.href + "?rolecode=employee";

            var a = document.createElement('a');

            var trueIndex = (rawData.payStatements.length - index);
            if (trueIndex < 10) {
                trueIndex = "00" + trueIndex;
            } else if (trueIndex < 100) {
                trueIndex = "0" + trueIndex;
            }

            a.download = "payslip.no." + trueIndex + ".from." + entry.payDate + ".pdf";
            a.href = url;
            document.body.appendChild(a);

            await sleep(500);
            a.click();
            delete a;
        }
    } else {
        console.log('Request failed.  Returned status of ' + xhr.status);
    }
};
xhr.send();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment