Last active
July 15, 2026 16:51
-
-
Save azagniotov/210c31540712c10206484d5297616842 to your computer and use it in GitHub Desktop.
Downloads all pay-slips from ADP website
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| 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 would appreciate any help here. Thank you
This works great as a tampermonkey user script, downloads all paystubs:
https://github.com/TechplexEngineer/userscript_download_all_payslips/tree/main
if you're on portal.people.adp.com "oneux"
(async () => {
const wrapper = document.querySelector('gmv-pay-wrapper').shadowRoot;
const boxes = Array.from(wrapper.querySelectorAll('sdf-expandable-box'));
let prevSrc = '';
let count = 0;
let skipped = [];
const months = {
january:'01', february:'02', march:'03', april:'04',
may:'05', june:'06', july:'07', august:'08',
september:'09', october:'10', november:'11', december:'12'
};
async function downloadItem(item, filename, attempt) {
item.click();
const iframe = wrapper.querySelector('iframe');
let waited = 0;
while (iframe?.src === prevSrc && waited < 15000) {
await new Promise(r => setTimeout(r, 500));
waited += 500;
}
if (!iframe?.src || iframe.src === prevSrc) return false;
prevSrc = iframe.src;
const resp = await fetch(iframe.src, {credentials: 'include'});
if (!resp.ok) return false;
const blob = await resp.blob();
if (blob.size < 1000) return false;
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
console.log(` → ${filename} (${(blob.size/1024).toFixed(0)}KB) attempt ${attempt}`);
return true;
}
for (const box of boxes) {
const year = box.shadowRoot?.textContent?.match(/(20\d{2})/)?.[1];
if (!year) continue;
const select = box.querySelector('sdf-select-simple');
if (!select) continue;
const items = Array.from(select.shadowRoot.querySelectorAll('sdf-select-item'));
console.log(`${year}: ${items.length} payslips`);
for (const item of items) {
const label = item.textContent.trim();
const match = label.match(/(\d+)\s+(\w+)/);
if (!match) continue;
const mm = months[match[2].toLowerCase()];
if (!mm) continue;
const filename = `${year}-${mm}-01.pdf`;
count++;
console.log(` ${count}: ${label} -> ${filename}`);
let ok = false;
for (let attempt = 1; attempt <= 3 && !ok; attempt++) {
if (attempt > 1) {
console.log(` retrying ${filename} (attempt ${attempt})`);
document.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape'}));
await new Promise(r => setTimeout(r, 2000));
}
ok = await downloadItem(item, filename, attempt);
}
if (!ok) {
console.warn(` ✗ FAILED after 3 attempts: ${filename}`);
skipped.push(filename);
}
document.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape'}));
await new Promise(r => setTimeout(r, 1500));
}
}
console.log(`Done! ${count - skipped.length}/${count} downloaded`);
if (skipped.length) console.log(`Failed: ${skipped.join(', ')}`);
})();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
maybe I'm missing something, but I can't get the JSON file to show up using the above URL.
When I login and then try to use the above URL, the page reloads and shows that's I'm not logged in.
Btw, this is the URL my company is using "https://adpworld.adp.com/