Zahlungs-Übersicht
Stripe-Integration, Checkout-Flows, Webhooks und Null-Kredit-Sandbox-Modus.
packages/payments bietet eine gemeinsame Schnittstelle für Checkout, Preiskatalog und Abrechnung. Mitgeliefert sind stripe, lemonsqueezy, polar, dodopayments, paddle, paypal und mock; Creem ist kein enthaltener Adapter.
Abrechnung auswählen und konfigurieren
Setzen Sie PAYMENT_PROVIDER und die passenden Zugangsdaten. Stripe ist der echte Standardanbieter. Die mitgelieferten Zahlungsanbieter unterstützen auch gespeicherte Zugangsdaten und Anbieterwahl unter /app/admin/setup. Umgebungsvariablen haben Vorrang.
| Anbieter | API-Zugangsdaten | Webhook-Route |
|---|---|---|
| Stripe | STRIPE_SECRET_KEY | /api/webhooks/stripe |
| Lemon Squeezy | LEMONSQUEEZY_API_KEY | /api/webhooks/lemonsqueezy |
| Polar | POLAR_ACCESS_TOKEN | /api/webhooks/polar |
| Dodo Payments | DODO_PAYMENTS_API_KEY | /api/webhooks/dodopayments |
| Paddle | PADDLE_API_KEY, PADDLE_CLIENT_TOKEN | /api/webhooks/paddle |
| PayPal | PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET | /api/webhooks/paypal |
Webhook-Secrets und anbieterspezifische Store- oder Produkteinstellungen sind von API-Zugangsdaten getrennt. Prüfen Sie den gewählten Adapter und konfigurieren Sie seinen passenden Endpunkt.
MOCK_SERVICES=true aktiviert simulierten Checkout ausdrücklich, auch bei einem lokalen Testserver im Produktionsmodus. Außerhalb der Produktion funktioniert auch PAYMENT_PROVIDER=mock; ohne Anbieterwahl und Stripe-Zugangsdaten wird Mock verwendet. Produktion ohne Zugangsdaten schlägt fehl, statt simulierten Zugriff zu gewähren.
Paddle und PayPal
Beide verwenden standardmäßig die Sandbox. Setzen Sie PADDLE_ENVIRONMENT oder PAYPAL_ENVIRONMENT nur mit passenden Live-Zugangsdaten und Live-Katalogzuordnungen auf production. Deaktivieren Sie MOCK_SERVICES, um einen echten Sandbox-Adapter zu testen.
Paddle: erstellen Sie Produkte und Preise, einen API-Schlüssel mit den nötigen Produkt-/Preis-, Transaktions-, Abo- und Kundenportalberechtigungen sowie einen Browser-Client-Token für dieselbe Umgebung. Setzen Sie PADDLE_WEBHOOK_SECRET aus einem Benachrichtigungsziel für /api/webhooks/paddle. Abonnieren Sie Abo-Lebenszyklusereignisse, transaction.completed, adjustment.created und adjustment.updated. Hinterlegen Sie die Zahlungsseite /checkout/paddle Ihrer Website in Paddle und lassen Sie sie freigeben; sie öffnet Paddle.js mit der Transaktions-ID und führt danach zur Abrechnungsseite zurück. Nutzen Sie test_-Client-Tokens für die Sandbox und live_ für Produktion. Unterstützt werden Einmalkäufe, wiederkehrende Tarife, Kundenportal, Pausieren, Kündigen und Fortsetzen.
PayPal: erstellen Sie eine REST-App im passenden Sandbox- oder Live-Konto und einen aktiven monatlichen oder jährlichen Abo-Tarif mit Festpreis. Verknüpfen Sie dessen P-...-Tarif-ID als Anbieterpreis-ID der Katalogvariante. Setzen Sie PAYPAL_WEBHOOK_ID auf die ID des App-Webhooks unter /api/webhooks/paypal und abonnieren Sie BILLING.SUBSCRIPTION.*. Das ist eine Webhook-ID, kein gemeinsames Signierungssecret: Der Adapter lässt das unveränderte Ereignis-JSON durch PayPal prüfen und liest dann den aktuellen Abo-Status. Unterstützt werden wiederkehrender Checkout, Pausieren, Kündigen und Fortsetzen. Einmalzahlungen, Einrichtungsgebühren, mehrstufige Testphasen und ein erzeugtes Kundenportal sind nicht implementiert.
Berechtigungen folgen bei beiden Anbietern dem Abo-Lebenszyklus. Wiederkehrende Zahlungs- und Erstattungsereignisse erzeugen kein Rechnungsbuch und entziehen allein keinen Abo-Zugriff. Kündigen oder pausieren Sie das Abo, wenn Ihre Erstattungsregeln das verlangen. Paddle aktiviert außerdem abgeschlossene Einmalkäufe und widerruft sie nach einer genehmigten vollständigen Erstattung. Browser-Rückleitungen gewähren nie Zugriff. Prüfen Sie vor dem Start einen echten Sandbox-Checkout, signierte und doppelte Webhook-Zustellung sowie die Kündigungs- und Erstattungsregeln.
Ein gemeinsamer Preiskatalog
config.payments.plans liefert den Startkatalog. /app/admin/pricing speichert Änderungen in SystemSetting unter pricing und überschreibt damit die Startwerte. Ein Tarif kann einmalige, monatliche und jährliche Varianten enthalten; Preise stehen in der kleinsten Währungseinheit. Echte Anbieterpreise müssen mit passenden Produkt-/Preis-IDs, Beträgen, Währungen und Intervallen verknüpft sein.
Checkout nimmt Tarif- und Varianten-IDs an, prüft Teameigentümer und Verfügbarkeit und ruft dann den Anbieter auf. Rückleitungs-URLs müssen zum Ursprung der Website gehören. Bestehende Kundenpreise sind vor inkompatiblen Änderungen geschützt; ergänzen Sie eine neue Variante. Auch ein Anbieterwechsel verlangt die Prüfung gespeicherter Zuordnungen.
Zahlungsanbieter ergänzen
Implementieren Sie PaymentAdapter aus payments/types in packages/payments/provider/. Ergänzen Sie die Provider-ID in packages/config/providers.ts sowie einen typisierten Resolver und die Zugangsdaten-Definition in packages/payments/provider/selection.ts. Implementieren Sie getAllPlans sowie Checkout, Kundenportal und verifizierte Webhooks. Der gemeinsame Checkout für echte Anbieter prüft verknüpfte Preise anhand von getAllPlans; eine funktionierende Katalogimplementierung ist daher auch ohne Admin-Preiseditor nötig; nicht unterstützte optionale Abo-Operationen müssen klar fehlschlagen. Ergänzen Sie eine explizite Webhook-Route nach dem vorhandenen Muster.
Erhalten Sie Preisprüfung, Rückleitungen zum eigenen Ursprung, Teamautorisierung, Ereignis-Deduplizierung und Berechtigungsaktualisierung. Prüfen Sie fehlgeschlagenen Checkout, ungültige Signaturen, doppelte Ereignisse, Erstattungen und Abo-Änderungen mit den vorhandenen Vertragstests. Ein neuer Adapter migriert vorhandene Kunden oder Abonnements nicht automatisch.
Siehe Stripe-Integration, Einmalige Käufe und Abonnements.
Ergänzen Sie bei einer neuen Provider-ID auch den zugehörigen Zugangsdaten-Hinweiseintrag in packages/config/providers.ts. Dieser dient Produktvalidierung und Setup-Hinweisen; ein Product-Manifest wählt zur Laufzeit keinen Adapter automatisch aus.