- Provider-Status/Uptime: Stripe-Kachel aktiviert; payment:check-uptime prüft zusätzlich api.stripe.com/v1/ (401 ohne Key = erreichbar) inkl. Auto-Incident - Zahlungen: Anbieter-Filter, Provider-Badges, Umsatz je Provider, Stripe-Dashboard-Deep-Links (ShoppingPayment/PaymentTransaction:: stripeDashboardUrl, pi_-Guard, testmodus-bewusst) - Rohe Transaktionen: Anbieter-Filter/-Spalte, Erfolgsraten je Anbieter; Bugfix: Stringable-Vergleich ließ den txaction-Filter immer mit leerem Wert greifen — Liste war dauerhaft leer - Neue Kachel „Abos je Anbieter" (Index + GF-Ansicht) mit Fehlerzählern und Stripe-Anteil-Fortschrittsbalken (Auslaufmodell PAYONE → Stripe ablesbar) - Incident-Kachel weist Stripe/PAYONE getrennt aus; Log-Viewer mit Kanal-Umschalter stripe/payone - Plan-Doku: S7.4-Umsetzungsstatus, Abo-Go-Live 2026-07-10 vermerkt Tests: PaymentDashboardProviderTest (9 neu), Dashboard-Suite 49 grün. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
119 lines
5.6 KiB
PHP
119 lines
5.6 KiB
PHP
@extends('layouts.layout-2')
|
|
|
|
@section('content')
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h4 class="mb-0">
|
|
<i class="ion ion-md-alert text-danger"></i> Payment Monitor
|
|
</h4>
|
|
<small class="text-muted">Stand: {{ now()->format('d.m.Y H:i') }}</small>
|
|
</div>
|
|
<a href="{{ route('admin.payment-dashboard.index') }}" class="btn btn-outline-secondary btn-sm">
|
|
<i class="ion ion-md-code-working"></i> Entwickler-Ansicht
|
|
</a>
|
|
</div>
|
|
|
|
{{-- Ampel-Karten --}}
|
|
<div class="row mb-4">
|
|
<div class="col-md-4">
|
|
@php
|
|
$level = $stats['critical_open'] > 0 ? 'danger' : ($stats['open_incidents'] > 0 ? 'warning' : 'success');
|
|
$levelText = $stats['critical_open'] > 0 ? 'Kritische Störung!' : ($stats['open_incidents'] > 0 ? 'Offene Störungen' : 'Alles in Ordnung');
|
|
@endphp
|
|
<div class="card border-{{ $level }}">
|
|
<div class="card-body text-center py-4">
|
|
<i class="ion ion-md-{{ $level === 'success' ? 'checkmark-circle' : 'alert' }} text-{{ $level }}" style="font-size: 3rem"></i>
|
|
<h5 class="mt-2 text-{{ $level }}">{{ $levelText }}</h5>
|
|
<div class="display-4 font-weight-bold">{{ $stats['open_incidents'] }}</div>
|
|
<div class="text-muted">Offene Störungen</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card {{ $transactionStats['failed'] > 0 ? 'border-warning' : '' }}">
|
|
<div class="card-body text-center py-4">
|
|
<i class="ion ion-md-card text-{{ $transactionStats['success_rate'] >= 95 ? 'success' : ($transactionStats['success_rate'] >= 80 ? 'warning' : 'danger') }}" style="font-size: 3rem"></i>
|
|
<h5 class="mt-2">Zahlungsquote</h5>
|
|
<div class="display-4 font-weight-bold text-{{ $transactionStats['success_rate'] >= 95 ? 'success' : ($transactionStats['success_rate'] >= 80 ? 'warning' : 'danger') }}">
|
|
{{ $transactionStats['success_rate'] }}%
|
|
</div>
|
|
<div class="text-muted">
|
|
{{ $transactionStats['failed'] }} fehlgeschlagen (30 Tage)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card">
|
|
<div class="card-body text-center py-4">
|
|
<i class="ion ion-md-cash text-info" style="font-size: 3rem"></i>
|
|
<h5 class="mt-2">Betroffener Umsatz</h5>
|
|
<div class="display-4 font-weight-bold text-{{ $stats['total_affected_revenue'] > 0 ? 'warning' : 'success' }}">
|
|
{{ number_format($stats['total_affected_revenue'], 0, ',', '.') }} €
|
|
</div>
|
|
<div class="text-muted">bei offenen Incidents</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Anbieter-Status --}}
|
|
<div class="card mb-4">
|
|
<h6 class="card-header">Anbieter-Status</h6>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
@foreach($providerStats as $key => $provider)
|
|
<div class="col-sm-6 col-md-3 text-center mb-3">
|
|
<div class="h5 mb-1">{{ $provider['label'] }}</div>
|
|
@if($provider['open_incidents'] > 0)
|
|
<span class="badge badge-danger badge-pill" style="font-size:1rem; padding: 0.5rem 1rem">
|
|
<i class="ion ion-md-alert"></i> {{ $provider['open_incidents'] }} Störung(en)
|
|
</span>
|
|
@else
|
|
<span class="badge badge-success badge-pill" style="font-size:1rem; padding: 0.5rem 1rem">
|
|
<i class="ion ion-md-checkmark"></i> OK
|
|
</span>
|
|
@endif
|
|
<div class="text-muted small mt-1">{{ $provider['total_30d'] }} Incidents (30d)</div>
|
|
@if(isset($transactionStats['providers'][$key]))
|
|
<div class="text-muted small">
|
|
Zahlungsquote: <strong>{{ $transactionStats['providers'][$key]['success_rate'] }}%</strong>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Abos je Provider (Auslauf-Fortschritt) --}}
|
|
@include('admin.payment-dashboard._partials.abo-provider-stats')
|
|
|
|
{{-- Aktive Störungen --}}
|
|
@if($openIncidents->count() > 0)
|
|
<div class="card mb-4 border-danger">
|
|
<h6 class="card-header bg-danger text-white">
|
|
<i class="ion ion-md-alert"></i> Aktive Störungen ({{ $openIncidents->count() }})
|
|
</h6>
|
|
<div class="card-body p-0">
|
|
@include('admin.payment-dashboard._partials.incident-table', [
|
|
'incidents' => $openIncidents,
|
|
'showActions' => false,
|
|
])
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Letzte Vorfälle --}}
|
|
<div class="card">
|
|
<h6 class="card-header">Letzte Vorfälle</h6>
|
|
<div class="card-body p-0">
|
|
@include('admin.payment-dashboard._partials.incident-table', [
|
|
'incidents' => $recentIncidents,
|
|
'showActions' => false,
|
|
])
|
|
</div>
|
|
</div>
|
|
|
|
@endsection
|