/home/kueuepay/public_html/app/Http/Controllers/User/CardController.php
<?php

namespace App\Http\Controllers\User;

use Exception;
use Carbon\Carbon;
use App\Models\Card;
use Illuminate\Support\Str;
use App\Constants\CardConst;
use Illuminate\Http\Request;
use App\Http\Helpers\Response;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;

class CardController extends Controller
{
    /**
     * Method for payment page
     * @return view
     */
    public function index(){
        $page_title     = "Save Cards";
        $cards          = Card::auth()->orderBy('id','desc')->get();

        return view('user.sections.card.index',compact(
            'page_title',
            'cards'
        ));
    }
    /**
     * Method for store payment information 
     * @param \Illuminate\Http\Request $request
     */
    public function store(Request $request){
        $validator = Validator::make($request->all(), [
            'name'        => 'required',
            'card_number' => 'required',
            'card_cvc'    => 'required|min:3|max:4',
            'expiry_date' => 'required|min:7|max:7',
        ]);

        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput()->with('modal', true);
        }

        $validated = $validator->validate();

        // Remove spaces in card number and hash it for uniqueness check
        $card_number_cleaned = str_replace(' ', '', $validated['card_number']);
        if(strlen($card_number_cleaned) < 15 || strlen($card_number_cleaned) > 19){
            return back()->with(['error' => ['Card number must be between 15 to 19 digits.']]);
        }
        $card_number_hash = hash('sha256', $card_number_cleaned);

        // Check if the card number hash already exists for this user
        if (Card::where('user_id', auth()->user()->id)
                ->where('card_number_hash', $card_number_hash)
                ->exists()) {
            throw ValidationException::withMessages([
                'card_number' => "This card number has already been added by you!",
            ]);
        }

        // Continue with validation for expiry date
        $exp_date = explode("/", $request->expiry_date);
        $month_data = str_replace(' ', '', $exp_date[0]);
        $year_data = str_replace(' ', '', $exp_date[1]);

        if ($month_data > 12) {
            return back()->with(['error' => ['Invalid Month.']]);
        }

        $current_month = Carbon::now()->format('m');
        $current_year = Carbon::now()->format('y');
        if ($current_year > $year_data) {
            return back()->with(['error' => ['Invalid Year.']]);
        }
        if ($current_month > $month_data && $current_year == $year_data) {
            return back()->with(['error' => ['Month expired.']]);
        }

        // Encrypt sensitive data
        $validated['user_id']   = auth()->user()->id;
        $expiry_date = $month_data.'/'.$year_data;
        $validated['expiry_date'] = encrypt($expiry_date);
        $validated['type'] = CardConst::LIVE;
        $validated['slug'] = Str::uuid();
        $validated['name'] = encrypt($validated['name']);
        $validated['card_number'] = encrypt($card_number_cleaned);
        $validated['card_cvc'] = encrypt($validated['card_cvc']);
        $validated['card_number_hash'] = $card_number_hash;

        try {
            Card::create($validated);
        } catch (Exception $e) {
            return back()->with(['error' => ['Something went wrong! Please try again.']]);
        }

        return back()->with(['success' => ['Card method created successfully.']]);
    }
    /**
     * Method for make default card
     */
    public function makeDefault(Request $request,$slug){
        $cards      = Card::auth()->where('slug','!=', $slug)->get();
        if($cards->count() != 0){
            foreach($cards ?? [] as $card){
                try{
                    $card->update([
                        'default'    => false,
                    ]);
                }catch(Exception $e){
                    return back()->with(['error' => ['Something went wrong! Please try again.']]);
                }
            }
        }
        $card       = Card::auth()->where('slug',$slug)->first();
        if(!$card) return back()->with(['error' => ['Card not found!']]);
        try{
            $card->update([
                'default'   => true
            ]);
        }catch(Exception $e){
            return back()->with(['error' => ['Something went wrong! Please try again.']]);
        }
        return back()->with(['success' => ['Card status updated.']]);
    }
    /**
     * Method for delete card payment information
     * @param $slug
     * @param \Illuminate\Http\Request $request
     */
    public function delete($slug){
        $card   = Card::where('slug',$slug)->first();
        if(!$card) return back()->with(['error' => ['Sorry! Card not found.']]);
        try{
            $card->delete();
        }catch(Exception $e){
            return back()->with(['error' => ['Something went wrong! Please try again.']]);
        }
        return back()->with(['success' => ['Card method deleted successfully.']]);
    }
    /**
     * Method for search card payment data
     */
    public function search(Request $request){
        
        $validator      = Validator::make($request->all(),[
            'text'      => 'required'
        ]);
        if($validator->fails()) {
            $error = ['error' => $validator->errors()];
            return Response::error($error,null,400);
        }

        $validated = $validator->validate();
        
        $cards    = Card::auth()->search($validated['text'])->get();
        return view('user.components.card-table.card',compact('cards'));
    }
}
Forgot Password