Skip to content

Instantly share code, notes, and snippets.

@azagniotov
Last active July 15, 2026 16:51
Show Gist options
  • Select an option

  • Save azagniotov/210c31540712c10206484d5297616842 to your computer and use it in GitHub Desktop.

Select an option

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();
@TechplexEngineer

Copy link
Copy Markdown

This works great as a tampermonkey user script, downloads all paystubs:
https://github.com/TechplexEngineer/userscript_download_all_payslips/tree/main

@bennypowers

bennypowers commented Jul 1, 2026

Copy link
Copy Markdown

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