WIP: PayPal-Einstellungen ueber die Verwaltung (Test folgt auf dem Server)
This commit is contained in:
@@ -638,6 +638,7 @@
|
||||
<button type="button" class="vw-filter-knopf vw-an" data-tab="anfragen">Anfragen</button>
|
||||
<button type="button" class="vw-filter-knopf" data-tab="projekte">Projekte</button>
|
||||
<button type="button" class="vw-filter-knopf" data-tab="kunden">Kunden</button>
|
||||
<button type="button" class="vw-filter-knopf" data-tab="zahlungen">Zahlungen</button>
|
||||
<button type="button" class="vw-filter-knopf" data-tab="postfach">Postfach<span
|
||||
class="vw-abzeichen" id="vw-pf-zaehler" hidden>0</span></button>
|
||||
</div>
|
||||
@@ -725,6 +726,13 @@
|
||||
<div id="vw-projekte-liste"><div class="vw-laedt">Wird geladen…</div></div>
|
||||
</div>
|
||||
|
||||
<!-- ============ ZAHLUNGEN ============ -->
|
||||
<div id="vw-zahlungen-bereich" hidden>
|
||||
<div id="vw-pp-stand"><div class="vw-laedt">Wird geladen…</div></div>
|
||||
<h2 style="font-size:1.15rem;margin-top:1.6rem">Zahlungen</h2>
|
||||
<div id="vw-zahlungen-liste"><div class="vw-laedt">Wird geladen…</div></div>
|
||||
</div>
|
||||
|
||||
<!-- ============ POSTFACH ============ -->
|
||||
<div id="vw-postfach-bereich" hidden>
|
||||
<p class="wd-klein wd-leise" style="margin-bottom:1rem">
|
||||
@@ -1423,6 +1431,7 @@
|
||||
anfragen: { titel: "Projektanfragen", kasten: null },
|
||||
projekte: { titel: "Projekte", kasten: "vw-projekte-bereich" },
|
||||
kunden: { titel: "Kunden", kasten: "vw-kunden-bereich" },
|
||||
zahlungen:{ titel: "Zahlungen", kasten: "vw-zahlungen-bereich" },
|
||||
postfach: { titel: "Postfach", kasten: "vw-postfach-bereich" },
|
||||
};
|
||||
|
||||
@@ -1443,6 +1452,7 @@
|
||||
|
||||
if (aktiverTab === "kunden") ladeKunden();
|
||||
if (aktiverTab === "projekte") ladeProjekte();
|
||||
if (aktiverTab === "zahlungen") ladeZahlungen();
|
||||
if (aktiverTab === "postfach") ladePostfach();
|
||||
});
|
||||
});
|
||||
@@ -1956,6 +1966,197 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* =================================================================
|
||||
ZAHLUNGEN UND PAYPAL-EINRICHTUNG
|
||||
|
||||
Filipe soll die Zugangsdaten HIER eintragen koennen und nicht per
|
||||
SSH in einer Datei. Die Werte gehen verschluesselt in die Datenbank
|
||||
und wirken sofort -- ohne Dienstneustart.
|
||||
|
||||
Was hier NIE passiert: einen hinterlegten Wert wieder anzeigen. Der
|
||||
Server gibt ihn gar nicht erst heraus. Sichtbar ist nur, ob etwas da
|
||||
ist, woher es stammt und wie lang es ist.
|
||||
================================================================= */
|
||||
var PP_FELDER = [
|
||||
{ k: "PAYPAL_ENV", titel: "Betriebsart", art: "wahl",
|
||||
hilfe: "live = echtes Geld. sandbox = Testbetrieb, es fliesst nichts." },
|
||||
{ k: "PAYPAL_CLIENT_ID", titel: "Client ID", art: "text",
|
||||
hilfe: "developer.paypal.com → Apps & Credentials → deine App" },
|
||||
{ k: "PAYPAL_CLIENT_SECRET", titel: "Secret", art: "geheim",
|
||||
hilfe: "Dort daneben auf „Show“ klicken. Wird nach dem Speichern nie wieder angezeigt." },
|
||||
{ k: "PAYPAL_WD_WEBHOOK_ID", titel: "Webhook-Kennung", art: "text",
|
||||
hilfe: "Beginnt mit WH-. Entsteht, wenn du den Webhook anlegst." },
|
||||
{ k: "PAYPAL_WD_PLAN_BASIS", titel: "Plan für die Betreuung", art: "text",
|
||||
hilfe: "Beginnt mit P-. Nur nötig für monatliche Betreuungs-Abos." },
|
||||
];
|
||||
|
||||
async function ladeZahlungen() {
|
||||
var ziel = document.getElementById("vw-pp-stand");
|
||||
ziel.innerHTML = '<div class="vw-laedt">Wird geladen…</div>';
|
||||
try {
|
||||
var d = await api("/webdesign/admin/einstellungen");
|
||||
zeichnePayPal(d);
|
||||
} catch (fehler) {
|
||||
if (fehler.status === 401) { token = null; tokenSchreiben(null); zeigeAnmeldung(); return; }
|
||||
ziel.innerHTML = '<div class="vw-leer-hinweis">' + s(fehler.message) + "</div>";
|
||||
}
|
||||
ladeZahlungsliste();
|
||||
}
|
||||
|
||||
function zeichnePayPal(d) {
|
||||
var e = d.einrichtung || {};
|
||||
var st = d.stand || {};
|
||||
|
||||
var kopf = e.einmal
|
||||
? (e.live
|
||||
? '<div class="wd-hinweis" style="margin-bottom:1rem;border-left-color:var(--wd-ok)">' +
|
||||
'<p class="wd-hinweis-titel" style="color:var(--wd-ok)">PayPal ist eingerichtet — Echtbetrieb</p>' +
|
||||
'<p class="wd-klein">Zahlungen gehen direkt auf dein Konto.</p></div>'
|
||||
: '<div class="wd-hinweis" style="margin-bottom:1rem"><p class="wd-hinweis-titel">' +
|
||||
'Eingerichtet, aber im TESTMODUS</p><p class="wd-klein">Es fließt kein echtes Geld. ' +
|
||||
'Stell die Betriebsart auf <strong>Echtbetrieb</strong>, sobald du bereit bist.</p></div>')
|
||||
: '<div class="wd-hinweis" style="margin-bottom:1rem"><p class="wd-hinweis-titel">' +
|
||||
'Noch nicht eingerichtet</p><p class="wd-klein">Es fehlt: <strong>' +
|
||||
s((e.fehlt || []).join(", ") || "—") + '</strong>. ' +
|
||||
'Solange sagt das Kundenportal freundlich Bescheid und nennt den Weg über das Postfach.</p></div>';
|
||||
|
||||
var felder = PP_FELDER.map(function (f) {
|
||||
var z = st[f.k] || {};
|
||||
var lage = z.gesetzt
|
||||
? '<span class="wd-tag wd-tag--ok">hinterlegt' +
|
||||
(z.quelle === "server" ? " (auf dem Server)" : "") +
|
||||
(z.laenge ? " · " + z.laenge + " Zeichen" : "") + "</span>"
|
||||
: '<span class="wd-tag wd-tag--gold">fehlt</span>';
|
||||
|
||||
if (f.art === "wahl") {
|
||||
var jetztWert = z.wert || "sandbox";
|
||||
return '<div class="wd-feld" style="margin-bottom:1rem">' +
|
||||
"<label>" + s(f.titel) + " " + lage + "</label>" +
|
||||
'<div class="vw-status-wahl" style="margin:.3rem 0">' +
|
||||
'<button type="button" class="vw-filter-knopf' + (jetztWert === "sandbox" ? " vw-an" : "") +
|
||||
'" data-pp-env="sandbox">Testmodus</button>' +
|
||||
'<button type="button" class="vw-filter-knopf' + (jetztWert === "live" ? " vw-an" : "") +
|
||||
'" data-pp-env="live">Echtbetrieb</button>' +
|
||||
"</div>" +
|
||||
'<span class="wd-feld-hilfe">' + s(f.hilfe) + "</span></div>";
|
||||
}
|
||||
|
||||
/* Der Platzhalter sagt ausdruecklich, dass Leerlassen NICHTS
|
||||
aendert. Ohne diesen Hinweis loescht man beim Speichern eines
|
||||
einzelnen Feldes versehentlich die anderen -- oder glaubt es
|
||||
zumindest und traut sich deshalb nicht. */
|
||||
return '<div class="wd-feld" style="margin-bottom:1rem">' +
|
||||
'<label for="pp-' + f.k + '">' + s(f.titel) + " " + lage + "</label>" +
|
||||
'<input type="' + (f.art === "geheim" ? "password" : "text") + '" id="pp-' + f.k +
|
||||
'" autocomplete="off" spellcheck="false" placeholder="' +
|
||||
(z.gesetzt ? "leer lassen → unverändert" : "hier einfügen") + '" />' +
|
||||
'<span class="wd-feld-hilfe">' + s(f.hilfe) + "</span></div>";
|
||||
}).join("");
|
||||
|
||||
document.getElementById("vw-pp-stand").innerHTML =
|
||||
kopf +
|
||||
'<div class="wd-karte">' +
|
||||
'<h2 style="font-size:1.15rem;margin-top:0">PayPal einrichten</h2>' +
|
||||
'<p class="wd-klein wd-leise">Die Werte werden verschlüsselt gespeichert und wirken sofort — ' +
|
||||
"kein Neustart nötig. Ein gespeicherter Wert wird nie wieder angezeigt; " +
|
||||
"wer ihn verliert, erzeugt bei PayPal einen neuen.</p>" +
|
||||
'<div class="wd-hinweis" style="margin:.9rem 0">' +
|
||||
'<p class="wd-hinweis-titel">Diese Adresse trägst du bei PayPal als Webhook ein</p>' +
|
||||
'<code style="display:block;word-break:break-all;font-size:.86rem;margin-top:.3rem">' +
|
||||
s(d.webhookUrl || "") + "</code></div>" +
|
||||
felder +
|
||||
'<div class="wd-btn-reihe">' +
|
||||
'<button type="button" class="wd-btn wd-btn--haupt" id="pp-speichern">Speichern</button>' +
|
||||
'<button type="button" class="wd-btn wd-btn--zweit" id="pp-pruefen">Verbindung testen</button>' +
|
||||
"</div>" +
|
||||
'<p class="wd-klein wd-leise" style="margin:.7rem 0 0">' +
|
||||
"„Verbindung testen“ meldet sich probeweise bei PayPal an. " +
|
||||
"Es fließt dabei kein Geld — aber erst das beweist, dass die Werte stimmen.</p>" +
|
||||
"</div>";
|
||||
|
||||
var gewaehlteArt = null;
|
||||
document.querySelectorAll("[data-pp-env]").forEach(function (b) {
|
||||
b.addEventListener("click", function () {
|
||||
gewaehlteArt = b.dataset.ppEnv;
|
||||
document.querySelectorAll("[data-pp-env]").forEach(function (x) {
|
||||
x.classList.toggle("vw-an", x === b);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("pp-speichern").addEventListener("click", async function () {
|
||||
var knopf = this;
|
||||
var werte = {};
|
||||
PP_FELDER.forEach(function (f) {
|
||||
if (f.art === "wahl") { if (gewaehlteArt) werte[f.k] = gewaehlteArt; return; }
|
||||
var el = document.getElementById("pp-" + f.k);
|
||||
/* Leeres Feld = NICHT anfassen. Nur so kann man ein einzelnes
|
||||
Feld nachtragen, ohne die anderen zu verlieren. */
|
||||
if (el && el.value.trim()) werte[f.k] = el.value.trim();
|
||||
});
|
||||
if (!Object.keys(werte).length) {
|
||||
window.WD.meldung(meldung, "Nichts eingetragen — es wurde nichts geändert.", "fehler");
|
||||
return;
|
||||
}
|
||||
window.WD.knopfSperren(knopf, true, "…");
|
||||
try {
|
||||
var r = await api("/webdesign/admin/einstellungen", { method: "POST", body: { werte: werte } });
|
||||
/* Felder sofort leeren: Ein Secret soll nicht im Formular stehen
|
||||
bleiben, wenn jemand anders auf den Bildschirm schaut. */
|
||||
PP_FELDER.forEach(function (f) {
|
||||
var el = document.getElementById("pp-" + f.k);
|
||||
if (el) el.value = "";
|
||||
});
|
||||
window.WD.meldung(meldung, "Gespeichert: " + (r.geaendert || []).join(", "), "ok");
|
||||
ladeZahlungen();
|
||||
} catch (f2) {
|
||||
window.WD.knopfSperren(knopf, false);
|
||||
window.WD.meldung(meldung, f2.message, "fehler");
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("pp-pruefen").addEventListener("click", async function () {
|
||||
var knopf = this;
|
||||
window.WD.knopfSperren(knopf, true, "Wird getestet…");
|
||||
try {
|
||||
var r = await api("/webdesign/admin/einstellungen/pruefen", { method: "POST", body: {} });
|
||||
window.WD.meldung(meldung, r.meldung, r.live ? "ok" : "fehler");
|
||||
} catch (f2) {
|
||||
window.WD.meldung(meldung, f2.message, "fehler");
|
||||
} finally { window.WD.knopfSperren(knopf, false); }
|
||||
});
|
||||
}
|
||||
|
||||
async function ladeZahlungsliste() {
|
||||
var ziel = document.getElementById("vw-zahlungen-liste");
|
||||
try {
|
||||
var d = await api("/webdesign/admin/zahlungen");
|
||||
if (!d.zahlungen.length) {
|
||||
ziel.innerHTML = '<div class="vw-leer-hinweis" style="padding:2rem 1rem">' +
|
||||
"Noch keine Zahlungen. Sie entstehen im Projekt.</div>";
|
||||
return;
|
||||
}
|
||||
ziel.innerHTML = d.zahlungen.map(function (z) {
|
||||
var marke = z.status === "bezahlt" ? "angenommen"
|
||||
: z.status === "offen" ? "neu"
|
||||
: z.status === "fehlge" ? "abgelehnt" : "pruefung";
|
||||
return '<div class="vw-karte" style="cursor:default">' +
|
||||
'<span class="vw-karte-nr">' + s(z.nummer) + "</span>" +
|
||||
'<span class="vw-karte-mitte">' +
|
||||
'<span class="vw-karte-name">' + s(z.betragText) + " · " + s(z.zweck_text || "") + "</span>" +
|
||||
'<span class="vw-karte-info">' + s(z.kunde_name || "") +
|
||||
(z.projekt_titel ? " · " + s(z.projekt_titel) : "") + "</span>" +
|
||||
"</span>" +
|
||||
'<span class="vw-karte-rechts">' +
|
||||
'<span class="vw-status vw-status--' + marke + '">' + s(z.status) + "</span>" +
|
||||
'<span class="vw-karte-zeit">' + window.WD.datum(z.erstellt_am) + "</span>" +
|
||||
"</span></div>";
|
||||
}).join("");
|
||||
} catch (fehler) {
|
||||
ziel.innerHTML = "";
|
||||
}
|
||||
}
|
||||
|
||||
/* =================================================================
|
||||
POSTFACH
|
||||
|
||||
|
||||
Reference in New Issue
Block a user