Stripe Integration
Erstelle automatisch EU-konforme E-Rechnungen wenn eine Stripe-Zahlung eingeht. Stripe Webhook → thelawin.dev → ZUGFeRD-PDF.
Voraussetzungen
- Stripe Account mit Webhook-Zugriff
- thelawin.dev API Key (zum Testen:
env_sandbox_demo) - Server fuer Webhook-Empfang (Node.js, Python, Ruby, etc.)
Architektur
Stripe Payment → Webhook (payment_intent.succeeded)
→ Dein Server (extrahiert Kundendaten + Betrag)
→ POST api.thelawin.dev/v1/generate
→ PDF per Email an Kunden sendenWebhook-Handler (Node.js)
javascript
import Stripe from 'stripe';
import { ThelawinClient } from '@thelawin/sdk';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const thelawin = new ThelawinClient(process.env.THELAWIN_API_KEY);
app.post('/webhooks/stripe', async (req, res) => {
const event = stripe.webhooks.constructEvent(
req.body, req.headers['stripe-signature'], process.env.STRIPE_WEBHOOK_SECRET
);
if (event.type === 'payment_intent.succeeded') {
const payment = event.data.object;
const customer = await stripe.customers.retrieve(payment.customer);
const result = await thelawin.invoice()
.number(`RE-${Date.now()}`)
.date(new Date().toISOString().split('T')[0])
.format('zugferd')
.seller({
name: 'Your Company GmbH',
vatId: 'DE123456789',
city: 'Berlin',
country: 'DE'
})
.buyer({
name: customer.name,
email: customer.email,
city: customer.address?.city,
country: customer.address?.country || 'DE'
})
.addItem({
description: payment.description || 'Service',
quantity: 1,
unitPrice: payment.amount / 100,
})
.generate();
if (result.success) {
// PDF per Email senden, in S3 speichern, etc.
console.log(`Invoice generated: ${result.filename}`);
}
}
res.json({ received: true });
});Webhook-Handler (Python)
python
import stripe
from thelawin import ThelawinClient
stripe.api_key = os.environ["STRIPE_SECRET_KEY"]
client = ThelawinClient(os.environ["THELAWIN_API_KEY"])
@app.route("/webhooks/stripe", methods=["POST"])
def stripe_webhook():
event = stripe.Webhook.construct_event(
request.data, request.headers["Stripe-Signature"],
os.environ["STRIPE_WEBHOOK_SECRET"]
)
if event["type"] == "payment_intent.succeeded":
payment = event["data"]["object"]
customer = stripe.Customer.retrieve(payment["customer"])
result = (
client.invoice()
.number(f"RE-{int(time.time())}")
.date(datetime.now().strftime("%Y-%m-%d"))
.format("zugferd")
.seller("Your Company GmbH", vat_id="DE123456789", city="Berlin", country="DE")
.buyer(customer["name"], email=customer["email"], country="DE")
.add_item(payment.get("description", "Service"), quantity=1, unit_price=payment["amount"] / 100)
.generate()
)
if result.success:
result.save_pdf(f"invoices/{result.filename}")
return jsonify(received=True)Stripe Checkout → Rechnung
Fuer Stripe Checkout Sessions nutze den checkout.session.completed Event:
javascript
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
const lineItems = await stripe.checkout.sessions.listLineItems(session.id);
// Baue Invoice-Items aus lineItems.data
}Naechste Schritte
- API Reference — Alle Felder der Generate-API
- n8n Guide — Stripe-Webhook ohne eigenen Server (via n8n)
- Invoice Formats — ZUGFeRD, XRechnung, Factur-X