WIP: PayPal-Einstellungen ueber die Verwaltung (Test folgt auf dem Server)

This commit is contained in:
2026-08-23 16:50:18 +02:00
parent 692d702ebf
commit 5043642951
6 changed files with 629 additions and 11 deletions
+31 -11
View File
@@ -29,6 +29,7 @@
===================================================================== */
import { randomUUID } from "node:crypto";
import { einstellung } from "./webdesign-geheimnisse.js";
export class PayPalNichtEingerichtet extends Error {
constructor(fehlend) {
@@ -47,13 +48,13 @@ export class PayPalNichtEingerichtet extends Error {
live) würde echtes Geld bewegt. Die ungefährliche Richtung gehört in die
Voreinstellung. */
function basis() {
return process.env.PAYPAL_ENV === "live"
return einstellung("PAYPAL_ENV") === "live"
? "https://api-m.paypal.com"
: "https://api-m.sandbox.paypal.com";
}
export function istLive() {
return process.env.PAYPAL_ENV === "live";
return einstellung("PAYPAL_ENV") === "live";
}
/* Prüft, ob alles Nötige da ist. `fuer` unterscheidet die beiden Welten:
@@ -62,9 +63,9 @@ export function istLive() {
Betreuungsplan angelegt wurde. */
export function fehlendeEinstellungen(fuer = "einmal") {
const fehlt = [];
if (!process.env.PAYPAL_CLIENT_ID) fehlt.push("PAYPAL_CLIENT_ID");
if (!process.env.PAYPAL_CLIENT_SECRET) fehlt.push("PAYPAL_CLIENT_SECRET");
if (fuer === "abo" && !process.env.PAYPAL_WD_PLAN_BASIS) fehlt.push("PAYPAL_WD_PLAN_BASIS");
if (!einstellung("PAYPAL_CLIENT_ID")) fehlt.push("PAYPAL_CLIENT_ID");
if (!einstellung("PAYPAL_CLIENT_SECRET")) fehlt.push("PAYPAL_CLIENT_SECRET");
if (fuer === "abo" && !einstellung("PAYPAL_WD_PLAN_BASIS")) fehlt.push("PAYPAL_WD_PLAN_BASIS");
return fehlt;
}
@@ -86,7 +87,7 @@ async function zugangstoken() {
if (token && token.laeuftAb > Date.now() + 60_000) return token.wert;
const anmeldung = Buffer.from(
`${process.env.PAYPAL_CLIENT_ID}:${process.env.PAYPAL_CLIENT_SECRET}`
`${einstellung("PAYPAL_CLIENT_ID")}:${einstellung("PAYPAL_CLIENT_SECRET")}`
).toString("base64");
const antwort = await fetch(`${basis()}/v1/oauth2/token`, {
@@ -111,6 +112,14 @@ async function zugangstoken() {
/* Für Tests: Zwischenspeicher leeren, damit ein Wechsel der Zugangsdaten
sofort wirkt statt erst nach einer Stunde. */
/* Meldet sich testweise an und wirft, wenn PayPal ablehnt. Bewegt kein
Geld. Erst das beweist, dass die Zugangsdaten stimmen -- "gesetzt"
heisst nur, dass etwas dasteht. */
export async function zugangstokenPruefen() {
await zugangstoken();
return true;
}
export function tokenVergessen() {
token = null;
}
@@ -158,6 +167,17 @@ export function paypalZuCent(wert) {
return parseInt(ganz, 10) * 100 + parseInt((rest + "00").slice(0, 2), 10);
}
/* WOHER DIE ZUGANGSDATEN KOMMEN
Nicht mehr direkt aus process.env, sondern ueber einstellung() aus
lib/webdesign-geheimnisse.js. Die liest zuerst die .env (dort hat sie
Vorrang) und faellt sonst auf die verschluesselten Werte zurueck, die
Filipe in seiner Verwaltung eintragen kann.
Der Grund ist praktisch: Fuer die .env braucht es SSH, einen Editor
und einen Dienstneustart. Ueber die Verwaltung wirkt eine Aenderung
sofort -- und niemand muss in die Konsole. */
/* ---------------------------------------------------------------------
1) EINMALZAHLUNG — Bestellung anlegen
Der Kunde wird danach zum "approve"-Link geschickt und bestätigt dort
@@ -273,9 +293,9 @@ export async function bestellungAbfragen(orderId) {
PayPal den Betrag am Plan festmacht — nicht am einzelnen Abo. */
export function planFuerPaket(paket) {
const karte = {
basis: process.env.PAYPAL_WD_PLAN_BASIS,
plus: process.env.PAYPAL_WD_PLAN_PLUS,
premium: process.env.PAYPAL_WD_PLAN_PREMIUM,
basis: einstellung("PAYPAL_WD_PLAN_BASIS"),
plus: einstellung("PAYPAL_WD_PLAN_PLUS"),
premium: einstellung("PAYPAL_WD_PLAN_PREMIUM"),
};
return karte[paket] || karte.basis || null;
}
@@ -339,7 +359,7 @@ export async function aboKuendigen(subscriptionId, grund) {
--------------------------------------------------------------------- */
export async function webhookEchtheitPruefen(kopfzeilen, rohkoerper) {
pruefeEingerichtet("einmal");
if (!process.env.PAYPAL_WD_WEBHOOK_ID) {
if (!einstellung("PAYPAL_WD_WEBHOOK_ID")) {
throw new PayPalNichtEingerichtet(["PAYPAL_WD_WEBHOOK_ID"]);
}
@@ -351,7 +371,7 @@ export async function webhookEchtheitPruefen(kopfzeilen, rohkoerper) {
transmission_id: kopfzeilen["paypal-transmission-id"],
transmission_sig: kopfzeilen["paypal-transmission-sig"],
transmission_time: kopfzeilen["paypal-transmission-time"],
webhook_id: process.env.PAYPAL_WD_WEBHOOK_ID,
webhook_id: einstellung("PAYPAL_WD_WEBHOOK_ID"),
webhook_event: JSON.parse(rohkoerper),
}),
});