@php /** * Bucket gateways by region / type so the page isn't a 30-item dump. * Each row is shown under the FIRST matching category. "Other" is * the catch-all so a new driver never disappears off the page. */ $catMap = [ 'popular' => ['stripe', 'paypal', 'razorpay', 'paddle', 'square', 'braintree', 'mollie', 'authorize_net'], 'india' => ['razorpay', 'instamojo', 'cashfree', 'paytm', 'phonepe', 'payu'], 'asia' => ['xendit', 'midtrans', 'paytm', 'phonepe', 'sslcommerz', 'hyperpay', 'tap'], 'africa' => ['paystack', 'flutterwave', 'cinetpay'], 'latam' => ['mercadopago'], 'mena' => ['hyperpay', 'tap', 'paytr', 'iyzico', 'fondy'], 'europe' => ['mollie', 'paddle', 'stripe', 'paytr', 'iyzico', 'fondy'], 'us' => ['stripe', 'paypal', 'square', 'braintree', 'authorize_net', 'twocheckout'], 'crypto' => ['coinbase'], 'offline' => ['offline', 'bank_transfer'], ]; $catLabels = [ 'all' => ['All', 'Every gateway available'], 'popular' => ['Popular', 'The big global ones — Stripe / PayPal / Razorpay etc.'], 'india' => ['India', 'Razorpay, Paytm, PhonePe, Cashfree, PayU, Instamojo'], 'asia' => ['Asia', 'Xendit, Midtrans, SSLCommerz, HyperPay, Tap'], 'mena' => ['MENA', 'HyperPay, Tap, PayTR, iyzico, Fondy'], 'europe' => ['Europe', 'Mollie, Paddle, Stripe, regional'], 'us' => ['US / CA', 'Stripe, PayPal, Square, Braintree, Authorize.Net, 2Checkout'], 'africa' => ['Africa', 'Paystack, Flutterwave, CinetPay'], 'latam' => ['LATAM', 'Mercado Pago'], 'crypto' => ['Crypto', 'Coinbase Commerce'], 'offline' => ['Offline', 'Bank transfer / cash on delivery'], ]; // Compute counts + per-card category-list for filter $catCounts = ['all' => $gateways->count()]; foreach ($catMap as $cat => $slugs) { $catCounts[$cat] = $gateways->filter(fn($g) => in_array($g->slug, $slugs, true))->count(); } // For each gateway, the list of categories it belongs to (used as data-cat="…") $gatewayCats = $gateways->mapWithKeys(function ($g) use ($catMap) { $cats = ['all']; foreach ($catMap as $cat => $slugs) { if (in_array($g->slug, $slugs, true)) { $cats[] = $cat; } } // Catch-all "other" so a new gateway slug never disappears if (count($cats) === 1) { $cats[] = 'other'; } return [$g->id => $cats]; }); $activeCount = $gateways->where('is_active', true)->count(); @endphp
{{ __('Admin') }} {{ __('Payment gateways') }}
{{ __('Admin · Billing · Gateways') }}

{{ __('Payment') }} {{ __('gateways') }}

{{ $gateways->count() }} drivers shipped — split by region / type so you only fill in the ones your customers will actually use. Credentials encrypted at rest. Workspaces only see gateways that accept their currency.

@if (session('success'))
{{ session('success') }}
@endif @if (session('error'))
{{ session('error') }}
@endif {{-- KPI strip --}}
{{ __('Total') }}
{{ $gateways->count() }}
{{ __('drivers available') }}
{{ __('Active') }}
{{ $activeCount }}
{{ __('accepting payments') }}
{{ __('India region') }}
{{ $catCounts['india'] ?? 0 }}
{{ __('Razorpay, Paytm, Cashfree…') }}
{{ __('Crypto') }}
{{ $catCounts['crypto'] ?? 0 }}
{{ __('on-chain settlement') }}
{{-- Category tabs + search --}}
@foreach ($catLabels as $key => [$label, $hint]) @endforeach
{{-- Gateway cards (server renders ALL; client filters via data-cat + data-search). Each card is COLLAPSED by default — only the header row is visible. Click the header to expand the credentials form (SnapNest pattern). --}} @forelse ($gateways as $g)

{{ $g->name }}

{{ $g->is_active ? 'Active' : 'Disabled' }} {{ $g->mode }} @php $hasCreds = !empty(array_filter($g->credentials_decrypted ?? [])); @endphp @if ($hasCreds) {{ __('Keys saved') }} @endif @foreach (array_slice(array_filter($gatewayCats[$g->id] ?? [], fn($c) => $c !== 'all'), 0, 3) as $cat) {{ $catLabels[$cat][0] ?? $cat }} @endforeach
slug: {{ $g->slug }}{{ $g->description ? ' · ' . $g->description : '' }}
@csrf
{{-- Chevron flips on expand. transition handled by Tailwind. --}}
@empty
{{ __('No payment gateways found') }}

{{ __('Run') }} php artisan db:seed --class=PaymentGatewaySeeder.

@endforelse
{{-- Tabs + search + collapsible cards are wired by resources/js/charts/admin-payment-gateways-index.js, auto-loaded by app.js when page="admin-payment-gateways-index". No inline JS. --}}