Viewing File: /home/ubuntu/walnutminds-ecom-backend-base/app/Http/Controllers/Api/TransactionApiController.php

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

use App\Helpers\Helper;

use DB, Exception, Setting, stdClass;

use Carbon\Carbon;

use App\Models\{ User, UserCard, UserBillingAccount, UserWallet, UserWalletPayment, UserWithdrawal };

use App\Services\{ PaymentService };

use Illuminate\Validation\Rule;

class TransactionApiController extends Controller
{
    protected $loginUser;

    protected $skip, $take;

    public function __construct(Request $request) {

        info(url()->current());

        info("Request Data".print_r($request->all(), true));
        
        $this->loginUser = User::find($request->id);

        $this->skip = $request->skip ?: 0;

        $this->take = $request->take ?: (Setting::get('admin_take_count') ?: TAKE_COUNT);

        $this->timezone = $this->loginUser->timezone ?? "America/New_York";

        $request->request->add(['timezone' => $this->timezone]);

    }

    /**
     * @method user_cards_add()
     *
     * @uses to add new card to user.
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param card_token
     * 
     * @return JSON Response
     */
    public function user_cards_add(Request $request) {

        try {

            $user = User::find($request->id);

            if(!$user) {

                throw new Exception(api_error(1009, tr('user')), 1009);
                
            }

            if(!Setting::get('stripe_secret_key')) {

                throw new Exception(api_error(105), 105);
            }

            \Stripe\Stripe::setApiKey(Setting::get('stripe_secret_key'));

            $rules = ['card_token' => 'required'];

            Helper::custom_validator($request->all(), $rules, $custom_errors = []);         

            $customer = \Stripe\Customer::create([ "email" => $user->email, "description" => "Customer for ".Setting::get('site_name') ]);

            $stripe = new \Stripe\StripeClient(Setting::get('stripe_secret_key'));

            $intent = \Stripe\SetupIntent::create([ 'customer' => $customer->id, 'payment_method' => $request->card_token ]);

            $stripe->setupIntents->confirm($intent->id, ['payment_method' => $request->card_token]);

            $retrieve = $stripe->paymentMethods->retrieve($request->card_token);
            
            $card_info_from_stripe = $retrieve->card ? $retrieve->card : [];

            DB::beginTransaction();

            $user_cards = UserCard::where(['user_id' => $request->id, 'is_default' => YES])->exists();

            if($customer && $card_info_from_stripe) {

                $card = UserCard::Create([
                    'user_id' => $request->id,
                    'customer_id' => $customer->id,
                    'card_token' => $request->card_token,
                    'card_type' => $card_info_from_stripe->brand ? : '',
                    'last_four' => $card_info_from_stripe->last4 ? : '',
                    'card_holder_name' => $request->card_holder_name ? : $user->name,
                    'is_default' => $user_cards ? NO : YES,
                ]);

                if($card) {

                    DB::commit();

                    return $this->sendResponse(api_success(105), 105, $card);
                }
            }

        } catch(Stripe_CardError | Stripe_InvalidRequestError | Stripe_AuthenticationError | Stripe_ApiConnectionError | Stripe_Error $e) {

            DB::rollback();

            return $this->sendError($e->getMessage(), $e->getCode());

        } catch(Exception $e) {

            DB::rollback();

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method user_cards_list()
     *
     * @uses to get all card details of user
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param 
     * 
     * @return
     */
    public function user_cards_list(Request $request) {

        try {

            $base_query = UserCard::where('user_id', $request->id)->orderBy('updated_at', 'desc');

            $data['total_user_cards'] = $base_query->count();

            $user_cards = $base_query->skip($this->skip)->take($this->take)->get();

            $data['user_cards'] = $user_cards;

            return $this->sendResponse("", "", $data);

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method user_cards_make_default()
     *
     * @uses to make an card as default
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param 
     * 
     * @return
     */
    public function user_cards_make_default(Request $request) {

        try {

            $rules = ['user_card_id' => ['required', 'exists:user_cards,id,user_id,'.$request->id]];

            $custom_errors = ['exists' => api_error(106)];

            $validated = Helper::custom_validator($request->all(), $rules, $custom_errors);

            DB::beginTransaction();

            $user_card = UserCard::find($request->user_card_id);

            if($user_card->is_default == YES) {

                throw new Exception(api_error(107), 107);
            }

            $old_default_card = UserCard::where(['user_id' => $request->id, 'is_default' => YES])->update(['is_default' => NO]);

            $result = $user_card->update(['is_default' => YES]);

            if($result && $old_default_card) {

                DB::commit();

                $data['user_card'] = $user_card;

                return $this->sendResponse(api_success(121), 121 , $data);
            }

            throw new Exception(api_error(108), 108);

        } catch (Exception $e) {

            DB::rollback();

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method user_cards_delete()
     *
     * @uses to delete a user card
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param 
     * 
     * @return
     */
    public function user_cards_delete(Request $request) {

        try {

            $rules = ['user_card_id' => ['required', 'exists:user_cards,id,user_id,'.$request->id]];

            $custom_errors = ['exists' => api_error(106)];

            $validated = Helper::custom_validator($request->all(), $rules, $custom_errors);

            DB::beginTransaction();

            $user_card = UserCard::find($request->user_card_id);

            if($user_card->is_default == YES) {

                $new_default_card = UserCard::firstWhere(['user_id' => $request->id, 'is_default' => NO]);

                if($new_default_card) {

                    $new_default_card->update(['is_default' => YES]);
                }
            }

            $result = $user_card->delete();

            if($result) {

                DB::commit();

                return $this->sendResponse(api_success(122), 122, '');
            }

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method user_wallet_payment_by_stripe()
     * 
     * @uses to add money to wallet by card
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param object $request
     *
     * @return JSON response
     */

    public function user_wallet_payment_by_stripe(Request $request) {

        try {

            DB::beginTransaction();

            $rules = [
                'amount' => 'required|numeric|min:1',
                'user_card_id' => 'nullable|exists:user_cards,id,user_id,'.$request->id
            ];

            Helper::custom_validator($request->all(), $rules, $custom_errors = []);

            if($request->user_card_id) {

                $user_card = UserCard::where(['id' => $request->user_card_id, 'user_id' => $request->id])->exists();

            } else {

                $user_card = UserCard::where(['user_id' => $request->id, 'is_default' => YES])->exists();
            }

            if(!$user_card) {

                throw new Exception(api_error(110), 110); 
            }
            
            $payment_response = PaymentService::user_wallet_payment_by_stripe($request->id, $request->amount, $request->user_card_id);

            if(!$payment_response['result']) {

                throw new Exception($payment_response['message']);
            }

            $data = $payment_response['data'];

            $payment_data = new stdClass;

            $payment_data->user_id = $request->id; $payment_data->amount = $request->amount;

            $payment_data->amount_type = AMOUNT_TYPE_ADD; $payment_data->payment_type = WALLET_PAYMENT_TYPE_CREDIT;

            $payment_data->payment_mode = CARD;

            $payment_data->user_billing_account_id = 0;

            $user_wallet_payment = PaymentService::user_wallet_payment_save($payment_data);

            if(!$user_wallet_payment['result']) {

                throw new Exception($user_wallet_payment['message']);
            }
                
            DB::commit();

            return $this->sendResponse(api_success(123, formatted_amount($data['paid_amount'])), 123, []);

        } catch(Exception $e) {

            DB::rollback();

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method user_wallet()
     *
     * @uses to get user wallet & wallet payment details
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param 
     * 
     * @return
     */
    public function user_wallet(Request $request) {

        try {

            $user_wallet = UserWallet::firstOrCreate(['user_id' => $request->id]);

            $base_query = UserWalletPayment::where(['user_id' => $user_wallet->user_id])->orderByDesc('created_at');

            $data['total_wallet_payments'] = $base_query->count();

            $user_wallet_payments = $base_query->skip($this->skip)->take($this->take)->get();

            $user_wallet_payments->each(function($user_wallet_payment) {

                $user_wallet_payment->paid_date_formatted = convertTimeToUSERzone($user_wallet_payment->paid_date, $this->timezone, "d M Y h:i A");
                
            });

            $data['user_wallet_payments'] = $user_wallet_payments;

            $data['user_wallet'] = $user_wallet;

            return $this->sendResponse("", "", $data);

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /** 
     * @method user_billing_accounts_save()
     *
     * @uses to create / update user billing account details
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param object $request
     *
     * @return JSON response with user billing account details
     */

    public function user_billing_accounts_save(Request $request) {

        try {

            DB::beginTransaction();

            $request->request->add(['user_id' => $request->id]);

            $rules = [
                'user_billing_account_id' => 'nullable|exists:user_billing_accounts,id,user_id,'.$request->id.'|exclude',
                'user_id' => 'exists:users,id',
                'route_number' => 'required',
                'account_number' => 'required',
                'first_name' => 'required|max:50',
                'last_name' => 'required|max:50',
                'bank_type' => ['required', Rule::in(SAVINGS, CHECKING)],
                'business_name' => 'nullable|max:25'
            ];

            $custom_errors = ['exists' => api_error(111), 111];

            $validated = Helper::custom_validator($request->all(), $rules, $custom_errors);

            $user_billing_accounts = UserBillingAccount::where(['user_id' => $request->id, 'is_default' => YES])->exists();

            $user_billing_account = UserBillingAccount::updateOrCreate(['id' => $request->user_billing_account_id], $validated);

            if($user_billing_account) {

                !$user_billing_accounts && $user_billing_account->update(['is_default' => YES]);

                $user_billing_account->refresh();

                DB::commit();
            }

            $success_code = $request->user_billing_account_id ? 125 : 124;

            return $this->sendResponse(api_success($success_code), $success_code, $user_billing_account);

        } catch(Exception $e) {

            DB::rollback();

            return $this->sendError($e->getMessage(), $e->getCode());

        }
    
    }

    /**
     * @method user_billing_accounts_list()
     *
     * @uses to get all user billing account details of user
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param 
     * 
     * @return
     */
    public function user_billing_accounts_list(Request $request) {

        try {

            $user_wallet = UserWallet::firstOrCreate(['user_id' => $request->id]);

            $base_query = UserBillingAccount::where('user_id', $request->id)->orderBy('updated_at', 'desc');

            $data['total_user_billing_accounts'] = $base_query->count();

            $user_billing_accounts = $base_query->skip($this->skip)->take($this->take)->get();

            $data['user_billing_accounts'] = $user_billing_accounts;

            $data['user_wallet'] = $user_wallet;

            return $this->sendResponse("", "", $data);

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method user_billing_accounts_make_default()
     *
     * @uses to make an card as default
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param user_billing_account_id
     * 
     * @return success / failure message
     */
    public function user_billing_accounts_make_default(Request $request) {

        try {

            $rules = ['user_billing_account_id' => ['required', 'exists:user_billing_accounts,id,user_id,'.$request->id]];

            $custom_errors = ['exists' => api_error(111)];

            $validated = Helper::custom_validator($request->all(), $rules, $custom_errors);

            DB::beginTransaction();

            $user_billing_account = UserBillingAccount::find($request->user_billing_account_id);

            if($user_billing_account->is_default == YES) {

                throw new Exception(api_error(112), 112);
            }

            $old_default_billing_account = UserBillingAccount::where(['user_id' => $request->id, 'is_default' => YES])->update(['is_default' => NO]);

            $result = $user_billing_account->update(['is_default' => YES]);

            if($result && $old_default_billing_account) {

                DB::commit();

                $data['user_billing_account'] = $user_billing_account;

                return $this->sendResponse(api_success(126), 126 , $data);
            }

            throw new Exception(api_error(113), 113);

        } catch (Exception $e) {

            DB::rollback();

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method user_billing_accounts_delete()
     *
     * @uses to delete a user billing account
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param user_billing_account_id
     * 
     * @return success / failure message
     */
    public function user_billing_accounts_delete(Request $request) {

        try {

            $rules = ['user_billing_account_id' => ['required', 'exists:user_billing_accounts,id,user_id,'.$request->id]];

            $custom_errors = ['exists' => api_error(111)];

            $validated = Helper::custom_validator($request->all(), $rules, $custom_errors);

            DB::beginTransaction();

            $user_billing_account = UserBillingAccount::find($request->user_billing_account_id);

            if($user_billing_account->is_default == YES) {

                $new_default_billing_account = UserBillingAccount::firstWhere(['user_id' => $request->id, 'is_default' => NO]);

                if($new_default_billing_account) {

                    $new_default_billing_account->update(['is_default' => YES]);
                }
            }

            $result = $user_billing_account->delete();

            if($result) {

                DB::commit();

                return $this->sendResponse(api_success(127), 127, '');
            }

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method withdrawal_requests_send()
     *
     * @uses to send a withdrawal request to admin.
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param unique_id
     * 
     * @return
     */
    public function withdrawal_requests_send(Request $request) {

        try {

            $rules = [
                'amount' => ['required', 'numeric', 'min:1'],
                'user_billing_account_id' => ['required', 'exists:user_billing_accounts,id,user_id,'.$request->id]
            ];

            $custom_errors = ['exists' => api_error(111)];

            Helper::custom_validator($request->all(), $rules, $custom_errors);

            $user_wallet = UserWallet::firstOrCreate(['user_id' => $request->id]);

            if($request->amount > $user_wallet->remaining) {

                throw new Exception(api_error(114), 114);
            }

            $withdrawal_data = new stdClass;

            $withdrawal_data->user_id = $request->id; $withdrawal_data->amount = $request->amount; 

            $withdrawal_data->user_billing_account_id = $request->user_billing_account_id;

            $result = PaymentService::add_withdrawal_request($withdrawal_data);

            if($result['result']) {

                $data['user_wallet'] = $user_wallet->refresh();

                return $this->sendResponse(api_success(128), 128, $data);

            }

            throw new Exception($result['message']);

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method withdrawal_requests_cancel()
     *
     * @uses to cancel a withdrawal request.
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param unique_id
     * 
     * @return
     */
    public function withdrawal_requests_cancel(Request $request) {

        try {

            $rules = [
                        'user_withdrawal_unique_id' => ['required', 'exists:user_withdrawals,unique_id,user_id,'.$request->id],
                        'cancel_reason' => ['nullable', 'max:191'],
                    ];

            $custom_errors = ['exists' => api_error(1009, tr('withdrawal'))];

            Helper::custom_validator($request->all(), $rules);

            $user_withdrawal = UserWithdrawal::firstWhere('unique_id', $request->user_withdrawal_unique_id);

            $user_withdrawal_status = PaymentService::get_withdrawal_status($user_withdrawal->status);

            if($user_withdrawal_status['result']) {

                throw new Exception(api_error($user_withdrawal_status['code']), $user_withdrawal_status['code']);
            }

            $result = PaymentService::cancel_withdrawal_request($user_withdrawal->id, $request->cancel_reason);

            $user_withdrawal->refresh();

            if($result['result']) {

                $user_withdrawal->created_formatted = common_date($user_withdrawal->created_at, $this->timezone, 'd M Y');

                $data['user_withdrawal'] = $user_withdrawal;

                $data['user_wallet'] = UserWallet::firstOrCreate(['user_id' => $request->id]);

                return $this->sendResponse(api_success(129), 129, $data);

            }

            throw new Exception($result['message']);

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method withdrawal_requests()
     *
     * @uses to all withdrawal requests of an user
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param 
     * 
     * @return
     */
    public function withdrawal_requests(Request $request) {

        try {

            $user_wallet = UserWallet::firstOrCreate(['user_id' => $request->id]);

            $base_query = UserWithdrawal::where(['user_id' => $request->id])->orderBy('updated_at', 'desc');

            $data['total_withdrawals'] = $base_query->count();

            $user_withdrawals = $base_query->skip($this->skip)->take($this->take)->get();

            $user_withdrawals->each(function($user_withdrawal) use($request){

                $user_withdrawal->created_formatted = common_date($user_withdrawal->created_at, $this->timezone, 'd M Y');

                $user_withdrawal->updated_formatted = common_date($user_withdrawal->updated_at, $this->timezone, 'd M Y');

            });

            $data['user_withdrawals'] = $user_withdrawals;
            
            $data['user_wallet'] = $user_wallet;

            return $this->sendResponse("", "", $data);

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * @method withdrawal_requests_view()
     *
     * @uses to get the details of an withdrawal request based on user_withdrawal_unique_id
     *
     * @created Karthick
     *
     * @updated 
     *
     * @param user_withdrawal_unique_id
     * 
     * @return withdrawal request details.
     */
    public function withdrawal_requests_view(Request $request) {

        try {

            $rules = [ 'user_withdrawal_unique_id' => ['required', 'exists:user_withdrawals,unique_id,user_id,'.$request->id] ];

            $custom_errors = ['exists' => api_error(1009, tr('withdrawal'))];

            Helper::custom_validator($request->all(), $rules);

            $user_withdrawal = UserWithdrawal::firstWhere('unique_id', $request->user_withdrawal_unique_id);

            $user_withdrawal->created_formatted = common_date($user_withdrawal->created_at, $this->timezone, 'd M Y');

            $user_withdrawal->updated_formatted = common_date($user_withdrawal->updated_at, $this->timezone, 'd M Y');

            $data['user_withdrawal'] = $user_withdrawal;

            return $this->sendResponse("", "", $data);

        } catch (Exception $e) {

            return $this->sendError($e->getMessage(), $e->getCode());
        }
    }
}
Back to Directory File Manager