Skip to content

Instantly share code, notes, and snippets.

@Enucatl
Created April 24, 2026 05:40
Show Gist options
  • Select an option

  • Save Enucatl/9d10ebc5ce736d840d92e6fc39bb046d to your computer and use it in GitHub Desktop.

Select an option

Save Enucatl/9d10ebc5ce736d840d92e6fc39bb046d to your computer and use it in GitHub Desktop.
Download coop.ch supercard receipts

Supercard Receipt Downloader

This script downloads all receipt PDFs, bill PDFs, and available warranty PDFs from the last 365 days from your logged-in Supercard account.

Prerequisites

  • You must already be logged in to your Supercard account in Firefox.
  • You should allow multiple downloads for www.supercard.ch if Firefox asks.
  • For the cleanest behavior, configure Firefox to download PDFs instead of opening them in a tab.

Which page to open

After logging in, open this page:

https://www.supercard.ch/it/app-supercard-digitale/i-miei-acquisti.html

This is the "I miei acquisti" page that lists your purchases and receipts.

How to use it

  1. Open Firefox and log in to your Supercard account.

  2. Navigate to: https://www.supercard.ch/it/app-supercard-digitale/i-miei-acquisti.html

  3. Wait until the page is fully loaded.

  4. Press F12 to open Developer Tools.

  5. Open the Console tab.

  6. Open supercard-download-all.js in a text editor.

  7. Copy the entire file contents.

  8. Paste the script into the Firefox Console and press Enter.

  9. When the console prints:

    Loaded. Run supercardDownloadAll() on the logged-in purchases page.

    run:

    supercardDownloadAll()
  10. Let the script run until it prints the final summary.

What the script does

  • Fetches all purchases visible to your account
  • Filters them to the last 365 days
  • Downloads:
    • offline receipts
    • online bills
    • warranty PDFs for offline purchases where available

The filenames are based on:

  • purchase date
  • store name
  • amount
  • document type

Example:

2026-04-23_Zurich_Stauffacher_CHF_16.40_receipt.pdf

Notes

  • The script uses your current logged-in browser session. It does not log in for you.
  • If the session expires, reload the page, log in again, and rerun the script.
  • If Firefox still opens PDFs in tabs, change Firefox PDF handling to save files instead of opening them in the browser.
  • The script only downloads documents from the last 365 days, not older purchases.
(() => {
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const sanitize = (value) =>
String(value ?? "")
.normalize("NFKD")
.replace(/[^\w\s.-]/g, "")
.replace(/\s+/g, "_")
.replace(/_+/g, "_")
.replace(/^_+|_+$/g, "")
.slice(0, 80);
const formatAmount = (amountCents, currency = "CHF") => {
const sign = amountCents < 0 ? "-" : "";
const absolute = Math.abs(Number(amountCents) || 0);
const whole = Math.floor(absolute / 100);
const fractional = String(absolute % 100).padStart(2, "0");
return `${currency}_${sign}${whole}.${fractional}`;
};
const formatDate = (dateString) => {
const date = new Date(dateString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
};
const buildMainDocument = (purchase) => {
if (purchase.online) {
if (!purchase.encTransNumber || !purchase.location?.formatId) {
return null;
}
return {
kind: "bill",
url:
`/bin/coop/kbk/kassenzettelpoc?bc=${encodeURIComponent(purchase.encTransNumber)}` +
`&pdfType=bill&format=${encodeURIComponent(purchase.location.formatId)}`,
};
}
if (!purchase.encBarcode) {
return null;
}
return {
kind: "receipt",
url: `/bin/coop/kbk/kassenzettelpoc?bc=${encodeURIComponent(purchase.encBarcode)}&pdfType=receipt`,
};
};
const buildWarrantyDocument = (purchase) => {
if (!purchase.hasWarranty || purchase.online || !purchase.encBarcode) {
return null;
}
return {
kind: "warranty",
url: `/bin/coop/kbk/kassenzettelpoc?bc=${encodeURIComponent(purchase.encBarcode)}&pdfType=warranty`,
};
};
const buildFilename = (purchase, kind) => {
const date = formatDate(purchase.date);
const store =
sanitize(purchase.location?.name) ||
sanitize(purchase.location?.specificFormatId) ||
sanitize(purchase.location?.formatId) ||
"store";
const amount = formatAmount(purchase.total?.amount, purchase.total?.currency || "CHF");
return `${date}_${store}_${amount}_${kind}.pdf`;
};
async function getAllPurchases() {
const allPurchases = [];
let endtimestamp;
while (true) {
const params = new URLSearchParams({
currentPage: "0",
totalAmountMin: "undefined00",
totalAmountMax: "undefined00",
});
if (endtimestamp) {
params.set("endtimestamp", endtimestamp);
}
const response = await fetch(
`/bin/coop/supercard/digitalReceipt/getPurchases.json?${params.toString()}`,
{ credentials: "include" },
);
if (!response.ok) {
throw new Error(`Purchase list request failed with status ${response.status}`);
}
const data = await response.json();
const purchases = data.purchases || [];
if (purchases.length === 0) {
break;
}
allPurchases.push(...purchases);
if (purchases.length < 20) {
break;
}
endtimestamp = purchases[purchases.length - 1].endtimestamp;
await sleep(300);
}
return allPurchases;
}
async function downloadPdf(url, filename) {
const response = await fetch(url, { credentials: "include" });
if (!response.ok) {
throw new Error(`PDF request failed with status ${response.status}`);
}
const pdfBlob = await response.blob();
const downloadBlob = new Blob([pdfBlob], { type: "application/octet-stream" });
const objectUrl = URL.createObjectURL(downloadBlob);
const anchor = document.createElement("a");
anchor.href = objectUrl;
anchor.download = filename;
anchor.target = "_self";
anchor.rel = "noopener";
document.body.appendChild(anchor);
anchor.click();
anchor.remove();
setTimeout(() => URL.revokeObjectURL(objectUrl), 10000);
}
async function run() {
const purchases = await getAllPurchases();
const cutoff = Date.now() - 365 * 24 * 60 * 60 * 1000;
const purchasesLastYear = purchases.filter((purchase) => new Date(purchase.date).getTime() >= cutoff);
const jobs = [];
for (const purchase of purchasesLastYear) {
const mainDocument = buildMainDocument(purchase);
if (mainDocument) {
jobs.push({
filename: buildFilename(purchase, mainDocument.kind),
url: mainDocument.url,
});
}
const warrantyDocument = buildWarrantyDocument(purchase);
if (warrantyDocument) {
jobs.push({
filename: buildFilename(purchase, warrantyDocument.kind),
url: warrantyDocument.url,
});
}
}
console.log(`Found ${purchases.length} purchases total`);
console.log(`Found ${purchasesLastYear.length} purchases in the last 365 days`);
console.log(`Downloading ${jobs.length} PDFs`);
let successCount = 0;
for (let index = 0; index < jobs.length; index += 1) {
const job = jobs[index];
try {
await downloadPdf(job.url, job.filename);
successCount += 1;
console.log(`Downloaded ${index + 1}/${jobs.length}: ${job.filename}`);
} catch (error) {
console.warn(`Failed ${index + 1}/${jobs.length}: ${job.filename}`, error);
}
await sleep(1200);
}
console.log(`Done. Downloaded ${successCount}/${jobs.length} PDFs.`);
}
window.supercardDownloadAll = run;
console.log("Loaded. Run supercardDownloadAll() on the logged-in purchases page.");
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment