/home/kueuepay/public_html/app/Http/Controllers/Api/V1/User/Auth/AuthorizationController.php
<?php

namespace App\Http\Controllers\Api\V1\User\Auth;

use Exception;
use Illuminate\Http\Request;
use App\Constants\GlobalConst;
use App\Http\Helpers\Response;
use App\Models\Admin\SetupKyc;
use Illuminate\Support\Carbon;
use App\Models\UserAuthorization;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Traits\ControlDynamicInputFields;
use Illuminate\Support\Facades\Validator;
use App\Providers\Admin\BasicSettingsProvider;
use App\Notifications\User\Auth\SendAuthorizationCode;

class AuthorizationController extends Controller
{
    use ControlDynamicInputFields;

    public static function sendCodeToMail($user = null) {

        if(!$user && auth()->guard("api")->check() == false) throw new Exception(__("Access denied! Unauthenticated"));
        if(!$user) $user = auth()->guard("api")->user();

        $data = [
            'user_id'       => $user->id,
            'code'          => generate_random_code(),
            'token'         => generate_unique_string("user_authorizations","token",200),
            'created_at'    => now(),
        ];
    
        DB::beginTransaction();
        try{
            UserAuthorization::where("user_id",$user->id)->delete();
            DB::table("user_authorizations")->insert($data);
            $user->notify(new SendAuthorizationCode((object) $data));
            DB::commit();
        }catch(Exception $e) {
            DB::rollBack();
            throw new Exception(__("Something went wrong! Please try again"));
        }

        return $data;
    }

    public function resendCodeToMail(Request $request) {
        $validator = Validator::make($request->all(),[
            'token'     => "required|string|exists:user_authorizations,token"
        ]);
        if($validator->fails()) return Response::error($validator->errors()->all(),[]);
        $validated = $validator->validate();
        $user_authorize = UserAuthorization::where("token",$validated['token'])->first();

        if(!$user_authorize) return Response::error([__("Request token is invalid")],[],404);

        if(Carbon::now() <= $user_authorize->created_at->addMinutes(GlobalConst::USER_PASS_RESEND_TIME_MINUTE)) {
            return Response::error(['You can resend verification code after '.Carbon::now()->diffInSeconds($user_authorize->created_at->addMinutes(GlobalConst::USER_PASS_RESEND_TIME_MINUTE)). ' seconds'],['token' => $validated['token'], 'wait_time' => (string) Carbon::now()->diffInSeconds($user_authorize->created_at->addMinutes(GlobalConst::USER_PASS_RESEND_TIME_MINUTE))],400);
        }

        $resend_code = generate_random_code();
        try{
            $user_authorize->update([
                'code'          => $resend_code,
                'created_at'    => now(),
            ]);
            $data = $user_authorize->toArray();
            try{
                $user_authorize->user->notify(new SendAuthorizationCode((object) $data));
            }catch(Exception $e){}
            
        }catch(Exception $e) {
            return Response::error([__("Something went wrong! Please try again")],[],500);
        }

        return Response::success([__("Verification code resend successfully!")],['token' => $validated['token'],'wait_time' => ""],200);
    }

    public function verifyMailCode(Request $request) {
        $validator = Validator::make($request->all(),[
            'token'     => "required|string|exists:user_authorizations,token",
            'code'      => "required|integer",
        ]);
        if($validator->fails()) {
            return Response::error($validator->errors()->all(),[],400);
        }
        $validated = $validator->validate();

        if(!UserAuthorization::where("code",$request->code)->exists()) {
            return Response::error([__("Invalid OTP. Please try again")],[],404);
        }

        $otp_exp_sec = BasicSettingsProvider::get()->otp_exp_seconds ?? GlobalConst::DEFAULT_TOKEN_EXP_SEC;
        $auth_column = UserAuthorization::where("token",$request->token)->where("code",$request->code)->first();
        if($auth_column->created_at->addSeconds($otp_exp_sec) < now()) {
            $auth_column->delete();
            $this->authLogout($request);
            return Response::error([__("Session expired. Please try again")],[],440);
        }

        try{
            $auth_column->user->update([
                'email_verified'    => true,
            ]);
            $auth_column->delete();
        }catch(Exception $e) {
            $auth_column->delete();
            $this->authLogout($request);
            return Response::error([__("Something went wrong! Please try again")],[],500);
        }

        return Response::success([__("Account successfully verified")],[],200);
    }

    public function authLogout(Request $request) {
        $user_token = Auth::guard(get_auth_guard())->user()->token();
        $user_token->revoke();
    }

    // Get KYC Input Fields
    public function getKycInputFields() {
        $user = auth()->guard(get_auth_guard())->user();

        $user_kyc = SetupKyc::userKyc()->first();
        $kyc_data = $user_kyc->fields;
        $kyc_fields = array_reverse($kyc_data);

        $data = [
            'status_info'  => '0: Unverified, 1: Verified, 2: Pending, 3: Rejected',
            'kyc_status'   => $user->kyc_verified,
            'input_fields' => $kyc_fields
        ];

        if(!$user_kyc) return Response::success(['User KYC section is under maintenance'], $data);
        if($user->kyc_verified == GlobalConst::VERIFIED) return Response::success(['You are already KYC Verified User'], $data);
        if($user->kyc_verified == GlobalConst::PENDING) return Response::success(['Your KYC information is submitted. Please wait for admin confirmation'], $data);

        return Response::success(['User KYC input fields fetch successfully!'], $data);
    }

    public function KycSubmit(Request $request) {
        $user = auth()->guard(get_auth_guard())->user();

        if($user->kyc_verified == GlobalConst::VERIFIED) return Response::warning(['You are already KYC Verified User']);

        $user_kyc_fields = SetupKyc::userKyc()->first()->fields ?? [];
        $validation_rules = $this->generateValidationRules($user_kyc_fields);
        
        $validated = Validator::make($request->all(),$validation_rules)->validate();

        $get_values = $this->placeValueWithFields($user_kyc_fields,$validated);

        $create = [
            'user_id'       => auth()->guard(get_auth_guard())->user()->id,
            'data'          => json_encode($get_values),
            'created_at'    => now(),
        ];

        DB::beginTransaction();
        try{
            DB::table('user_kyc_data')->updateOrInsert(["user_id" => $user->id],$create);
            $user->update([
                'kyc_verified'  => GlobalConst::PENDING,
            ]);
            DB::commit();
        }catch(Exception $e) {
            DB::rollBack();
            $user->update([
                'kyc_verified'  => GlobalConst::DEFAULT,
            ]);
            $this->generatedFieldsFilesDelete($get_values);
            return Response::error(['KYC information successfully submitted']);
        }

       return Response::success(['KYC information successfully submitted'],[],200);
    }
    /**
     * Google 2FA Verification
     *
     * @method GET
     * @return \Illuminate\Http\Response
     */

     public function verify2FACode(Request $request) {

        $validator = Validator::make($request->all(), [
            'otp' => 'required',
        ]);

        if($validator->fails()){
            $error =  ['error'=>$validator->errors()->all()];
            return Response::validation($error);
        }

        $code = $request->otp;
        $user = auth()->guard(get_auth_guard())->user();
        
        if(!$user->two_factor_secret) {
            return Response::error(['Your secret key not stored properly. Please contact with system administrator']);
        }

        if(google_2fa_verify($user->two_factor_secret,$code)) {
            $user->update([
                'two_factor_verified'   => true,
            ]);
            return Response::success(['Two factor verified successfully!'],[],200);
        }

        return Response::error(['Failed to login. Please try again']);
    }
}
Prerequisites

Prerequisites

Before you begin integrating the Kueue Pay Developer API, make sure you have:

  1. An active Kueue Pay merchant account.
  2. Basic knowledge of API integration and web development with PHP & Laravel.
  3. A secure and accessible web server to handle API requests.