@extends('backend.layout.master-tailwind') @section('title', __('Payments')) @section('breadcrumb_section', 'Marketplace') @section('breadcrumb_page', __('Payments')) @section('admin_styles') @endsection @section('content') @php // ── Formatters ─────────────────────────────────────────────────────────────── $fmt = function($v) { if ($v >= 1_000_000) return '$' . number_format($v / 1_000_000, 1) . 'M'; if ($v >= 1_000) return '$' . number_format($v / 1_000, 1) . 'K'; return '$' . number_format($v, 0); }; $fmtFull = function($v) { return '$' . number_format((float)$v, 0); }; $delta = function($cur, $prev) { if ($prev == 0) return ['val' => '—', 'dir' => '']; $pct = round(($cur - $prev) / abs($prev) * 100, 1); return ['val' => ($pct >= 0 ? '↑ ' : '↓ ') . abs($pct) . '%', 'dir' => $pct >= 0 ? 'up' : 'down']; }; $deltaAbs = function($cur, $prev) { $diff = $cur - $prev; return ['val' => ($diff >= 0 ? '↑ ' : '↓ ') . abs($diff) . ' items', 'dir' => $diff >= 0 ? 'up' : 'down']; }; $deltaPp = function($cur, $prev) { $diff = round($cur - $prev, 2); return ['val' => ($diff >= 0 ? '↑ ' : '↓ ') . abs($diff) . 'pp', 'dir' => $diff >= 0 ? 'up' : 'down']; }; // ── Sparkline SVG ──────────────────────────────────────────────────────────── $sfn = function($pts, $w, $h) { $pts = array_values($pts); $max = count($pts) ? max($pts) : 0; if (!$max) { return ''; } $n = count($pts); $step = $n > 1 ? $w / ($n - 1) : $w; $pad = 4; $coords = []; foreach ($pts as $i => $v) { $x = round($i * $step, 1); $y = round($h - $pad - ($v / $max) * ($h - $pad * 2), 1); $coords[] = "$x $y"; } $line = 'M' . implode(' L', $coords); $fill = $line . ' L' . $w . ' ' . $h . ' L0 ' . $h . ' Z'; $id = 'pay-cf-' . substr(md5(implode(',', array_map('intval', $pts))), 0, 6); return '' . '' . '' . '' . '' . ''; }; // ── Transaction type config ─────────────────────────────────────────────────── $typeConf = [ 'escrow_funded' => ['color' => 'var(--info)', 'label' => __('Escrow funded')], 'milestone_release' => ['color' => 'var(--success)', 'label' => __('Milestone release')], 'payout' => ['color' => 'var(--success)', 'label' => __('Payout')], 'refund' => ['color' => 'var(--warn)', 'label' => __('Refund')], 'subscription' => ['color' => 'var(--text-dim)', 'label' => __('Subscription')], 'chargeback' => ['color' => 'var(--danger)', 'label' => __('Chargeback')], ]; // ── State tag + state key ───────────────────────────────────────────────────── $resolveState = function($tx) { if (in_array((int)$tx->order_status, [6, 7]) || $tx->tx_type === 'chargeback') return 'flagged'; if ($tx->payment_status === 'complete') return 'cleared'; if ($tx->payment_status === 'cancel') return 'cancelled'; return 'processing'; }; $stateTag = function($state) { $map = [ 'cleared' => '' . __('Cleared') . '', 'processing' => '' . __('Processing') . '', 'flagged' => '' . __('Flagged') . '', 'cancelled' => '' . __('Cancelled') . '', ]; return $map[$state] ?? $map['processing']; }; // ── Gateway display name ────────────────────────────────────────────────────── $gwLabel = function($raw) { $map = [ 'stripe' => 'Stripe', 'paypal' => 'PayPal', 'bank_transfer' => 'Wire', 'ach' => 'ACH', 'wise' => 'Wise', 'sepa' => 'SEPA', 'manual' => 'Manual', ]; return $map[strtolower($raw ?? '')] ?? ucfirst($raw ?? '—'); }; // ── Deltas ─────────────────────────────────────────────────────────────────── $dProcessed = $delta($processedToday, $processedYest); $dPayouts = $deltaAbs($pendingPayoutsCount, $pendingPayoutsCountPrev); $dEscrow = $delta($escrowNew, $escrowPrev); $dFailure = $deltaPp($failureRate, $failureRatePrev); $dCashFlow = $delta($cashFlowTotal, $cashFlowPrevTotal); // ── Payout bar colours ──────────────────────────────────────────────────────── $barColors = [ 'var(--accent)', 'color-mix(in oklch, var(--accent) 70%, white)', 'color-mix(in oklch, var(--accent) 50%, white)', 'color-mix(in oklch, var(--accent) 30%, white)', 'var(--text-dim)', ]; @endphp

{{ __('Payments') }}

{{ __('All escrow, payouts, refunds, and subscription transactions') }}

{{-- KPIs --}}
{{ __('Processed today') }}
{{ $fmt($processedToday) }}
{{ $dProcessed['val'] }} {{ __('vs yesterday') }}
{{ __('Pending payouts') }}
{{ $fmt($pendingPayoutsAmt) }}
{{ $dPayouts['val'] }} {{ __('vs yesterday') }}
{{ __('Held in escrow') }}
{{ $fmt($heldEscrow) }}
{{ $dEscrow['val'] }} {{ __('new this week') }}
{{ __('Failure rate (7d)') }}
{{ $failureRate }}%
{{ $dFailure['val'] }} {{ __('vs prev 7d') }}
{{-- Recent transactions --}}
{{ __('Recent transactions') }}
{{-- Type filter --}}
{{ __('Type') }}
{{ __('Type') }}
@foreach($typeConf as $typeKey => $tc) @endforeach
{{-- State filter --}}
{{ __('State') }}
{{ __('State') }}
@foreach(['cleared' => ['tag'=>'success','label'=>__('Cleared')], 'processing' => ['tag'=>'warn','label'=>__('Processing')], 'flagged' => ['tag'=>'danger','label'=>__('Flagged')], 'cancelled' => ['tag'=>'','label'=>__('Cancelled')]] as $stateKey => $sc) @endforeach
{{-- Sort --}}
@forelse($transactions as $tx) @php $conf = $typeConf[$tx->tx_type] ?? ['color' => 'var(--text-dim)', 'label' => $tx->tx_type]; $prefix = $tx->direction ? $tx->direction . ' ' : ''; $fee = (float)$tx->fee; $net = (float)$tx->net; $txState = $resolveState($tx); @endphp @empty @endforelse
{{ __('ID') }} {{ __('Time') }} {{ __('Type') }} {{ __('Counterparty') }} {{ __('Method') }} {{ __('Amount') }} {{ __('Fee') }} {{ __('Net') }} {{ __('State') }}
{{ $tx->tx_id }} {{ date('H:i', strtotime($tx->tx_time)) }} {{ $conf['label'] }} {{ $prefix }}{{ $tx->counterparty }} {{ $gwLabel($tx->method) }} {{ $fmtFull($tx->amount) }} {{ $fee > 0 ? $fmtFull($fee) : '—' }} {{ $fmtFull($net) }} {!! $stateTag($txState) !!}
{{ __('No transactions yet') }}
{{-- No-results row (shown by JS when filters exclude everything) --}}
{{-- Right column --}}
{{ __('Cash flow (7d)') }}
{{ $fmt($cashFlowTotal) }} {{ $dCashFlow['val'] }}
{!! $sfn($cashFlowPoints, 280, 64) !!}
{{ __('Payout methods') }}
@forelse($payoutMethods as $i => $gw) @php $pct = $payoutTotal > 0 ? round($gw->total / $payoutTotal * 100) : 0; @endphp
{{ $gw->gateway_name }}
{{ $pct }}%
@empty

{{ __('No completed payouts yet') }}

@endforelse
{{ __('Risk flags') }}
{{ __('Velocity spikes') }} {{ $velocitySpikes }}
{{ __('Chargebacks (7d)') }} {{ $chargebacks7d }}
{{ __('High-value new users (7d)') }} {{ $amlHighRisk }}
@endsection @section('script') @endsection