Myeparts - Meine Ersatzteile und WinPoints

MyEparts WinPoints-Schnittstelle

Einbauanleitung für Webseitenbetreiber · Bestehende Schnittstelle · Stand 11.10.2026

1. Welche Richtung ist gemeint?

Einzahlung: Ein Mitglied überträgt Winpoints von seinem MyEparts-Konto auf das MyEparts-Konto des Webseitenbetreibers. Die Betreiberseite ordnet die Zahlung anschließend ihrem eigenen Benutzer oder Auftrag zu.

Auszahlung: Der Betreiber überträgt Winpoints von seinem MyEparts-Konto auf das MyEparts-Konto eines Mitglieds. Dafür muss der Betreiber genügend Winpoints besitzen.

Die Schnittstelle überträgt Winpoints, keine Euro. Beide Richtungen benötigen mindestens 2 ganze Winpoints.

2. Vorbereitung auf der Betreiberseite

  1. MyEparts-Mitglieds-ID des Betreibers und dessen Schnittstellenpasswort hinterlegen. Das ist das Passwort des Winpoints-Kontos.
  2. Den MD5-Wert dieses Passworts ausschließlich auf dem eigenen Server speichern. Er ist bei dieser Schnittstelle selbst ein Zugangsschlüssel. Nicht an JavaScript, HTML-Formulare oder Besucher weitergeben.
  3. HTTPS verwenden. Zugangsschlüssel und vollständige Auszahlungs-URLs nicht in eigenen Protokollen speichern.
  4. Für jeden Vorgang lokal speichern: eindeutige Vorgangsnummer, eigener Benutzer/Auftrag, Winpoints-Menge und Bearbeitungsstatus.

Die folgenden Beispiele sind für PHP 5.6 geschrieben. Betreiber-ID, Geheimnis und Rückkehradresse ersetzen. Die Verbindung mit der eigenen Benutzer- und Guthabentabelle ist an den markierten Stellen vorzunehmen.

Gemeinsame Konfiguration – nur serverseitig

<?php
$betreiberId = '12345'; // Eigene MyEparts-Mitglieds-ID ersetzen.
$betreiberMd5 = 'HIER_DEN_32_STELLIGEN_MD5_WERT_EINTRAGEN';
// Falls stattdessen das Klartext-Schnittstellenpasswort vorliegt:
// $betreiberMd5 = md5($schnittstellenPasswort);
// Einen bereits vorhandenen MD5-Wert NICHT erneut mit md5() umwandeln.

$rueckkehrUrl = 'https://www.example.org/winpoints-rueckkehr.php';
// Feste HTTPS-Adresse, ohne ?Parameter oder #Fragment.
?>

3. Einzahlung: Mitglied → Betreiber

Die Betreiberseite erstellt serverseitig einen Vorgang und zeigt ein POST-Formular mit Ziel https://myeparts.de/zahlschnittwp.php. Das Mitglied wechselt damit zu MyEparts und gibt dort seine Mitglieds-ID und sein Schnittstellenpasswort ein. anteilzahlen.php bucht die Punkte und leitet bei Erfolg zurück.

POST-FeldInhalt
empfaengerMyEparts-Mitglieds-ID des Betreibers
mengeGanze Winpoints, mindestens 2; ohne Tausendertrennzeichen
v_zweckVerwendungszweck
kunden_var_0Eindeutige Vorgangsnummer der Betreiberseite
zahllinkFeste Rückkehradresse nach erfolgreicher Buchung
keyServerseitig berechnete Prüfsumme
nickAnzeigename des Betreibers; gehört nicht zur Prüfsumme

Kompatibilität: Für neue Einbauten in v_zweck und kunden_var_0 ausschließlich A–Z, a–z, 0–9, Bindestrich, Unterstrich oder Punkt verwenden. Die bestehenden Skripte kodieren diese Felder zweimal; Leerzeichen, Umlaute, Pluszeichen oder Prozentzeichen können deshalb beim zweiten Schritt die Prüfsumme ungültig machen. Die Rückkehradresse darf keine vorhandene Query enthalten, da das Skript selbst ein ? anhängt.

Die Reihenfolge der Prüfsummenbestandteile ist verbindlich:

Einzahlungsformular auf der eigenen Webseite

<?php
// Zuvor gemeinsame Konfiguration laden.
// Betrag aus dem eigenen Auftrag lesen, nicht ungeprüft aus Besuchereingaben.
$menge = 1000;
$zweck = 'Einzahlung';
$vorgang = bin2hex(openssl_random_pseudo_bytes(16));
$betreiberName = 'Meine Webseite';

// VOR Ausgabe des Formulars dauerhaft in der eigenen Datenbank speichern:
// $vorgang, eingeloggter eigener Benutzer/Auftrag, $menge, Status "offen".
// MyEparts-Mitglieds-ID des Zahlenden ebenfalls speichern, falls bekannt.

$key = md5(implode('|', array(
    urlencode((string) $menge),
    urlencode($zweck),
    urlencode($vorgang),
    urlencode($betreiberId),
    $rueckkehrUrl, // Hier KEIN urlencode().
    $betreiberMd5
)));
$felder = array(
    'empfaenger' => $betreiberId,
    'menge' => (string) $menge,
    'v_zweck' => $zweck,
    'kunden_var_0' => $vorgang,
    'zahllink' => $rueckkehrUrl,
    'key' => $key,
    'nick' => $betreiberName
);
?>
<form method="post" action="https://myeparts.de/zahlschnittwp.php"
      accept-charset="UTF-8">
<?php foreach ($felder as $name => $wert): ?>
  <input type="hidden"
    name="<?php echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8'); ?>"
    value="<?php echo htmlspecialchars($wert, ENT_QUOTES, 'UTF-8'); ?>">
<?php endforeach; ?>
  <button type="submit">Mit Winpoints einzahlen</button>
</form>

4. Einzahlung: Rückmeldung prüfen

Bei Erfolg führt MyEparts eine Browserweiterleitung auf diese Adresse aus:

https://www.example.org/winpoints-rueckkehr.php?artikel=VORGANG&passwort=PRUEFSUMME&betrag=1000&userid=MITGLIEDSID
GET-FeldBedeutung
artikelDer zuvor übergebene Wert kunden_var_0
passwortMD5 aus kodierter Vorgangsnummer + MD5 des Betreiberpassworts
betragÜbertragene Winpoints
useridMyEparts-Mitglieds-ID des Zahlenden

Dies ist eine Browserweiterleitung, keine unabhängige Serverbenachrichtigung. Schließt das Mitglied den Browser nach der Buchung, kann die Rückmeldung ausbleiben. Bei Fehlern zeigt MyEparts eine Meldung; es gibt dafür keine zugesicherte Fehlerweiterleitung an den Betreiber.

Prüffunktion für winpoints-rueckkehr.php

<?php
// Gemeinsame Konfiguration laden. Keine neue Zahlung erzeugen.
function pruefeWinpointsRueckkehr(array $get, array $auftrag, $betreiberMd5) {
    foreach (array('artikel', 'passwort', 'betrag', 'userid') as $feld) {
        if (!isset($get[$feld]) || !is_string($get[$feld])) {
            return false;
        }
    }
    // $auftrag stammt aus der EIGENEN Datenbank, nicht aus GET!
    // Erwartete Felder: vorgang, menge; optional myeparts_userid.
    if ($get['artikel'] !== $auftrag['vorgang']) {
        return false;
    }
    $erwartet = md5(urlencode($auftrag['vorgang']) . $betreiberMd5);
    if (!preg_match('/^[a-f0-9]{32}$/D', $get['passwort']) ||
        !hash_equals($erwartet, $get['passwort'])) {
        return false;
    }
    if ($get['betrag'] !== (string) $auftrag['menge'] ||
        !preg_match('/^[0-9]+$/D', $get['userid'])) {
        return false;
    }
    if (isset($auftrag['myeparts_userid']) &&
        $get['userid'] !== (string) $auftrag['myeparts_userid']) {
        return false;
    }
    return true;
}

// Einbindung in die eigene Anwendung:
// 1. Vorgang anhand GET['artikel'] laden; unbekannten Vorgang ablehnen.
// 2. pruefeWinpointsRueckkehr($_GET, $auftrag, $betreiberMd5) aufrufen.
// 3. In einer eigenen DB-Transaktion den Vorgang sperren und erneut prüfen.
// 4. Falls bereits gutgeschrieben: nichts erneut gutschreiben.
// 5. Dem gespeicherten eigenen Benutzer den GESPEICHERTEN Betrag gutschreiben
//    und den Vorgang in derselben Transaktion auf "gutgeschrieben" setzen.
// 6. Erfolg erst nach dem Commit anzeigen.
?>

Grenze der bisherigen Rückmeldung

Die vorhandene Rückgabeprüfsumme schützt nur die Vorgangsnummer, nicht Betrag oder Zahlenden. Eine bereits bekannte gültige Prüfsumme beweist keine neue Zahlung. Deshalb sind der vorher gespeicherte Betrag, die Zuordnung zum eigenen Benutzer und die einmalige Verarbeitung erforderlich. Die Prüffunktion bildet das bestehende Verfahren ab; sie ergänzt keinen unabhängigen Zahlungsnachweis. Für einen solchen Nachweis wäre eine zusätzliche Schnittstellenfunktion samt Anpassung beim Betreiber nötig.

Fehlt die Rückmeldung trotz einer möglichen Buchung, den Vorgang zur Klärung markieren und mit den MyEparts-Buchungen abgleichen. Keine automatische erneute Einziehung auslösen.

5. Auszahlung: Betreiber → Mitglied

Die Auszahlung erfolgt ausschließlich durch einen Aufruf vom Server der Betreiberseite an https://myeparts.de/zahlen_winpoins.php. Der Dateiname lautet tatsächlich zahlen_winpoins.php. Nicht in einen Browserlink oder ein Besucherformular einsetzen.

GET-FeldInhalt
mitgliedsidMyEparts-Mitglieds-ID des zahlenden Betreibers
md5passwMD5 seines Schnittstellenpassworts
empfidMyEparts-Mitglieds-ID des Empfängers
mengeGanze Winpoints, mindestens 2
verwNicht leerer Verwendungszweck, z. B. eine eigene Vorgangsnummer

Das Passwort des Empfängers wird für die Auszahlung nicht benötigt. Der Empfänger muss als Mitglied existieren. Voraussetzung auf der Betreiberseite: PHP-cURL mit funktionierender HTTPS-Zertifikatsprüfung.

Serverseitige Auszahlungsfunktion

<?php
function zahleWinpointsAus($betreiberId, $betreiberMd5, $empfaengerId, $menge, $zweck) {
    if (!preg_match('/^[0-9]+$/D', (string) $betreiberId) ||
        !preg_match('/^[0-9]+$/D', (string) $empfaengerId) ||
        !preg_match('/^[a-f0-9]{32}$/D', $betreiberMd5) ||
        !is_int($menge) || $menge < 2 || !is_string($zweck) || $zweck === '') {
        throw new InvalidArgumentException('Ungueltige Auszahlungsdaten');
    }
    $parameter = array(
        'mitgliedsid' => (string) $betreiberId,
        'md5passw' => $betreiberMd5,
        'empfid' => (string) $empfaengerId,
        'menge' => (string) $menge,
        'verw' => $zweck
    );
    $url = 'https://myeparts.de/zahlen_winpoins.php?' .
           http_build_query($parameter, '', '&', PHP_QUERY_RFC3986);
    $ch = curl_init($url);
    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_FOLLOWLOCATION => false
    ));
    $antwort = curl_exec($ch);
    $http = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $fehler = curl_errno($ch);
    curl_close($ch);
    // Unklar bedeutet: moeglicherweise gebucht. NICHT automatisch wiederholen.
    if ($antwort === false || $fehler !== 0 || $http !== 200) {
        return array('status' => 'unklar');
    }
    $text = trim(strip_tags($antwort));
    if ($text === 'Transaktion erfolgreich|' . (string) $menge) {
        return array('status' => 'erfolgreich', 'menge' => $menge);
    }
    if (preg_match('/^([^|]+)\|0$/D', $text, $treffer)) {
        return array('status' => 'abgelehnt', 'meldung' => $treffer[1]);
    }
    if ($text === 'Nur alle 10 Sekunden ist ein Transfer machbar') {
        return array('status' => 'abgelehnt', 'meldung' => $text);
    }
    return array('status' => 'unklar');
}

// Beispiel NUR als Teil eines bereits gespeicherten Auszahlungsauftrags:
// $ergebnis = zahleWinpointsAus($betreiberId, $betreiberMd5,
//                              '67890', 1000, 'AuszahlungA123');
// Die Funktion zahlt bei einem echten Aufruf sofort aus!
?>

6. Auszahlung in die eigene Webseite einbauen

  1. Empfänger-ID erfassen und den Benutzer auf der eigenen Webseite authentifizieren. Betrag und Auszahlungsberechtigung serverseitig prüfen; bei einem Browserformular den eigenen CSRF-Schutz verwenden.
  2. Einen eindeutigen Auszahlungsauftrag lokal speichern. Das eigene Guthaben in einer Datenbanktransaktion reservieren. Derselbe Auftrag darf nicht durch Doppelklick oder parallele Anfragen zweimal gestartet werden.
  3. Auszahlungen für dasselbe Betreiberkonto über eine gemeinsame Warteschlange nacheinander ausführen. Die derzeitige Auszahlungsdatei besitzt noch nicht die neuen Kontosperren aus anteilzahlen.php.
  4. Die Auszahlungsfunktion genau einmal für diesen Auftrag aufrufen.
  5. Bei erfolgreich die Reservierung endgültig verbuchen und den Auftrag als ausgezahlt markieren.
  6. Bei einer eindeutigen Ablehnung die Reservierung freigeben oder den Auftrag kontrolliert zur späteren Bearbeitung zurückstellen.
  7. Bei unklar die Reservierung behalten und den Auftrag zur Klärung markieren. Erst die MyEparts-Buchungen abgleichen. Nicht automatisch erneut senden.

Die bestehende API kennt keinen Wiederholungsschlüssel. Ein zweiter Aufruf kann eine zweite Auszahlung auslösen, auch wenn verw identisch ist.

Pro Empfänger gilt eine Wartezeit von 30 Sekunden. Auch abgewiesene Versuche können diese Wartezeit starten. Zusätzlich besteht eine ältere Handelssperre, deren Meldung „10 Sekunden“ nennt, obwohl der Code ein 20-Sekunden-Zeitfenster prüft. Keine schnellen Wiederholungsversuche durchführen.

7. Antworten und Fehlermeldungen

Erfolg wird als Transaktion erfolgreich|1000<br> zurückgegeben. Die Menge muss zum eigenen Auftrag passen. Ein HTTP-Status 200 allein bedeutet keinen Erfolg.

Die üblichen Ablehnungen enden auf |0:

  • Es sind nicht alle Parameter korrekt übermittelt worden
  • Falsche Mengenangabe
  • Nur alle 30 Sekunden ist ein Transfer machbar
  • Betreiber ID oder Passwort Falsch, oder Betreiber gesperrt
  • Beim Betreiberkonto Menge nicht vorhanden
  • Angegebene Mitglied ID unbekannt. Es darf nur eine Zahl eingegeben werden, kein Name

Beim Einzug werden Fehlermeldungen auf MyEparts angezeigt. In der aktuell überarbeiteten anteilzahlen.php gilt zusätzlich: nach fünf falschen Passwörtern je Mitglied/IP oder 30 Fehlversuchen je IP jeweils 15 Minuten Sperre. IPv6 wird pro /64-Netz gezählt.

8. Erster Test

  1. Einzahlung mit 2 Winpoints durchführen: auf beiden MyEparts-Konten Abbuchung/Gutschrift prüfen und die einmalige Zuordnung auf der Betreiberseite kontrollieren.
  2. Die Rückkehradresse erneut öffnen: sie darf keine zweite lokale Gutschrift auslösen.
  3. Nach Ablauf der Wartezeit eine Auszahlung mit 2 Winpoints durchführen. Beide MyEparts-Konten und den lokalen Auftrag prüfen.
  4. Doppelklick und Wiederaufruf des eigenen Auszahlungsformulars müssen denselben Auftrag erkennen und dürfen keinen zweiten API-Aufruf auslösen.

Grundlage dieser Anleitung sind die bereitgestellten PHP-Dateien und die zuletzt überarbeitete anteilzahlen.php. Die Beispielcodes wurden auf PHP-5.6-Syntax geprüft; sie wurden hier nicht gegen den produktiven Server ausgeführt.