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

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

use Exception;
use App\Models\User;
use App\Models\UserWallet;
use App\Models\Transaction;
use Jenssegers\Agent\Agent;
use Illuminate\Http\Request;
use App\Constants\GlobalConst;
use App\Http\Helpers\Response;
use App\Models\Admin\Currency;
use App\Models\UserNotification;
use Illuminate\Support\Facades\DB;
use App\Models\Admin\BasicSettings;
use App\Http\Controllers\Controller;
use App\Constants\PaymentGatewayConst;
use App\Models\Admin\TransactionSetting;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Notification;
use App\Notifications\User\TransferMoneyNotification;
use App\Notifications\User\TransferMoneyReceivedNotification;

class TransferMoneyController extends Controller
{
    /**
     * Method for get transfer money information
     * @return response
     */
    public function info(){
        $base_currency          = Currency::default();
        $user_wallet            = UserWallet::auth()->first();
        $transaction_settings   = TransactionSetting::where('slug',GlobalConst::TRANSFER_MONEY)->get()->map(function($data){
            return [
                'title'         => $data->title,
                'fixed_charge'  => get_amount($data->fixed_charge),
                'percent_charge'=> get_amount($data->percent_charge),
                'min_limit'     => get_amount($data->min_limit),
                'max_limit'     => get_amount($data->max_limit),
            ];
        })->first();
        $transactions               = Transaction::auth()->where('type',PaymentGatewayConst::TYPETRANSFERMONEY)->get()->map(function($data){
            if($data->attribute == PaymentGatewayConst::SEND){
                $receiver_name            = $data->details->receiver->fullname;
                $receiver_email           = $data->details->receiver->email;
                return [
                    'type'              => $data->type,
                    'trx_id'           => $data->trx_id,
                    'receiver_name'     => $receiver_name,
                    'receiver_email'    => $receiver_email,
                    'request_amount'    => get_amount($data->request_amount),
                    'fixed_charge'      => get_amount($data->fixed_charge),
                    'percent_charge'    => get_amount($data->percent_charge),
                    'total_charge'      => get_amount($data->total_charge),
                    'total_payable'     => get_amount($data->total_payable),
                    'request_currency'  => $data->request_currency,
                    'remark'            => $data->remark,
                    'attribute'         => $data->attribute,
                    'status'            => $data->stringStatus->value,
                ];
            }else{
                $sender_name              = $data->details->sender->fullname;
                $sender_email             = $data->details->sender->email;
                return [
                    'type'              => $data->type,
                    'trx_id'           => $data->trx_id,
                    'sender_name'       => $sender_name,
                    'sender_email'      => $sender_email,
                    'request_amount'    => get_amount($data->request_amount),
                    'fixed_charge'      => get_amount($data->fixed_charge),
                    'percent_charge'    => get_amount($data->percent_charge),
                    'total_charge'      => get_amount($data->total_charge),
                    'total_payable'     => get_amount($data->total_payable),
                    'request_currency'  => $data->request_currency,
                    'remark'            => $data->remark,
                    'attribute'         => $data->attribute,
                    'status'            => $data->stringStatus->value,
                ];
            }
            
        });

        $currency_image_paths = [
            'base_url'          => url("/"),
            'path_location'     => files_asset_path_basename("currency-flag"),
            'default_image'     => files_asset_path_basename("currency-flag"),
        ];
        
        return Response::success(['Transfer money fetch successfully.'],[
            'base_currency'          => $base_currency->code,
            'rate'                   => get_amount($base_currency->rate),
            'flag'                   => $base_currency->flag,
            'currency_image_paths'   => $currency_image_paths,
            'wallet'                 => [
                'code'               => $user_wallet->currency->code,
                'balance'            => get_amount($user_wallet->balance),
            ],
            'transaction_settings'   => $transaction_settings,
            'transactions'           => $transactions
        ],200);
    }
    /**
     * Method for check the user data
     * @param Illuminate\Http\Request $request
     */
    public function checkUser(Request $request){
        $validator          = Validator::make($request->all(),[
            'email'         => 'required|email',
        ]);
        if($validator->fails()) return Response::error($validator->errors()->all(),[]);
        $validated          = $validator->validate();
        $user               = User::where('email',$validated['email'])->first();
        if(!$user){
            return Response::error(['Sorry! User not found.'],[],400);
        }
        if(auth()->user()->email == $validated['email']){
            return Response::error(['Sorry! You can not transfer money to your own account.'],[],400);
        }
        $user_data      = [
            'name'      => $user->fullname,
            'email'     => $user->email,
            'image'     => $user->image
        ];
        $image_paths = [
            'base_url'          => url("/"),
            'path_location'     => files_asset_path_basename("user-profile"),
            'default_image'     => files_asset_path_basename("profile-default"),
        ];
        return Response::success(['Valid user for transfer money.'],[
            'user'          => $user_data,
            'image_paths'   => $image_paths
        ],200);
            

    }
    /**
     * Method for confirm transfer money request
     * @param Illuminate\Http\Request $request
     */
    public function confirm(Request $request){
        $validator          = Validator::make($request->all(),[
            'amount'        => 'required|numeric',
            'email'         => 'required|email',
            'remark'        => 'nullable'
        ]);
        if($validator->fails()) return Response::error($validator->errors()->all(),[]);
        $validated          = $validator->validate();
        if(auth()->user()->email == $validated['email']){
            return Response::error(['Sorry! You can not transfer money to your own account.'],[],400); 
        }
        $user_wallet        = UserWallet::auth()->first();
        if(!$user_wallet) return Response::error(['Sorry! Wallet not found.'],[],400); 
        $amount             = $validated['amount'];
        $receiver           = User::with(['wallet'])->where('email',$validated['email'])->first();
        if(!$receiver) return Response::error(['Sorry! Receiver not found.'],[],400);
        $transaction_settings   = TransactionSetting::where('slug',GlobalConst::TRANSFER_MONEY)->first();
        if(!$transaction_settings) return Response::error(['Sorry! Transaction charges not found.'],[],400);

        if($user_wallet->balance < $amount){
            return Response::error(['Sorry! Insufficient balance.'],[],400);
        }
        $basic_settings      = BasicSettings::first();
        $fixed_charge        = $transaction_settings->fixed_charge;
        $percent_charge      = ($amount * $transaction_settings->percent_charge) / 100;
        $total_charge        = $fixed_charge + $percent_charge;
        $payable_amount      = $amount + $total_charge;

        if($transaction_settings->min_limit > $payable_amount || $transaction_settings->max_limit < $payable_amount){
            return Response::error(['Please follow the transaction limit.'],[],400);
        }

        if($user_wallet->balance < $payable_amount){
            return Response::error(['Sorry! Insufficient balance.'],[],400);
        }
        if(isset($validated['remark']) == '' || isset($validated['remark']) == null){
            $remark = null;
        }else{
            $remark = $validated['remark'];
        }
        try{
            // for sender
            $transaction      = $this->insertSenderRecord($amount,$user_wallet,$receiver,$fixed_charge,$percent_charge,$total_charge,$payable_amount,$remark);
            $this->transactionDevice($transaction);
            $this->userNotification($transaction,$amount,$receiver);
            if($basic_settings->email_notification){
                try{
                    Notification::route('mail',auth()->user()->email)->notify(new TransferMoneyNotification($amount,$receiver,$payable_amount));
                }catch(Exception $e){}
            }
            
            // for receiver
            $receiver_transaction      = $this->insertReceiverRecord($amount,$user_wallet,$receiver,$fixed_charge,$percent_charge,$total_charge,$payable_amount,$remark);
            $this->userReceiverNotification($receiver_transaction,$amount,$receiver);
            if($basic_settings->email_notification){
                try{
                    Notification::route('mail',$receiver->email)->notify(new TransferMoneyReceivedNotification($amount,$receiver));
                }catch(Exception $e){}
            }
        }catch(Exception $e){
            return Response::error(['Something went wrong! Please try again.'],[],400);
        }
        $transaction_data       = Transaction::where('id',$transaction)->first();
        $image_paths = [
            'base_url'          => url("/"),
            'path_location'     => files_asset_path_basename("user-profile"),
            'default_image'     => files_asset_path_basename("profile-default"),
        ];  
        return Response::success(['Successfully transferred money.'],[
           'currency'           => $transaction_data->request_currency,
           'request_amount'     => floatval($transaction_data->request_amount),
           'total_charge'       => floatval($transaction_data->total_charge),
           'total_payable'      => floatval($transaction_data->total_payable),
           'receiver_name'      => $transaction_data->details->receiver->fullname,
           'receiver_email'     => $transaction_data->details->receiver->email,
           'status'             => $transaction_data->stringStatus->value,
           'receiver_image'     => $receiver->image,
           'image_paths'        => $image_paths
        ],200);
    }
    //insert transaction data
    function insertSenderRecord($amount,$user_wallet,$receiver,$fixed_charge,$percent_charge,$total_charge,$payable_amount,$remark){
        $available_balance = $user_wallet->balance - $payable_amount;
        DB::beginTransaction();
        try{
            $trx_id         = generateTrxString("transactions","trx_id","TM",8);
            $id = DB::table('transactions')->insertGetId([
                'trx_id'                => $trx_id,
                'user_id'               => auth()->user()->id,
                'user_wallet_id'        => $user_wallet->id,
                'type'                  => PaymentGatewayConst::TYPETRANSFERMONEY,
                'request_amount'        => $amount,
                'fixed_charge'          => $fixed_charge,
                'percent_charge'        => $percent_charge,
                'total_charge'          => $total_charge,
                'total_payable'         => $payable_amount,
                'request_currency'      => get_default_currency_code(),
                'available_balance'     => $available_balance,
                'payment_currency'      => get_default_currency_code(),
                'remark'                => ucwords(remove_special_char("Transfer Money"," ")) . " Send to" . " " . $receiver->email,
                'details'               => json_encode(['remark' => $remark,'receiver' => [
                    'fullname'          => $receiver->fullname,
                    'email'             => $receiver->email
                ]]),
                'attribute'             => PaymentGatewayConst::SEND,
                'status'                => PaymentGatewayConst::STATUSSUCCESS,
                'created_at'            => now()
            ]);
            $this->updateSenderWalletBalance($user_wallet,$payable_amount);
            DB::commit();
        }catch(Exception $e){
            DB::rollBack();
            return Response::error(['Something went wrong! Please try again.'],[],400);
        }
        return $id;
    }
    // update sender wallet balance
    function updateSenderWalletBalance($user_wallet,$amount){
        $user_wallet->update([
            'balance'   => $user_wallet->balance - $amount,
        ]);
    }
    // save the transaction device information
    function transactionDevice($id){
        $client_ip = request()->ip() ?? false;
        $location = geoip()->getLocation($client_ip);
        $agent = new Agent();
        $mac = "";
        DB::beginTransaction();
        try{
            DB::table("transaction_devices")->insert([
                'transaction_id'=> $id,
                'ip'            => $client_ip,
                'mac'           => $mac,
                'city'          => $location['city'] ?? "",
                'country'       => $location['country'] ?? "",
                'longitude'     => $location['lon'] ?? "",
                'latitude'      => $location['lat'] ?? "",
                'timezone'      => $location['timezone'] ?? "",
                'browser'       => $agent->browser() ?? "",
                'os'            => $agent->platform() ?? "",
            ]);
            DB::commit();
        }catch(Exception $e) {
            DB::rollBack();
            return Response::error(['Something went wrong! Please try again.'],[],400);
        }
    }
    //user notification
    public function userNotification($id,$amount,$receiver){
        UserNotification::create([
            'user_id'           => auth()->user()->id,
            'transaction_id'    => $id,
            'details'           => [
                'title'         => 'Transfer Money to ' .$receiver->email,
                'amount'        => floatval($amount),
                'currency'      => get_default_currency_code(),
                'message'       => "Successfully Send."
            ],
        ]);
    }
    //insert transaction data
    function insertReceiverRecord($amount,$user_wallet,$receiver,$fixed_charge,$percent_charge,$total_charge,$payable_amount,$remark){
        $available_balance = $receiver->wallet->balance + $amount;
        DB::beginTransaction();
        try{
            $trx_id         = generateTrxString("transactions","trx_id","TM",8);
            
            $id = DB::table('transactions')->insertGetId([
                'trx_id'                => $trx_id,
                'user_id'               => $receiver->id,
                'user_wallet_id'        => $receiver->wallet->id,
                'type'                  => PaymentGatewayConst::TYPETRANSFERMONEY,
                'request_amount'        => $amount,
                'fixed_charge'          => $fixed_charge,
                'percent_charge'        => $percent_charge,
                'total_charge'          => $total_charge,
                'total_payable'         => $payable_amount,
                'request_currency'      => get_default_currency_code(),
                'available_balance'     => $available_balance,
                'payment_currency'      => get_default_currency_code(),
                'remark'                => ucwords(remove_special_char("Received Money"," ")) . " From" . " " . auth()->user()->email,
                'details'               => json_encode(['remark' => $remark,'sender' => [
                    'fullname'          => auth()->user()->fullname,
                    'email'             => auth()->user()->email
                ]]),
                'attribute'             => PaymentGatewayConst::RECEIVED,
                'status'                => PaymentGatewayConst::STATUSSUCCESS,
                'created_at'            => now()
            ]);
            $this->updateReceiverWalletBalance($receiver,$amount);

            DB::commit();
        }catch(Exception $e){
            DB::rollBack();
            return Response::error(['Something went wrong! Please try again.'],[],400);
        }
        return $id;
    }
    //update receiver wallet balance
    function updateReceiverWalletBalance($receiver,$amount){
        $update_balance     = $receiver->wallet->balance + $amount;
        $receiver->wallet->update([
            'balance' => $update_balance,
        ]);
    }
    //user notification
    public function userReceiverNotification($id,$amount,$receiver){
        UserNotification::create([
            'user_id'           => $receiver->id,
            'transaction_id'    => $id,
            'details'           => [
                'title'         => 'Received Money From ' .auth()->user()->email,
                'amount'        => floatval($amount),
                'currency'      => get_default_currency_code(),
                'message'       => "Successfully Received."
            ],
        ]);
    }
}
Refund Policy
top

At NFC Pay, we strive to provide a seamless and satisfactory experience with our services. This Refund Policy outlines the circumstances under which refunds may be issued for transactions made through our platform. Please read this policy carefully to understand your rights regarding refunds.
1. Eligibility for Refunds
Refunds may be considered under the following circumstances:
 

2. Non-Refundable Situations
Refunds will generally not be issued in the following situations:
 

3. Refund Process
To request a refund, please follow these steps:
 

  1. Contact Customer Support: Reach out to our customer support team via [email/phone/app support chat] with your transaction details, including the date, amount, and reason for the refund request.
  2. Investigation: Our team will review your request and may ask for additional information or documentation to support your claim. This process typically takes [5-10 business days], depending on the complexity of the issue.
  3. Refund Decision: After reviewing your request, we will notify you of our decision. If approved, the refund will be processed back to your original payment method. The timing of the refund will depend on your bank or payment provider and may take up to [10 business days] to reflect in your account.

4. Refund Exceptions
Certain transactions may be subject to specific terms and conditions, including non-refundable fees or charges. Please review the terms associated with each transaction carefully, as some fees may not be eligible for refunds.
5. Modifications to the Refund Policy
NFC Pay reserves the right to modify this Refund Policy at any time. Changes will be communicated through updates on our website and app, and the effective date will be updated accordingly. We encourage you to review this policy periodically to stay informed about our refund practices.
By using NFC Pay, you agree to this Refund Policy and understand the terms under which refunds may be issued. Our goal is to ensure a fair and transparent refund process, providing you with confidence and peace of mind when using our services.