HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/be.naniguide.com/app/Http/Controllers/Refactor/Admin/PaymentGatewayController.php
<?php

namespace App\Http\Controllers\Refactor\Admin;

use App\Http\Controllers\Controller;
use App\Library\Facades\Billing;
use App\Model\PaymentGateway;
use App\Model\Setting;
use Illuminate\Http\Request;

class PaymentGatewayController extends Controller
{
    public function index(Request $request)
    {
        if (!$request->user()->admin->can('read', new PaymentGateway())) {
            return $this->notAuthorized();
        }

        $query = PaymentGateway::query()->global();

        $stats = [
            'total' => (clone $query)->count(),
            'active' => (clone $query)->where('status', PaymentGateway::STATUS_ACTIVE)->count(),
            'inactive' => (clone $query)->where('status', PaymentGateway::STATUS_INACTIVE)->count(),
        ];

        // Category distribution by capability (remote-subscription vs direct charge).
        // Plugins implementing RemoteSubscriptionGatewayInterface automatically bucket
        // into "remote" — no type-string hardcoding here.
        $globals = (clone $query)->get();
        $remoteCount = $globals->filter(fn ($gw) => Billing::supportsRemoteSubscription($gw))->count();
        $categoryDistribution = [
            'direct' => $globals->count() - $remoteCount,
            'remote' => $remoteCount,
        ];

        return view('refactor.pages.admin.payment-gateways.index', compact('stats', 'categoryDistribution'));
    }

    public function listing(Request $request)
    {
        if (!$request->user()->admin->can('read', new PaymentGateway())) {
            return response('Unauthorized', 403);
        }

        $query = PaymentGateway::query()->global();
        if ($request->keyword) {
            $keyword = '%' . strtolower(trim($request->keyword)) . '%';
            $query->where(function ($q) use ($keyword) {
                $q->whereRaw('LOWER(name) LIKE ?', [$keyword])
                  ->orWhereRaw('LOWER(description) LIKE ?', [$keyword]);
            });
        }

        // Type filter
        if ($request->type && $request->type !== 'all') {
            $query = $query->where('type', $request->type);
        }

        // Status filter
        if ($request->status && $request->status !== 'all') {
            $query = $query->where('status', $request->status);
        }

        $sortBy = $request->sort_by ?? 'payment_gateways.created_at';
        $sortDir = $request->sort_direction ?? 'desc';
        $query = $query->orderBy($sortBy, $sortDir);

        $items = $query->paginate($request->per_page ?? 15);

        return view('refactor.pages.admin.payment-gateways._list', compact('items'));
    }

    public function selectType(Request $request)
    {
        if (!$request->user()->admin->can('create', PaymentGateway::class)) {
            return $this->notAuthorized();
        }

        $gatewayServices = Billing::getGateways();

        return view('refactor.pages.admin.payment-gateways.select-type', compact('gatewayServices'));
    }

    public function create(Request $request, $type)
    {
        if (!$request->user()->admin->can('create', PaymentGateway::class)) {
            return $this->notAuthorized();
        }

        $paymentGateway = PaymentGateway::newDefault($type);
        $gatewayServices = Billing::getGateways();
        $gatewayService = $gatewayServices[$type] ?? null;

        if (!$gatewayService) {
            abort(404);
        }

        return view('refactor.pages.admin.payment-gateways.create', compact('paymentGateway', 'gatewayService'));
    }

    public function store(Request $request, $type)
    {
        if (!$request->user()->admin->can('create', PaymentGateway::class)) {
            return $this->notAuthorized();
        }

        $paymentGateway = PaymentGateway::newDefault($type);

        $validator = $paymentGateway->savePaymentGateway(
            $request->name,
            $request->description,
            $request->gateway_data
        );

        if ($validator->fails()) {
            $gatewayServices = Billing::getGateways();
            $gatewayService = $gatewayServices[$type];

            return response()->view('refactor.pages.admin.payment-gateways.create', [
                'paymentGateway' => $paymentGateway,
                'gatewayService' => $gatewayService,
                'errors' => $validator->errors(),
            ], 400);
        }

        $request->session()->flash('alert-success', trans('refactor/admin_payment_gateways.flash.created'));

        return redirect()->route('refactor.admin.payment-gateways.index');
    }

    public function edit(Request $request, $uid)
    {
        $paymentGateway = PaymentGateway::global()->where('uid', $uid)->first();
        if (!$paymentGateway) {
            abort(404);
        }

        if (!$request->user()->admin->can('update', $paymentGateway)) {
            return $this->notAuthorized();
        }

        $gatewayServices = Billing::getGateways();
        $gatewayService = $gatewayServices[$paymentGateway->type] ?? null;

        return view('refactor.pages.admin.payment-gateways.edit', compact('paymentGateway', 'gatewayService'));
    }

    public function update(Request $request, $uid)
    {
        $paymentGateway = PaymentGateway::global()->where('uid', $uid)->first();
        if (!$paymentGateway) {
            abort(404);
        }

        if (!$request->user()->admin->can('update', $paymentGateway)) {
            return $this->notAuthorized();
        }

        $validator = $paymentGateway->savePaymentGateway(
            $request->name,
            $request->description,
            $request->gateway_data
        );

        if ($validator->fails()) {
            $gatewayServices = Billing::getGateways();
            $gatewayService = $gatewayServices[$paymentGateway->type];

            return response()->view('refactor.pages.admin.payment-gateways.edit', [
                'paymentGateway' => $paymentGateway,
                'gatewayService' => $gatewayService,
                'errors' => $validator->errors(),
            ], 400);
        }

        $request->session()->flash('alert-success', trans('refactor/admin_payment_gateways.flash.updated'));

        return redirect()->route('refactor.admin.payment-gateways.index');
    }

    public function enable(Request $request)
    {
        $items = PaymentGateway::global()->whereIn(
            'uid',
            is_array($request->uids) ? $request->uids : explode(',', $request->uids)
        );

        foreach ($items->get() as $item) {
            if ($request->user()->admin->can('enable', $item)) {
                $item->enable();
            }
        }

        echo trans('refactor/admin_payment_gateways.flash.enabled');
    }

    public function disable(Request $request)
    {
        $items = PaymentGateway::global()->whereIn(
            'uid',
            is_array($request->uids) ? $request->uids : explode(',', $request->uids)
        );

        foreach ($items->get() as $item) {
            if ($request->user()->admin->can('disable', $item)) {
                $item->disable();
            }
        }

        echo trans('refactor/admin_payment_gateways.flash.disabled');
    }

    public function delete(Request $request)
    {
        $items = PaymentGateway::global()->whereIn(
            'uid',
            is_array($request->uids) ? $request->uids : explode(',', $request->uids)
        );

        // Surface any persistence/business error verbatim instead of 500. The
        // FK on payment_intents.payment_gateway_id used to be RESTRICT — a
        // gateway with historical intents would throw SQL 1451 which Konstantin
        // saw as a generic "server error". Migration 2026_05_14_140000 relaxed
        // that to nullOnDelete; this catch covers any remaining FK on a child
        // table we may have missed and keeps the response shape predictable.
        try {
            foreach ($items->get() as $item) {
                if ($request->user()->admin->can('delete', $item)) {
                    $item->delete();
                }
            }
        } catch (\Throwable $e) {
            \Log::warning('admin.payment-gateways.delete failed', [
                'admin_uid' => $request->user()->admin->uid ?? null,
                'uids'      => $request->uids,
                'error'     => $e->getMessage(),
            ]);
            return response()->json([
                'status'  => 'error',
                'message' => trans('refactor/admin_payment_gateways.flash.delete_failed', ['reason' => $e->getMessage()]),
            ], 422);
        }

        echo trans('refactor/admin_payment_gateways.flash.deleted');
    }

    public function testConnection(Request $request, $uid)
    {
        $paymentGateway = PaymentGateway::global()->where('uid', $uid)->first();
        if (!$paymentGateway) {
            abort(404);
        }

        try {
            $service = Billing::resolveService($paymentGateway);

            if ($service instanceof \App\Cashier\Contracts\RemoteSubscriptionGatewayInterface) {
                $plans = app(\App\Services\Subscription\SubscriptionManagementService::class)
                    ->fetchRemotePlans($paymentGateway);
                return response()->json([
                    'status' => 'success',
                    'message' => trans('refactor/admin_payment_gateways.test_connection.success_remote', ['count' => count($plans)]),
                ]);
            }

            if (method_exists($service, 'isActive') && $service->isActive()) {
                return response()->json([
                    'status' => 'success',
                    'message' => trans('refactor/admin_payment_gateways.test_connection.success'),
                ]);
            }

            return response()->json([
                'status' => 'error',
                'message' => trans('refactor/admin_payment_gateways.test_connection.not_active'),
            ], 400);
        } catch (\Throwable $e) {
            return response()->json([
                'status' => 'error',
                'message' => trans('refactor/admin_payment_gateways.test_connection.failed', ['error' => $e->getMessage()]),
            ], 400);
        }
    }

    public function settings(Request $request)
    {
        if ($request->user()->admin->getPermission('setting_general') != 'yes') {
            return $this->notAuthorized();
        }

        return view('refactor.pages.admin.payment-gateways.settings');
    }

    public function settingsSave(Request $request)
    {
        if ($request->user()->admin->getPermission('setting_general') != 'yes') {
            return $this->notAuthorized();
        }

        $this->validate($request, [
            'auto_billing_period' => 'required',
            'grace_period' => 'required|integer|min:0',
        ]);

        Setting::set('grace_period', $request->grace_period);
        Setting::set('subscription.auto_billing_period', $request->auto_billing_period);

        $request->session()->flash('alert-success', trans('refactor/admin_payment_gateways.flash.settings_updated'));

        return redirect()->route('refactor.admin.payment-gateways.settings');
    }
}