label('Process Refund') ->icon(Heroicon::OutlinedReceiptRefund) ->color('danger') ->visible(fn (): bool => auth()->user()?->can('process_refunds') ?? false) ->schema([ Select::make('payment_id') ->label('Payment') ->options(fn () => Payment::query() ->where('status', PaymentStatus::Completed->value) ->with('booking') ->get() ->mapWithKeys(fn (Payment $payment) => [ $payment->id => "{$payment->booking?->booking_ref} — {$payment->amount} {$payment->currency} (#{$payment->id})", ])) ->searchable() ->required(), TextInput::make('amount') ->numeric() ->minValue(0.01) ->required(), Textarea::make('reason') ->required(), ]) ->action(function (array $data): void { $payment = Payment::with('booking')->findOrFail($data['payment_id']); try { app(RefundBookingAction::class)->handle( $payment->booking, (string) $data['amount'], $data['reason'], auth()->id(), ); Notification::make() ->title('Refund processed') ->success() ->send(); } catch (RefundNotAllowedException|RefundFailedException $exception) { Notification::make() ->title('Refund failed') ->body($exception->getMessage()) ->danger() ->send(); } }); } }