@extends('dashboard.app') @section('title', 'Billing') @section('page_title', 'Billing') @section('page_subtitle', 'Subscription status and plan details.') @section('dashboard_content') @php $user = $user ?? auth()->user(); $subscription = $subscription ?? null; $hasSub = $subscription !== null; $orders = $orders ?? collect(); $payments = $payments ?? collect(); $currentPlan = (string) ($subscription->plan ?? ($user?->tier === 'personal' ? 'personal_monthly' : 'free')); $hasPendingPayment = $payments->contains(fn ($payment) => (string) ($payment->status ?? '') === 'pending'); $pendingCooldownWindow = (int) config('dewemoji.billing.pending_cooldown_seconds', 120); $latestPendingPayment = $payments->first(fn ($payment) => (string) ($payment->status ?? '') === 'pending'); $pendingCooldownRemaining = 0; if ($latestPendingPayment?->created_at && $pendingCooldownWindow > 0) { $age = max(0, now()->getTimestamp() - $latestPendingPayment->created_at->getTimestamp()); $pendingCooldownRemaining = max(0, $pendingCooldownWindow - $age); } $formatPlan = function (?string $code): string { $value = (string) ($code ?? ''); return match ($value) { 'personal_monthly' => 'Personal Monthly', 'personal_annual' => 'Personal Annual', 'personal_lifetime' => 'Personal Lifetime', 'free' => 'Free', '' => 'Free', default => \Illuminate\Support\Str::of($value)->replace('_', ' ')->title(), }; }; @endphp
Plan
{{ $hasSub ? $formatPlan($subscription->plan ?? 'Personal') : 'Free' }}
{{ $hasSub ? ucfirst($subscription->status ?? 'active') : 'No subscription' }}
Renewal
{{ $subscription?->next_renewal_at?->toDateString() ?? '—' }}
Next charge date
Status
{{ $subscription?->expires_at?->toDateString() ?? 'Active' }}
Access ends
Billing summary
Subscription details
Current cycle
@if ($hasSub) Provider: {{ $subscription->provider ?? 'direct' }} · Started {{ $subscription->started_at?->toDateString() }} @else You are on the free plan. Upgrade to unlock private keywords and sync. @endif
Downgrading to Free revokes any active API keys immediately.
@if ($hasPendingPayment)
You have a pending checkout. Use Pay in the table below to continue the same payment. @if ($pendingCooldownRemaining > 0) New checkout unlocks in {{ $pendingCooldownRemaining }}s. @endif
@endif
Payment method
Card
Coming soon
Invoices
0
Billing history
Change plan

Plan change policy: when your new payment is confirmed, Dewemoji cancels the previous recurring plan automatically. No prorated refund is applied.

@if (in_array($currentPlan, ['personal_monthly', 'personal_annual'], true)) @if ($currentPlan === 'personal_monthly') Switch to Annual @endif @if ($currentPlan === 'personal_annual') Switch to Monthly @endif Upgrade to Lifetime @elseif ($currentPlan === 'personal_lifetime') Lifetime active @else Choose Personal Plan @endif
@if ($payments->count() > 0)
Recent payments
@foreach ($payments as $payment) @php $status = $payment->status ?? 'pending'; $pill = $status === 'paid' ? ['bg' => 'bg-emerald-100 dark:bg-emerald-500/20', 'text' => 'text-emerald-800 dark:text-emerald-200'] : ($status === 'failed' ? ['bg' => 'bg-rose-100 dark:bg-rose-500/20', 'text' => 'text-rose-800 dark:text-rose-200'] : ['bg' => 'bg-amber-100 dark:bg-amber-500/20', 'text' => 'text-amber-800 dark:text-amber-200']); @endphp @endforeach
Provider Plan Amount Status Created Action
{{ $payment->provider ?? '—' }} {{ $formatPlan($payment->plan_code) }} {{ $payment->currency ?? 'USD' }} {{ number_format((float) ($payment->amount ?? 0), 2) }} {{ $status }} {{ $payment->created_at?->toDateString() ?? '—' }} @if ($status === 'pending') @else @endif
@if ($payments->contains(fn ($payment) => in_array($payment->status, ['pending', 'failed'], true)))
Failed payments need a new checkout. Pending payments can be continued from the table using the Pay action.
Start new checkout @endif
@endif @if (!$hasSub || (string) $user?->tier !== 'personal')
Upgrade to Personal for private keywords and synced personalization.
Upgrade to Personal @endif
@endsection @push('scripts') @endpush