Stripe Import & Export Commands¶
Diese Dokumentation listet alle verfügbaren PHP Artisan Commands für den Import und Export von Daten zwischen HostAdmin und Stripe.
Inhaltsverzeichnis¶
- Import Commands (Stripe → HostAdmin)
- stripe:import-customers
- stripe:import-subscriptions
- stripe:import-invoices
- stripe:import-subscription-items
- Export/Sync Commands (HostAdmin → Stripe)
- stripe:sync-customers
- stripe:sync-products
- subscriptions:update-descriptions
- Utility Commands
- customer:link-stripe
- Automatisierung
- Best Practices
Import Commands (Stripe → HostAdmin)¶
Diese Commands importieren Daten von Stripe in HostAdmin.
stripe:import-customers¶
Importiert Kunden von Stripe in HostAdmin.
Verwendung¶
# Docker
docker-compose exec app php artisan stripe:import-customers [OPTIONS]
# Lokal
php artisan stripe:import-customers [OPTIONS]
Optionen¶
| Option | Beschreibung |
|---|---|
--dry-run |
Simulation ohne tatsächlichen Import |
--update-existing |
Verknüpft bestehende HostAdmin-Kunden (gleiche E-Mail) mit Stripe |
Beispiele¶
# Dry-Run (empfohlen für ersten Test)
docker-compose exec app php artisan stripe:import-customers --dry-run
# Echter Import
docker-compose exec app php artisan stripe:import-customers
# Mit Verknüpfung bestehender Kunden
docker-compose exec app php artisan stripe:import-customers --update-existing
Was wird importiert?¶
- Kundendaten (Name, E-Mail, Adresse, Telefon)
- Stripe Customer ID
- Standard-Zahlungsmethode
- Tax Rate (19% für DE, sonst 0%)
- Source =
stripe
Duplikat-Behandlung¶
- E-Mail-Duplikate: Ohne
--update-existingwerden übersprungen - Metadata
customer_id: Kunde gilt als bereits synchronisiert
Automatisierung¶
Läuft automatisch täglich um 3:00 Uhr (siehe routes/console.php).
stripe:import-subscriptions¶
Importiert Subscriptions von Stripe in HostAdmin.
Verwendung¶
Optionen¶
| Option | Beschreibung |
|---|---|
--dry-run |
Simulation ohne tatsächlichen Import |
--update-existing |
Aktualisiert bestehende Subscriptions wenn Stripe ID übereinstimmt |
Beispiele¶
# Dry-Run
docker-compose exec app php artisan stripe:import-subscriptions --dry-run
# Echter Import
docker-compose exec app php artisan stripe:import-subscriptions
# Mit Update bestehender
docker-compose exec app php artisan stripe:import-subscriptions --update-existing
Was wird importiert?¶
- Subscription Details (Status, Billing Cycle, Next Billing Date)
- Subscription Items mit Prices
- Verknüpfung mit Kunden
- Metadata-Mapping zu ServiceDefinitions
- Source =
stripe
Voraussetzungen¶
- Kunden müssen bereits importiert sein (
stripe:import-customers) - ServiceDefinitions sollten synchronisiert sein (
stripe:sync-products)
Status-Mapping¶
| Stripe Status | HostAdmin Status |
|---|---|
active |
Active |
canceled, cancelled |
Cancelled |
incomplete, incomplete_expired |
Draft |
past_due |
Active (mit Flag) |
trialing |
Active |
unpaid |
Active |
stripe:import-invoices¶
NEU! Importiert Rechnungen von Stripe in HostAdmin.
Verwendung¶
Optionen¶
| Option | Wert | Beschreibung |
|---|---|---|
--from |
Y-m-d |
Start-Datum für Import (z.B. 2024-01-01) |
--to |
Y-m-d |
End-Datum für Import (z.B. 2024-12-31) |
--status |
paid, open, draft, void, uncollectible |
Filter nach Status (mehrfach möglich) |
--dry-run |
- | Simulation ohne tatsächlichen Import |
--download-pdfs |
- | PDFs automatisch herunterladen |
Beispiele¶
# Alle unbezahlten Rechnungen ab 2024
docker-compose exec app php artisan stripe:import-invoices --from=2024-01-01 --status=open
# Alle bezahlten Rechnungen mit PDFs
docker-compose exec app php artisan stripe:import-invoices --status=paid --download-pdfs
# Dry Run für letzten Monat
docker-compose exec app php artisan stripe:import-invoices --from=2024-12-01 --to=2024-12-31 --dry-run
# Alle Rechnungen mit PDF-Download (empfohlen)
docker-compose exec app php artisan stripe:import-invoices --download-pdfs
Was wird importiert?¶
- Invoice-Daten: Nummer, Datum, Fälligkeitsdatum, Beträge
- Invoice Items: Alle Positionen mit Beschreibung, Menge, Preisen
- Status: Draft, Sent, Paid, Overdue, Cancelled
- PDFs: Werden zu S3 heruntergeladen (wenn
--download-pdfsaktiviert) - Payment Records: Für bezahlte Rechnungen automatisch erstellt
- Source:
stripe
PDF-Ablage¶
PDFs werden nach folgendem Schema gespeichert:
Beispiel: customer/123/invoices/2025/10001-RE-2025-001.pdf
Status-Mapping¶
| Stripe Status | HostAdmin Status |
|---|---|
draft |
draft |
open |
sent |
paid |
paid |
void |
cancelled |
uncollectible |
overdue |
Voraussetzungen¶
- Kunden müssen bereits importiert sein (
stripe:import-customers)
Performance-Hinweis¶
Mit --download-pdfs kann der Import mehrere Minuten dauern, da jedes PDF einzeln von Stripe heruntergeladen wird.
stripe:import-subscription-items¶
Importiert fehlende Subscription Items und erstellt automatisch CustomerServices.
Verwendung¶
Optionen¶
| Option | Beschreibung |
|---|---|
--create-services |
Erstellt automatisch CustomerServices für Items |
Beispiel¶
Voraussetzungen¶
- Kunden importiert
- Subscriptions importiert
- ServiceDefinitions synchronisiert
Export/Sync Commands (HostAdmin → Stripe)¶
Diese Commands übertragen Daten von HostAdmin zu Stripe.
stripe:sync-customers¶
Synchronisiert lokale Kunden zu Stripe (erstellt oder aktualisiert).
NEU: Sucht standardmäßig nach existierenden Stripe-Kunden anhand der E-Mail-Adresse, um Duplikate zu vermeiden.
Verwendung¶
Optionen¶
| Option | Wert | Beschreibung |
|---|---|---|
--force |
- | Synchronisiert alle Kunden neu (auch bereits synchronisierte) |
--id |
customer_id |
Nur bestimmte Kunden synchronisieren (mehrfach möglich) |
--no-search |
- | NEU: Erstellt immer neue Stripe-Kunden ohne nach existierenden zu suchen |
Beispiele¶
# Alle unsyncten Kunden (mit Suche nach existierenden - EMPFOHLEN)
docker-compose exec app php artisan stripe:sync-customers
# Alle Kunden neu synchronisieren (mit Suche nach existierenden)
docker-compose exec app php artisan stripe:sync-customers --force
# Nur Kunde mit ID 123 (mit Suche nach existierenden)
docker-compose exec app php artisan stripe:sync-customers --id=123
# Mehrere Kunden (mit Suche nach existierenden)
docker-compose exec app php artisan stripe:sync-customers --id=123 --id=456
# OHNE Suche - erstellt immer neue Kunden (Legacy-Verhalten)
docker-compose exec app php artisan stripe:sync-customers --no-search
Was wird synchronisiert?¶
- Name (company_name oder first_name/last_name)
- Adresse (inkl. Country)
- Telefon
- Tax ID (mit automatischem Type-Mapping nach Land)
- Metadata:
customer_id,customer_number
Suche nach existierenden Kunden (NEU)¶
Standard-Verhalten (empfohlen):
Wenn ein Kunde keine stripe_customer_id hat:
1. Suche auf Stripe nach Kunden mit gleicher E-Mail-Adresse
2. Falls gefunden: Verknüpft den existierenden Stripe-Kunden und updated dessen Daten
3. Falls nicht gefunden: Erstellt einen neuen Stripe-Kunden
Vorteile: - ✅ Vermeidet Duplikate auf Stripe - ✅ Verknüpft automatisch bereits existierende Stripe-Kunden - ✅ Nützlich bei Migrationen oder Re-Importen - ✅ Bessere Datenintegrität
Logging:
- Bei gefundenem Kunden: Found existing Stripe customer by email
- Bei neuem Kunden: Created new Stripe customer
Auto-Sync Logik¶
Ohne --force werden nur Kunden synchronisiert:
- Die noch keine stripe_customer_id haben
- Oder deren stripe_synced_at älter als 24h ist
stripe:sync-products¶
Synchronisiert ServiceDefinitions als Stripe Products und Prices.
Verwendung¶
Optionen¶
| Option | Wert | Beschreibung |
|---|---|---|
--force |
- | Synchronisiert alle Products neu |
--id |
service_definition_id |
Nur bestimmte ServiceDefinitions (mehrfach möglich) |
Beispiele¶
# Alle unsyncten ServiceDefinitions
docker-compose exec app php artisan stripe:sync-products
# Alle neu synchronisieren
docker-compose exec app php artisan stripe:sync-products --force
# Nur ServiceDefinition mit ID 5
docker-compose exec app php artisan stripe:sync-products --id=5
Was wird synchronisiert?¶
Product:
- Name
- Beschreibung
- Active-Status
- Tax Code: txcd_10000000 (Software/Digital Services)
- Metadata: service_definition_id, article_number, service_type, billing_cycle
Price:
- Amount (in Cents)
- Currency: EUR
- Tax Behavior: exclusive
- Recurring Interval (monthly, quarterly, yearly)
- Metadata: service_definition_id, billing_cycle
Billing Cycle Mapping¶
| HostAdmin | Stripe Interval |
|---|---|
monatlich, 1 |
month / 1 |
vierteljaehrlich, 3 |
month / 3 |
halbjaehrlich, 6 |
month / 6 |
jaehrlich, 12 |
year / 1 |
zweijaehrlich, 24 |
year / 2 |
einmalig, 0 |
One-time (kein recurring) |
Price Immutability¶
Wichtig: Stripe Prices sind immutable! Bei Änderungen:
1. Alte Price wird archiviert (active = false)
2. Neue Price wird erstellt
3. stripe_price_id wird aktualisiert
Rate Limiting¶
Der Command enthält 0.5s Delay zwischen Produkten, um Stripe Rate Limits zu vermeiden.
subscriptions:update-descriptions¶
Aktualisiert die Beschreibungen (Namen) aller Subscriptions in Stripe.
Verwendung¶
Was passiert?¶
- Für jede Subscription in HostAdmin:
- Name wird aus Subscription + Items generiert
- Name wird zu Stripe hochgeladen
- Macht Subscriptions in Stripe lesbarer
Beispiel-Output¶
Vorher: sub_1ABC123
Nachher: Hosting Pro (10001) - 3 Services
Utility Commands¶
customer:link-stripe¶
Manuelles Verknüpfen eines HostAdmin-Kunden mit einem Stripe Customer.
Verwendung¶
Beispiel¶
# Verknüpfe HostAdmin Kunde 123 mit Stripe Customer cus_ABC123
docker-compose exec app php artisan customer:link-stripe 123 cus_ABC123
Wann nutzen?¶
- Nach manueller Erstellung in Stripe
- Bei Migrationen
- Zur Fehlerkorrektur
Automatisierung¶
Scheduled Commands¶
In routes/console.php konfiguriert:
Scheduler aktivieren¶
Der Scheduler-Container muss laufen:
Scheduler-Status prüfen¶
# Liste aller scheduled Tasks
docker-compose exec app php artisan schedule:list
# Scheduler-Logs
docker-compose logs -f scheduler
Custom Schedule¶
Beispiele für eigene Schedules:
// Wöchentlich statt täglich
Schedule::command('stripe:import-customers')->weekly();
// Nur montags um 3 Uhr
Schedule::command('stripe:import-customers')->mondays()->at('03:00');
// Alle 6 Stunden
Schedule::command('stripe:import-customers')->everySixHours();
// Invoice-Import täglich um 4 Uhr
Schedule::command('stripe:import-invoices --download-pdfs')->dailyAt('04:00');
Best Practices¶
1. Import-Reihenfolge¶
Für einen vollständigen Import von Stripe:
# 1. Kunden importieren
docker-compose exec app php artisan stripe:import-customers
# 2. Produkte synchronisieren (falls nötig)
docker-compose exec app php artisan stripe:sync-products
# 3. Subscriptions importieren
docker-compose exec app php artisan stripe:import-subscriptions
# 4. Subscription Items importieren
docker-compose exec app php artisan stripe:import-subscription-items --create-services
# 5. Rechnungen importieren
docker-compose exec app php artisan stripe:import-invoices --download-pdfs
2. Immer erst Dry-Run¶
Bei jedem Command mit --dry-run Option:
3. Monitoring¶
Logs überwachen während laufender Imports:
# Application Logs
docker-compose exec app tail -f storage/logs/laravel.log
# Scheduler Logs
docker-compose logs -f scheduler
# Queue Logs (falls Queue genutzt wird)
docker-compose logs -f queue
4. Settings prüfen¶
Vor Stripe-Operations:
docker-compose exec app php artisan tinker
# Stripe-Konfiguration prüfen
>>> config('services.stripe.secret')
>>> config('services.stripe.webhook_secret')
# Settings prüfen
>>> setting('stripe_download_invoice_pdf')
>>> setting('billing_use_stripe_invoices')
5. Fehlerbehandlung¶
Bei Fehlern:
- Logs prüfen:
storage/logs/laravel.log - Stripe Dashboard: Überprüfen ob Daten in Stripe korrekt sind
- Metadata prüfen: In Stripe Dashboard → Customer/Subscription → Metadata
- Command wiederholen: Meistens idempotent
6. Performance¶
Bei großen Datenmengen:
- Invoices:
--fromund--tonutzen für zeitliche Begrenzung - Customers: In Batches via
--idimportieren - PDF-Download: Separat nach Import durchführen wenn zeitkritisch
7. Backup¶
Vor großen Operationen:
# Database Backup
docker-compose exec hostadmin-db mysqldump -u laravel -p hostadmin > backup.sql
# Oder via phpMyAdmin
# http://localhost:8088
Troubleshooting¶
Problem: "Stripe API key not configured"¶
Lösung:
# .env prüfen
grep STRIPE .env
# Sollte enthalten:
# STRIPE_KEY=pk_...
# STRIPE_SECRET=sk_...
# STRIPE_WEBHOOK_SECRET=whsec_...
Problem: "Customer not found"¶
Ursache: Rechnungs-Import findet Kunden nicht
Lösung:
Problem: "Price already exists"¶
Ursache: ServiceDefinition wurde mehrfach synchronisiert
Lösung: Ist normal! Alte Price wird archiviert, neue erstellt.
Problem: "Rate limit exceeded"¶
Ursache: Zu viele API-Requests zu Stripe
Lösung:
- Warten und wiederholen
- --id Option nutzen für kleinere Batches
- Rate Limiting in Code ist bereits aktiv (0.5s delay)
Problem: "Invoice PDF download failed"¶
Ursache: PDF nicht verfügbar oder S3-Problem
Lösung:
# S3-Konfiguration prüfen
docker-compose exec app php artisan tinker
>>> \Storage::disk('s3')->exists('test.txt')
# MinIO Console prüfen
# http://localhost:9091
Problem: Scheduler läuft nicht¶
Lösung:
# Scheduler-Container starten
docker-compose up -d scheduler
# Status prüfen
docker-compose ps scheduler
# Logs prüfen
docker-compose logs scheduler
Webhook-Integration¶
Für automatische Synchronisation via Webhooks siehe:
- Webhook-Handler: app/Http/Controllers/Api/StripeWebhookController.php
- Webhook-Route: /api/webhooks/stripe
Events:
- invoice.finalized → Invoice wird importiert
- invoice.paid → Status wird aktualisiert, Payment erstellt
- invoice.payment_succeeded → Payment erstellt
- invoice.payment_failed → Status auf overdue
- customer.subscription.created/updated/deleted → Subscription-Status aktualisiert
Konfiguration in Stripe Dashboard:
1. Developers → Webhooks → Add endpoint
2. URL: https://your-domain.com/api/webhooks/stripe
3. Events auswählen
4. Webhook Secret in .env: STRIPE_WEBHOOK_SECRET=whsec_...
Weiterführende Links¶
- Stripe API Docs: https://stripe.com/docs/api
- Laravel Scheduling: https://laravel.com/docs/scheduling
- Filament Admin Panel: https://filamentphp.com
Command-Übersicht (Quick Reference)¶
# === IMPORTS (Stripe → HostAdmin) ===
php artisan stripe:import-customers [--dry-run] [--update-existing]
php artisan stripe:import-subscriptions [--dry-run] [--update-existing]
php artisan stripe:import-invoices [--from=] [--to=] [--status=] [--dry-run] [--download-pdfs]
php artisan stripe:import-subscription-items [--create-services]
# === EXPORTS/SYNC (HostAdmin → Stripe) ===
php artisan stripe:sync-customers [--force] [--id=*] [--no-search]
php artisan stripe:sync-products [--force] [--id=*]
php artisan subscriptions:update-descriptions
# === UTILITIES ===
php artisan customer:link-stripe {customer_id} {stripe_customer_id}
# === SCHEDULER ===
php artisan schedule:list
php artisan schedule:run