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/ai.naniguide.com/app/Http/Controllers/Refactor/CheckoutController.php
<?php

namespace App\Http\Controllers\Refactor;

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

class CheckoutController extends Controller
{
    protected function findOwnedInvoice(Request $request, string $invoiceUid): ?Invoice
    {
        $customer = $request->user()->customer;

        return $customer->invoices()->where('invoices.uid', $invoiceUid)->first();
    }

    protected function findOwnedPaymentMethod(Request $request, string $paymentMethodUid): ?PaymentMethod
    {
        $customer = $request->user()->customer;

        return $customer->paymentMethods()->where('payment_methods.uid', $paymentMethodUid)->first();
    }

    public function cart(Request $request, $invoice_uid)
    {
        $invoice = $this->findOwnedInvoice($request, $invoice_uid);

        if (!$invoice) {
            return redirect()->route('refactor.account.subscription');
        }

        return view('refactor.pages.checkout.cart', compact('invoice'));
    }

    public function billingAddress(Request $request, $invoice_uid)
    {
        $customer = $request->user()->customer;
        $invoice = $this->findOwnedInvoice($request, $invoice_uid);

        if (!$invoice) {
            return redirect()->route('refactor.account.subscription');
        }

        // Pre-fill from customer's default billing address
        $billingAddress = $customer->getDefaultBillingAddress();
        if ($billingAddress) {
            $invoice->fillBillingAddressNotReplace($billingAddress);
        }

        // Save posted data
        if ($request->isMethod('post')) {
            $validator = $invoice->updateBillingInformation($request->all());

            if ($validator->fails()) {
                return view('refactor.pages.checkout.billing_address', [
                    'invoice' => $invoice,
                    'errors' => $validator->errors(),
                ]);
            }

            // Update customer's default billing address for next time
            $customer->updateBillingInformationFromInvoice($invoice);

            return redirect()->route('refactor.checkout.payment', [
                'invoice_uid' => $invoice->uid,
            ]);
        }

        return view('refactor.pages.checkout.billing_address', compact('invoice'));
    }

    public function payment(Request $request, $invoice_uid)
    {
        $invoice = $this->findOwnedInvoice($request, $invoice_uid);

        if (!$invoice) {
            return redirect()->route('refactor.account.subscription');
        }

        if (!$invoice->hasBillingInformation()) {
            return redirect()->route('refactor.checkout.billing_address', [
                'invoice_uid' => $invoice->uid,
            ]);
        }

        return view('refactor.pages.checkout.payment', compact('invoice'));
    }

    public function checkout(Request $request, $invoice_uid)
    {
        $invoice = $this->findOwnedInvoice($request, $invoice_uid);

        if (!$invoice) {
            return redirect()->route('refactor.account.subscription');
        }

        if (!$invoice->hasBillingInformation()) {
            return redirect()->route('refactor.checkout.billing_address', [
                'invoice_uid' => $invoice->uid,
            ]);
        }

        // Always update invoice price from plan
        app(\App\Library\OrderFulfillment\FulfillmentService::class)->refreshPrice($invoice->order);

        // Set return URL based on order type
        $orderItemType = $invoice->order->orderItems->first()->type;
        switch ($orderItemType) {
            case \App\Library\OrderFulfillment\OrderItemTypes::SUBSCRIPTION_NEW:
            case \App\Library\OrderFulfillment\OrderItemTypes::SUBSCRIPTION_RENEW:
            case \App\Library\OrderFulfillment\OrderItemTypes::SUBSCRIPTION_CHANGE_PLAN:
                $returnUrl = route('refactor.account.subscription');
                break;
            case \App\Library\OrderFulfillment\OrderItemTypes::CREDIT_VERIFICATION_TOPUP:
                $returnUrl = route('refactor.account.email_verification_credits');
                break;
            case \App\Library\OrderFulfillment\OrderItemTypes::CREDIT_SENDING_TOPUP:
                $returnUrl = route('refactor.account.sending_credits');
                break;
            default:
                $returnUrl = route('refactor.account.subscription');
        }

        /*
        // Free plan — no charge needed
        if ($invoice->total() == 0) {
            $invoice->paySuccess();
            return redirect()->away($returnUrl);
        }
        */

        // Auto charge via saved payment method
        if ($request->payment_method_id) {
            $paymentMethod = $this->findOwnedPaymentMethod($request, $request->payment_method_id);
            if (!$paymentMethod) {
                return redirect()->route('refactor.checkout.payment', ['invoice_uid' => $invoice->uid])
                    ->with('alert-error', 'Payment method not found.');
            }
            app(\App\Services\Subscription\SubscriptionManagementService::class)
                ->autoChargeInvoice($invoice, $paymentMethod);
            return redirect()->away($returnUrl);
        }

        // Redirect to payment gateway checkout
        $paymentGateway = PaymentGateway::global()->where('uid', $request->payment_gateway_id)->first();

        // Guard: remote subscription gateways cannot process one-time invoice payments
        if (Billing::supportsRemoteSubscription($paymentGateway)) {
            return redirect()->route('refactor.checkout.payment', ['invoice_uid' => $invoice->uid])
                ->with('alert-error', trans('refactor/checkout.payment.gateway_not_supported'));
        } else {
            return redirect()->away(Billing::buildCheckoutUrl($paymentGateway, $invoice, $returnUrl));
        }
    }

    public function cancel(Request $request, $invoice_uid)
    {
        $invoice = $this->findOwnedInvoice($request, $invoice_uid);

        if (!$invoice) {
            return redirect()->route('refactor.account.subscription');
        }

        app(\App\Library\OrderFulfillment\FulfillmentService::class)->cancelInvoice($invoice);

        return redirect()->back();
    }
}