Neu Aliexpress und Amazon Rechnungen runterladen - freies Tampermonkey Script

musaza

Aktives Mitglied
13. Januar 2018
83
15
Ich wollte mal ein kleines ChatGPT-Script mit euch teilen, das ich mir „herausgepromptet“ habe 🙂 War mir blöd, monatlich einer Firma, die diese Dateien automatisiert runterladen könnte, schlappe 30 Euro im Monat zu bezahlen...


Hintergrund​


  • Ich habe kein Amazon Business Konto und konnte deshalb die Kaufrechnungen nicht gebündelt herunterladen – nur einzeln.
  • Bei AliExpress gibt es den Button „Rechnung“ seit April 2025 nicht mehr. Davor konnte man Rechnungen mit MwSt. herunterladen, danach nur noch Eigenbelege (Netto), die man dem Finanzamt vorlegen muss.
    → Mit den hier vorgestellten Scripts bekomme ich jetzt wieder alle Rechnungen, bzw. sogar eine Ordner-Summary als PDF.

Installation​


  • Browser: Firefox
  • Einstellung: PDFs sollen heruntergeladen und nicht im Browser geöffnet werden
  • Add-on: Tampermonkey installieren
  • Dann: im Tampermonkey-Addon auf „Neues Userscript erstellen“ klicken und die Scripts jeweils einfügen.

Bedienung​


  • AliExpress:
    Rechts unten erscheint ein Button „Rechnungen (sichtbar) laden“.
    Alle sichtbaren Rechnungen werden heruntergeladen. Wenn ihr mehr wollt, einfach weiterscrollen, bis alle Bestellungen geladen sind.
  • Amazon:
    Alle Rechnungen der jeweils sichtbaren Seite werden heruntergeladen.
    Für weitere Seiten müsst ihr einfach weiterblättern.
    Wichtig: Die URL muss https://www.amazon.de/your-orders/orders lauten – dann erscheint links unten der Button „Alle Rechnungs-PDF laden“.

Hinweis​


Ich teile hier nur die Idee und wie es bei mir funktioniert hat.


  • Gewährleistung oder Haftung übernehme ich nicht – jeder ist für seine Daten selbst verantwortlich.
  • Die Scripts generieren nichts Eigenes, sie laden nur herunter, was die Plattformen ohnehin bereitstellen.
  • Support kann ich leider nicht bieten – aber: wenn ihr die Scripts erweitert oder verbessert, teilt es gerne hier! Vielleicht baut ja jemand auch etwas für eBay 😉 oder alles andere in gewissen erleichterungen auf diversen Plattformen




Hier der Aliexpress Script:

// ==UserScript==
// @name AliExpress: Rechnungen aller sichtbaren Bestellungen laden
// @namespace ae-invoice-bulk
// @version 1.0
// @description Lädt die Rechnungen (PDF) für alle sichtbaren Bestellungen mit passendem Dateinamen herunter.
// @author you
// @match https://www.aliexpress.com/p/order/index.html*
// @match https://www.aliexpress.com/p/order/index.htm*
// @ICON https://www.aliexpress.com/favicon.ico
// @run-at document-idle
// @grant GM_xmlhttpRequest
// @grant GM_download
// @connect trade.aliexpress.com
// ==/UserScript==

(function () {
'use strict';

/*** UI-Button einfügen ***/
function addButton() {
const btn = document.createElement('button');
btn.textContent = 'Rechnungen (sichtbar) laden';
btn.style.position = 'fixed';
btn.style.right = '16px';
btn.style.bottom = '16px';
btn.style.zIndex = '999999';
btn.style.padding = '10px 14px';
btn.style.borderRadius = '8px';
btn.style.border = 'none';
btn.style.background = '#1677ff';
btn.style.color = '#fff';
btn.style.fontWeight = '600';
btn.style.cursor = 'pointer';
btn.title = 'Lädt die Rechnungen für alle aktuell sichtbaren Bestellungen';

btn.addEventListener('click', run);
document.body.appendChild(btn);
}

/*** Hilfen ***/
const MONTHS_DE = {
jan: 1, januar: 1,
feb: 2, februar: 2,
mär: 3, maerz: 3, märz: 3, mar: 3, march: 3,
apr: 4, april: 4,
mai: 5,
jun: 6, juni: 6,
jul: 7, juli: 7,
aug: 8, august: 8,
sep: 9, sept: 9, september: 9,
okt: 10, oktober: 10,
nov: 11, november: 11,
dez: 12, dezember: 12
};

function pad2(n) { return String(n).padStart(2, '0'); }

function parseGermanDateToYYYYMMDD(txt) {
// erwartet z. B. "24. Aug 2025"
const m = txt.trim().match(/(\d{1,2})\.\s*([A-Za-zäöüÄÖÜ]+)\s*(\d{4})/);
if (!m) return null;
const d = parseInt(m[1], 10);
const monKey = m[2].toLowerCase()
.replace('ä', 'ä') // bleibt
.replace('ö', 'o')
.replace('ü', 'u')
.replace('ß', 'ss')
.replace('mär', 'mär'); // gängigste Abk.
const mon = MONTHS_DE[monKey] || MONTHS_DE[monKey.slice(0,3)];
const y = parseInt(m[3], 10);
if (!mon) return null;
return `${y}${pad2(mon)}${pad2(d)}`;
}

function extractOrderInfo(orderEl) {
// Bestellnummer
const orderIdMatch = orderEl.textContent.match(/Bestellnummer:\s*(\d{6,})/);
const orderId = orderIdMatch ? orderIdMatch[1] : null;

// Kaufdatum
const dateDiv = Array.from(orderEl.querySelectorAll('.order-item-header-right-info div'))
.find(d => /Bestellung aufgegeben am/i.test(d.textContent));
const dateText = dateDiv ? dateDiv.textContent.replace(/.*?:\s*/, '') : '';
const yyyymmdd = parseGermanDateToYYYYMMDD(dateText);

// Gesamtbetrag
let totalText = '';
const totalEl = orderEl.querySelector('[data-pl="order_item_content_price_total"]');
if (totalEl) {
// enthält „Gesamt: 21,39 €“
totalText = totalEl.innerText || totalEl.textContent || '';
} else {
// Fallback: suche irgendein „Gesamt:“ mit € in der Nähe
const hint = Array.from(orderEl.querySelectorAll('span,div'))
.find(n => /Gesamt/i.test(n.textContent) && /€/.test(n.textContent));
totalText = hint ? hint.textContent : '';
}
const amountMatch = totalText.replace(/\s+/g, ' ').match(/([\d.,]+)\s*€/);
let amountStr = amountMatch ? amountMatch[1] : '';
// Normalisieren -> Zahl und danach wieder nach DE-Format
if (amountStr) {
const val = parseFloat(amountStr.replace(/\./g, '').replace(',', '.'));
if (!isNaN(val)) amountStr = val.toFixed(2).replace('.', ',');
}

return { orderId, yyyymmdd, amountStr };
}

function fetchInvoiceId(orderId) {
const url = `https://trade.aliexpress.com/ajax/invoice/queryInvoiceIdAjax.htm?orderIds=${orderId}`;
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
url,
onload: (res) => {
try {
const data = JSON.parse(res.responseText);
// Antwort ist i. d. R. ["908704618996"] oder []
resolve(Array.isArray(data) && data[0] ? String(data[0]) : null);
} catch (e) {
reject(e);
}
},
onerror: reject,
ontimeout: reject
});
});
}

function downloadInvoicePdf(invoiceId, orderId, filename) {
const url = `https://trade.aliexpress.com/ajax/invoice/invoiceExportAjax.htm?invoiceId=${encodeURIComponent(invoiceId)}&orderId=${encodeURIComponent(orderId)}`;
// Wir holen die PDF als Blob und übergeben sie dann an GM_download, damit Dateiname sicher gesetzt wird.
GM_xmlhttpRequest({
method: 'GET',
url,
responseType: 'blob',
onload: (res) => {
try {
const blob = res.response;
const objectUrl = URL.createObjectURL(blob);
GM_download({
url: objectUrl,
name: filename,
saveAs: false,
ontimeout: () => console.warn('Download timeout:', filename),
onerror: (e) => console.warn('Download error:', filename, e),
onload: () => {
// Object URL freigeben, wenn der Download gestartet wurde
setTimeout(() => URL.revokeObjectURL(objectUrl), 10000);
}
});
} catch (e) {
console.error('PDF-Verarbeitung fehlgeschlagen', e);
}
},
onerror: (e) => console.error('PDF-Request fehlgeschlagen', e),
ontimeout: (e) => console.error('PDF-Request Timeout', e)
});
}

async function run() {
const items = Array.from(document.querySelectorAll('.order-item'));
if (!items.length) {
alert('Keine sichtbaren Bestellungen gefunden.');
return;
}

let ok = 0, skipped = 0;
for (const el of items) {
const { orderId, yyyymmdd, amountStr } = extractOrderInfo(el);

if (!orderId) { console.warn('Order ohne Bestellnummer übersprungen.'); skipped++; continue; }
const datePart = yyyymmdd || '00000000';
const amountPart = amountStr || '0,00';

try {
const invoiceId = await fetchInvoiceId(orderId);
if (!invoiceId) {
console.warn(`Keine invoiceId für Order ${orderId} (evtl. keine Rechnung vorhanden).`);
skipped++;
continue;
}
const filename = `${datePart}_${orderId}__EUR_${amountPart}.pdf`;
console. log('Lade Rechnung:', filename, ' invoiceId:', invoiceId);
downloadInvoicePdf(invoiceId, orderId, filename);
ok++;
} catch (e) {
console.error('Fehler bei Order', orderId, e);
skipped++;
}
}
setTimeout(() => {
alert(`Fertig: ${ok} Rechnung(en) angestoßen. Übersprungen: ${skipped}.`);
}, 100);
}

/*** Start ***/
addButton();
})();
















und hier der Amazon Script:


// ==UserScript==
// @name Amazon DE – Alle Rechnungs-PDFs laden
// @namespace ama-pdf-bulk
// @version 1.0
// @description Lädt auf /your-orders/orders alle Rechnungs-/Korrektur-PDFs je Bestellung herunter – inkl. mehrfach vorhandener PDFs – und benennt sie nach Wunschschema.
// @author you
// @match https://www.amazon.de/your-orders/orders*
// @grant GM_download
// @grant GM_xmlhttpRequest
// @connect www.amazon.de
// ==/UserScript==

(function () {
'use strict';

// ---------- kleine Hilfen ----------
const $ = (sel, el = document) => el.querySelector(sel);
const $$ = (sel, el = document) => Array.from(el.querySelectorAll(sel));

const MONTHS_DE = {
'januar': 1, 'februar': 2, 'märz': 3, 'maerz': 3, 'april': 4,
'mai': 5, 'juni': 6, 'juli': 7, 'august': 8, 'september': 9,
'oktober': 10, 'november': 11, 'dezember': 12
};

const sanitizeForFilename = (s) =>
s.trim()
.replace(/\s+/g, '-') // Leerzeichen → Bindestrich
.replace(/[\u2013\u2014]/g, '-') // Gedankenstriche normalisieren
.replace(/[^A-Za-z0-9ÄÖÜäöüß\-]/g, ''); // ungültige Zeichen raus, Umlaute ok

function parseGermanOrderDateToYYYYMMDD(s) {
// Beispiele: "24. August 2025", "7. August 2025"
if (!s) return '00000000';
const m = s.trim()
.toLowerCase()
.replace(/\./g, '')
.replace('märz', 'maerz')
.match(/^(\d{1,2})\s+([a-zäöü]+)\s+(\d{4})$/i);
if (!m) return '00000000';
const dd = String(m[1]).padStart(2, '0');
const mon = MONTHS_DE[m[2]] || 0;
const mm = String(mon).padStart(2, '0');
const yyyy = m[3];
return `${yyyy}${mm}${dd}`;
}

function extractTextAfterLabel(container, labelText) {
// Sucht im "order-header" das Listenelement, dessen Mini-Label gleich labelText ist,
// und gibt den Wert im nachfolgenden .a-size-base zurück.
const items = $$('.order-header__header-list-item', container);
for (const li of items) {
const label = $('.a-size-mini .a-color-secondary', li);
const value = $('.a-size-base', li);
if (label && value && label.textContent.trim().toLowerCase() === labelText.toLowerCase()) {
return value.textContent.trim();
}
}
return '';
}

function absolute(url) {
try { return new URL(url, location.origin).href; } catch { return url; }
}

function gmGet(url) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
url,
headers: { 'Accept': 'text/html,application/xhtml+xml' },
// Cookies mitnehmen (wichtig, weil die Popover-URL auth-gebunden ist)
anonymous: false,
// manche TM-Versionen nutzen withCredentials:
// @ts-ignore
withCredentials: true,
onload: (res) => resolve(res.responseText),
onerror: (e) => reject(e)
});
});
}

async function downloadAllForOrder(orderCard) {
try {
// Header-Infos ermitteln
const header = $('.order-header', orderCard) || orderCard;
const orderDateHuman = extractTextAfterLabel(header, 'Bestellung aufgegeben');
const orderDate = parseGermanOrderDateToYYYYMMDD(orderDateHuman);
const sumRaw = extractTextAfterLabel(header, 'Summe')
.replace(/[€\s\u00A0]/g, '') // Euro-Symbol & NBSP entfernen
.replace(/EUR/i, '')
.trim();
const sumForFile = sumRaw.replace(/[^\d,]/g, ''); // "58,42" behalten
const orderId = $('.yohtmlc-order-id span[dir="ltr"]', header)?.textContent.trim() || 'UNKNOWN';

// Link zum Popover (enthält alle Rechnungs-/Korrektur-Links als HTML)
const invoiceTrigger = $$('a.a-link-normal', header)
.find(a => /\/invoice\/invoice\.html/i.test(a.getAttribute('href') || '') ||
/\/shared-cs\/ajax\/invoice\/invoice\.html/i.test(a.getAttribute('href') || '') ||
a.textContent.trim().toLowerCase().startsWith('rechnung'));

if (!invoiceTrigger) {
console.warn('Keine Rechnungslinks für Bestellung gefunden:', orderId);
return;
}

// Popover-HTML abrufen
const popoverUrl = absolute(invoiceTrigger.getAttribute('href'));
const html = await gmGet(popoverUrl);

// HTML parsen und alle PDF-Links herausfischen
const dp = new DOMParser();
const doc = dp.parseFromString(html, 'text/html');

// robuste Suche: alle <a>, deren href .pdf enthält
const links = $$('a', doc).filter(a => {
const href = a.getAttribute('href') || '';
return /\.pdf(\?|$)/i.test(href);
});

if (!links.length) {
console.warn('Kein PDF-Link im Popover gefunden:', orderId, popoverUrl);
return;
}

for (let idx = 0; idx < links.length; idx++) {
const a = links[idx];
const href = absolute(a.getAttribute('href'));
let linkText = a.textContent.trim() || `Rechnung-${idx + 1}`;
// Einheitlich: Leerzeichen -> -, Sonderzeichen raus
linkText = sanitizeForFilename(linkText);

const filename = `${orderDate}_${linkText}_${orderId}__EUR_${sumForFile}.PDF`;

// Download starten
await new Promise((resolve) => {
GM_download({
url: href,
name: filename,
saveAs: false,
ontimeout: resolve,
onerror: resolve,
ontimeout: resolve,
onprogress: () => {},
onload: resolve
});
});

// kleine Pause, um Rate Limits zu vermeiden
await new Promise(r => setTimeout(r, 400));
}
} catch (e) {
console.error('Fehler bei Bestellung:', e);
}
}

// ---------- Button in die Seite einfügen ----------
function addUi() {
if ($('#tm-load-all-invoices')) return;
const btn = document.createElement('button');
btn.id = 'tm-load-all-invoices';
btn.textContent = 'Alle Rechnungs-PDFs laden';
Object.assign(btn.style, {
position: 'fixed',
bottom: '16px',
left: '16px',
zIndex: 99999,
background: '#ffd814',
color: '#111',
border: '1px solid #888',
borderRadius: '8px',
padding: '10px 14px',
cursor: 'pointer',
fontSize: '14px',
fontWeight: 'bold',
boxShadow: '0 2px 6px rgba(0,0,0,.2)'
});
btn.addEventListener('click', async () => {
btn.disabled = true;
btn.textContent = 'Lade PDFs…';
const cards = $$('.order-card');
for (const card of cards) {
await downloadAllForOrder(card);
}
btn.textContent = 'Fertig ✓';
setTimeout(() => { btn.disabled = false; btn.textContent = 'Alle Rechnungs-PDFs laden'; }, 3000);
});
document.body.appendChild(btn);
}

// ---------- Start ----------
const obs = new MutationObserver(() => addUi());
obs.observe(document.documentElement, { childList: true, subtree: true });
addUi();
})();
 
  • Gefällt mir
Reaktionen: sah
Ähnliche Themen
Titel Forum Antworten Datum
Neu JTL-Connector + Shopware 6: Zweite Lizenz führt zu „Invalid credentials“ und blockiert bestehenden Shop Shopware-Connector 0
Neu Referenznummer Grösse auf den Versand Etiketten von DPD-Cloudservice und GLS Api JTL-ShippingLabels - Ideen, Lob und Kritik 0
Kundengutschrift - Button: "Speichern und Bestand buchen" fehlt. JTL-Wawi 1.11 0
Neu JTL-WAWI und LS-POS Wechseln Starten mit JTL: Projektabwicklung & Migration 1
Neu Paket x/y auf Versandetikett bzw. Lieferscheinnummer und Paketanzahl fehlt Druck-/ E-Mail-/ Exportvorlagen in JTL-Wawi 0
Neu Lieferzeiten Angabe bei "wenn ausverkauft" und schon in Beschaffung ist Allgemeine Fragen zu JTL-Shop 0
Neu Serverwechsel und kurzzeitig zwei Shop-URLs Installation von JTL-Wawi 2
Artikel Z besteht aus den Positionen A, B und C mit unterschiedlichen Steuersätzen. Wie im Angebot, Auftrag, Rechnung richtig dargestellen ? JTL-Wawi 1.11 4
Neu Grundpreisanzeige von Liter, Meter und Stück JTL-Shop - Fehler und Bugs 5
Neu Marktplatz anbindung und Analyse User helfen Usern 0
Neu Shopware Connector sendet keine Zahlungs und Versandinfos von WAWI zu SW6 Shopware-Connector 5
Neu Seriennummer und Beschreibung 1 in XML Lieferschein ausgeben Druck-/ E-Mail-/ Exportvorlagen in JTL-Wawi 0
Neu Smarty für "im Zulauf" und "auf Einkaufsliste"? Allgemeine Fragen zu JTL-Shop 7
Neu askJan | Neuer KI-Assistent für JTL-Wawi - schnelle, effiziente und transparente KI-Datenanalyse - ohne SQL! Dienstleistung, Jobs und Ähnliches 22
Neu FBA Bestände schwanken in JTL und sind dann über Stunden falsch Amazon-Anbindung - Fehler und Bugs 2
Neu JTL REST API einen Workflow ausführen und benutzerspezifischen Drucker ansteuern User helfen Usern 0
Übergehe Datensatz, da weder Nachname noch Firmenname und Stasse, Plz, und Ort des Kunden gesetzt sind! JTL-Wawi 1.9 0
Neu Verkauf je Plattform und 2 Ladenlokalen Eigene Übersichten in der JTL-Wawi 0
Rechnungskorrekturen zuordnen und Status anpassen JTL-Wawi 1.9 1
Neu Sitemap per cronjob und nicht mit Wawi Abgleich Allgemeine Fragen zu JTL-Shop 3
Kleinunternehmer - Einstellungen und Angaben Einrichtung JTL-Shop5 1
Neu JTL-Wawi 1.11.5: Sequenzieller Kundenexport mit Workflow und SQL-Queue Schnittstellen Import / Export 2
Steuer Einstellung bei Sonderpreis und nach OSS Landauswahl JTL-Wawi 1.10 0
Neu Rechnungen werden und können nicht mehr vom Rechner im Lager gedruckt werden JTL-Wawi - Fehler und Bugs 4
Erfahrungen zur JTL Wawi 1.11.5 – Tipps, Bugs und Praxisberichte JTL-Wawi 1.11 19
Neu JTL SHOP 5.6 und Konfigurationsartikel Allgemeine Fragen zu JTL-Shop 0
Neu POS doppelte Artikel und Kategorien nach Update Einrichtung / Updates von JTL-POS 3
Neu Artikelname und Preis zentrieren Allgemeine Fragen zu JTL-Shop 8
Neu Downloadmodul – Keine Reiter "Downloads" und keine Download nach Bestellung möglich Technische Fragen zu Plugins und Templates 6
Neu Eine Amazon-Abrechnung wurde mit Verspätung generiert und fehlt jetzt in WAWI Amazon-Anbindung - Fehler und Bugs 3
Neu Wo kann ich mich über JTL Kundencenter beschweren? 20 Minuten Lang einen Bug im Ticket dokumentiert, und am Ende "ein Fehler ist aufgetreten" Smalltalk 3
Neu Interne Links in den Dropdowns "Sortierung" und "Artikel pro Seite" auf follow setzen Betrieb / Pflege von JTL-Shop 1
Neu Ist ein Hin- und Rückversand so machbar? User helfen Usern - Fragen zu JTL-Wawi 3
Neu 2x 19% Steuern ausweisen möglich? (MwSt und Versicherungssteuer) Druck-/ E-Mail-/ Exportvorlagen in JTL-Wawi 1
Monatsabschluss Amazon FBA UK / CH mit JTL2Datev WaWi 1.10 bei IDU Nutzung und Zwangs VCS für GB / Schweiz JTL-Wawi 1.10 0
Neu Shopabgleich und McAfee Virenschutz = Problem? User helfen Usern - Fragen zu JTL-Wawi 2
Kein E-Mail-Versand von Versandbestätigung und Zahlungsbestätigung JTL-Wawi 1.10 0
Auftrag hängt in Pickliste fest und lässt sich nicht ausliefern! Tipps und Tricks - hilfreiche Videoanleitungen 2
Neu Paypal Checkout nimmt neue CLIENT ID und SECRET nicht wahr User helfen Usern - Fragen zu JTL-Wawi 1
Neu Sind Support-Tickets für WaWi und Ameise ohne kostenpflichtigen Tarif nicht mehr möglich? JTL-Wawi - Fehler und Bugs 3
Vorlagen und eigene Felder JTL-Wawi 1.10 3
JTL AGBs und Gewährleistungsrechte / Schadensersatz JTL-Wawi 1.11 1
Neu Frage zum Thema Skonto bei Bezahlungsarten Barzahlung und QR-Code Betrieb / Pflege von JTL-Shop 0
Neu SUCHE Freelancer für JTL WAWI Anbindung an WooCommerce und Einrichtung Dienstleistung, Jobs und Ähnliches 2
Neu Rechnungsvorlage Tarik und Herkunftsland User helfen Usern - Fragen zu JTL-Wawi 4
Neu Rechnung als pdf. speichern mit Rechnungsnummer und Kundennummer im Namen klappt nicht User helfen Usern - Fragen zu JTL-Wawi 4
Neu Artikel KinderArtikel anlegen: Workflow "Artikel erstellt und Artikel geändert" werden NUR beim Vaterartikel gestartet User helfen Usern - Fragen zu JTL-Wawi 0
Liste exportieren mit Kategorien und Anzahl der Artikel in der jeweiligen Kategorie JTL Ameise - Eigene Exporte 3
Vollständiger Ex- und Import wegen fehlerhafter Datenbank - Reihenfolge? JTL-Wawi 1.6 9
Am eigenen Lager Bestand = 0, bei FBA = 170, Probleme mit dem eigenen Shop und Otto.de JTL-Wawi 1.10 3

Ähnliche Themen