Your IP : 216.73.217.77


Current Path : /home/users/unlimited/www/eshop.codeskitter.site/application/controllers/admin/
Upload File :
Current File : /home/users/unlimited/www/eshop.codeskitter.site/application/controllers/admin/Webhook.php

<?php defined('BASEPATH') or exit('No direct script access allowed');
class Webhook extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->data['firebase_project_id'] = get_settings('firebase_project_id');
        $this->data['service_account_file'] = get_settings('service_account_file');
    }

    public function razorpay()
    {
        //Debug in server first
        if ((strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') || !array_key_exists('HTTP_X_RAZORPAY_SIGNATURE', $_SERVER))
            exit();

        $this->load->library(['razorpay']);
        $system_settings = get_settings('system_settings', true);
        $credentials = $this->razorpay->get_credentials();

        $request = file_get_contents('php://input');
        if ($request === false || empty($request)) {
            $this->edie("Error in reading Post Data");
        }
        $request = json_decode($request, true);

        define('RAZORPAY_SECRET_KEY', $credentials['secret_hash']);
        log_message('error', 'Razorpay IPN POST --> ' . var_export($request, true));
        log_message('error', 'Razorpay IPN SERVER --> ' . var_export($_SERVER, true));
        $http_razorpay_signature = isset($_SERVER['HTTP_X_RAZORPAY_SIGNATURE']) ? $_SERVER['HTTP_X_RAZORPAY_SIGNATURE'] : "";

        $txn_id = (isset($request['payload']['payment']['entity']['id'])) ? $request['payload']['payment']['entity']['id'] : "";

        if (!empty($request['payload']['payment']['entity']['id'])) {
            if (!empty($txn_id)) {
                $transaction = fetch_details('transactions', ['txn_id' => $txn_id], '*');
            }
            $amount = $request['payload']['payment']['entity']['amount'];
            $amount = ($amount / 100);
        } else {
            $amount = 0;
            $currency = (isset($request['payload']['payment']['entity']['currency'])) ? $request['payload']['payment']['entity']['currency'] : "";
        }


        if (!empty($transaction)) {
            $order_id = $transaction[0]['order_id'];
            log_message('error', 'razorpay Webhook | transaction order id --> ' . var_export($order_id, true));

            $user_id = $transaction[0]['user_id'];
        } else {
            $order_id = 0;
            $order_id = (isset($request['payload']['order']['entity']['notes']['order_id'])) ? $request['payload']['order']['entity']['notes']['order_id'] : $request['payload']['payment']['entity']['notes']['order_id'];
            log_message('error', 'razorpay Webhook | webhook order id --> ' . var_export($order_id, true));
        }

        $this->load->model('transaction_model');

        if ($http_razorpay_signature) {
            if ($request['event'] == 'payment.authorized') {
                $currency = (isset($request['payload']['payment']['entity']['currency'])) ? $request['payload']['payment']['entity']['currency'] : "INR";
                $this->load->library("razorpay");
                $response = $this->razorpay->capture_payment($amount * 100, $txn_id, $currency);
                return;
            }
            if ($request['event'] == 'payment.captured' || $request['event'] == 'order.paid') {
                if ($request['event'] == 'order.paid') {
                    $order_id = $request['payload']['order']['entity']['receipt'];
                    $order_data = fetch_orders($order_id);
                    $user_id = (isset($order_data['order_data'][0]['user_id'])) ? $order_data['order_data'][0]['user_id'] : "";
                }
                if (!empty($order_id)) {
                    /* To do the wallet recharge if the order id is set in the patter */
                    if (strpos($order_id, "wallet-refill-user") !== false) {
                        if (!is_numeric($order_id) && strpos($order_id, "wallet-refill-user") !== false) {
                            $temp = explode("-", $order_id);
                            if (isset($temp[3]) && is_numeric($temp[3]) && !empty($temp[3] && $temp[3] != '')) {
                                $user_id = $temp[3];
                            } else {
                                $user_id = 0;
                            }
                        }

                        $data['transaction_type'] = "wallet";
                        $data['user_id'] = $user_id;
                        $data['order_id'] = $order_id;
                        $data['type'] = "credit";
                        $data['txn_id'] = $txn_id;
                        $data['amount'] = $amount;
                        $data['status'] = "success";
                        $data['message'] = "Wallet refill successful";
                        log_message('error', 'Razorpay user ID -  transaction data--> ' . var_export($data, true));


                        $this->transaction_model->add_transaction($data);
                        log_message('error', 'Razorpay user ID - Add transaction --> ' . var_export($txn_id, true));


                        $this->load->model('customer_model');
                        if ($this->customer_model->update_balance($amount, $user_id, 'add')) {
                            $response['error'] = false;
                            $response['transaction_status'] = $request['event'];
                            $response['message'] = "Wallet recharged successfully!";
                            log_message('error', 'Razorpay user ID - Wallet recharged successfully --> ' . var_export($order_id, true));
                        } else {
                            $response['error'] = true;
                            $response['transaction_status'] = $request['event'];
                            $response['message'] = "Wallet could not be recharged!";
                            log_message('error', 'razorpay Webhook | wallet recharge failure --> ' . var_export($request['event'], true));
                        }
                        echo json_encode($response);
                        return false;
                    } else {

                        /* process the order and mark it as received */
                        $order = fetch_orders($order_id, false, false, false, false, false, false, false);
                        log_message('error', 'Razorpay order -   data--> ' . var_export($order, true));

                        if (isset($order['order_data'][0]['user_id'])) {
                            $user = fetch_details('users', ['id' => $order['order_data'][0]['user_id']]);
                            $overall_total = array(
                                'total_amount' => $order['order_data'][0]['total'],
                                'delivery_charge' => $order['order_data'][0]['delivery_charge'],
                                'tax_amount' => $order['order_data'][0]['total_tax_amount'],
                                'tax_percentage' => $order['order_data'][0]['total_tax_percent'],
                                'discount' =>  $order['order_data'][0]['promo_discount'],
                                'wallet' =>  $order['order_data'][0]['wallet_balance'],
                                'final_total' =>  $order['order_data'][0]['final_total'],
                                'otp' => $order['order_data'][0]['otp'],
                                'address' =>  $order['order_data'][0]['address'],
                                'payment_method' => $order['order_data'][0]['payment_method']
                            );

                            $overall_order_data = array(
                                'cart_data' => $order['order_data'][0]['order_items'],
                                'order_data' => $overall_total,
                                'subject' => 'Order received successfully',
                                'user_data' => $user[0],
                                'system_settings' => $system_settings,
                                'user_msg' => 'Hello, Dear ' . ucfirst($user[0]['username']) . ', We have received your order successfully. Your order summaries are as followed',
                                'otp_msg' => 'Here is your OTP. Please, give it to delivery boy only while getting your order.',
                            );
                            if (isset($user[0]['email']) && !empty($user[0]['email'])) {
                                send_mail($user[0]['email'], 'Order received successfully', $this->load->view('admin/pages/view/email-template.php', $overall_order_data, TRUE));
                            }
                            /* No need to add because the transaction is already added just update the transaction status */
                            if (!empty($transaction)) {
                                $transaction_id = $transaction[0]['id'];
                                update_details(['status' => 'success'], ['id' => $transaction_id], 'transactions');
                            } else {
                                /* add transaction of the payment */
                                $amount = ($request['payload']['payment']['entity']['amount'] / 100);
                                $data = [
                                    'transaction_type' => 'transaction',
                                    'user_id' => $user_id,
                                    'order_id' => $order_id,
                                    'type' => 'razorpay',
                                    'txn_id' => $txn_id,
                                    'amount' => $amount,
                                    'status' => 'success',
                                    'message' => 'order placed successfully',
                                ];
                                $this->transaction_model->add_transaction($data);
                            }

                            update_details(['active_status' => 'received'], ['order_id' => $order_id], 'order_items');
                            $status = json_encode(array(array('received', date("d-m-Y h:i:sa"))));
                            update_details(['status' => $status], ['order_id' => $order_id], 'order_items', false);

                            // place order custome notification on payment success

                            $custom_notification = fetch_details('custom_notifications', ['type' => "place_order"], '');
                            $hashtag_order_id = '< order_id >';
                            $string = json_encode($custom_notification[0]['title'], JSON_UNESCAPED_UNICODE);
                            $hashtag = html_entity_decode($string);
                            $data1 = str_replace($hashtag_order_id, $order_id, $hashtag);
                            $title = output_escaping(trim($data1, '"'));
                            $hashtag_application_name = '< application_name >';
                            $string = json_encode($custom_notification[0]['message'], JSON_UNESCAPED_UNICODE);
                            $hashtag = html_entity_decode($string);
                            $data2 = str_replace($hashtag_application_name, $system_settings['app_name'], $hashtag);
                            $message = output_escaping(trim($data2, '"'));

                            $fcm_admin_subject = (!empty($custom_notification)) ? $title : 'New order placed ID #' . $order_id;
                            $fcm_admin_msg = (!empty($custom_notification)) ? $message : 'New order received for  ' . $system_settings['app_name'] . ' please process it.';
                            $user_fcm = fetch_details('users', ['id' => $user_id], 'fcm_id,mobile,email,platform_type');
                            // Step 1: Group by platform
                            $groupedByPlatform = [];
                            foreach ($user_fcm as $item) {
                                $platform = $item['platform_type'];
                                $groupedByPlatform[$platform][] = $item['fcm_id'];
                            }

                            // Step 2: Chunk each platform group into arrays of 1000
                            $user_fcm_ids = [];
                            foreach ($groupedByPlatform as $platform => $fcmIds) {
                                $user_fcm_ids[$platform] = array_chunk($fcmIds, 1000);
                            }

                            $user_fcm_id[0] = $user_fcm_ids[0]['fcm_id'];
                            // $user_fcm_id[0][] = $user_fcm_ids[0]['fcm_id'];
                            $firebase_project_id = $this->data['firebase_project_id'];
                            $service_account_file = $this->data['service_account_file'];
                            if (!empty($user_fcm_id) && isset($firebase_project_id) && isset($service_account_file) && !empty($firebase_project_id) && !empty($service_account_file)) {
                                $fcmMsg = array(
                                    'title' => $fcm_admin_subject,
                                    'body' => $fcm_admin_msg,
                                    'type' => "place_order",
                                );
                                send_notification($fcmMsg, $user_fcm_id, $fcmMsg);
                            }
                            notify_event(
                                'place_order',
                                ["customer" => [$user_fcm[0]['email']]],
                                ["customer" => [$user_fcm[0]['mobile']]],
                                ["orders.id" => $order_id]
                            );
                            update_stock($order['order_data'][0]['product_variant_ids'], $order['order_data'][0]['quantity'], 'plus');
                        }
                    }
                } else {
                    log_message('error', 'Razorpay Order id not found --> ' . var_export($request, true));
                    /* No order ID found */
                }

                $response['error'] = false;
                $response['transaction_status'] = $request['event'];
                $response['message'] = "Transaction successfully done";
                echo json_encode($response);
                return false;
            } elseif ($request['event'] == 'payment.failed') {
                //$order = fetch_orders($order_id, false, false, false, false, false, false, false);

                if (!empty($order_id)) {
                    // update_stock($order['order_data'][0]['product_variant_ids'], $order['order_data'][0]['quantity'], 'plus');
                    update_details(['active_status' => 'cancelled'], ['order_id' => $order_id], 'order_items');
                }
                /* No need to add because the transaction is already added just update the transaction status */
                if (!empty($transaction)) {
                    $transaction_id = $transaction[0]['id'];
                    update_details(['status' => 'failed'], ['id' => $transaction_id], 'transactions');
                }
                $response['error'] = true;
                $response['transaction_status'] = $request['event'];
                $response['message'] = "Transaction is failed. ";
                log_message('error', 'Razorpay Webhook | Transaction is failed --> ' . var_export($request['event'], true));
                echo json_encode($response);
                return false;
            } elseif ($request['event'] == 'payment.authorized') {
                if (!empty($order_id)) {
                    update_details(['active_status' => 'awaiting'], ['order_id' => $order_id], 'order_items');
                }
            } elseif ($request['event'] == "refund.processed") {
                //Refund Successfully
                $transaction = fetch_details('transactions', ['txn_id' => $request['payload']['refund']['entity']['payment_id']]);
                if (empty($transaction)) {
                    return false;
                }
                // process_refund($transaction[0]['id'], $transaction[0]['status']);

                $response['error'] = false;
                $response['transaction_status'] = $request['event'];
                $response['message'] = "Refund successfully done. ";
                $data = [
                    'transaction_type' => 'transaction',
                    'user_id' => $user_id,
                    'type' => 'razorpay',
                    'amount' => $amount,
                    'message' => 'Refund successfully done.',
                    'order_id' => $order_id,
                    'is_refund' => '1',
                    'status' => (isset($status) && !empty($status)) ? $status : 'success',
                ];
                
                $this->db->insert('transactions', $data);
                log_message('error', 'Razorpay Webhook | Payment refund done --> ' . var_export($request['event'], true));
                echo json_encode($response);
                return false;
            } elseif ($request['event'] == "refund.failed") {
                $response['error'] = true;
                $response['transaction_status'] = $request['event'];
                $response['message'] = "Refund is failed. ";
                log_message('error', 'Razorpay Webhook | Payment refund failed --> ' . var_export($request['event'], true));
                echo json_encode($response);
                return false;
            } else {
                $response['error'] = true;
                $response['transaction_status'] = $request['event'];
                $response['message'] = "Transaction could not be detected.";
                log_message('error', 'Razorpay Webhook | Transaction could not be detected --> ' . var_export($request['event'], true));
                echo json_encode($response);
                return false;
            }
        } else {
            log_message('error', 'razorpay Webhook | Invalid Server Signature  --> ' . var_export($request['event'], true));
            return false;
        }
    }

    public function edie($error_msg)
    {
        global $debug_email;
        $report =  "ERROR : " . $error_msg . "\n\n";
        $report .= "POST DATA\n\n";
        foreach ($_POST as $key => $value) {
            $report .= "|$key| = |$value| \n";
        }
        log_message('error', $report);
        die($error_msg);
    }


    // ------------------------------------------------ MyFatoorah PAYMENT GATEWAY ------------------------------------------

    public function myfatoorah_success_url()
    {
        $response['error'] = false;
        $response['transaction_status'] = 'Success';
        $response['message'] = "Transaction successfully done";
        echo json_encode($response);
        return false;
    }

    public function myfatoorah_error_url()
    {

        $response['error'] = true;
        $response['transaction_status'] = 'Failure';
        $response['message'] = "Transaction is failed. ";
        log_message('error', 'My Fatoorah Transaction is failed --> ');
        echo json_encode($response);
        return false;
    }
    public function myfatoorah()
    {
        $system_settings = get_settings('system_settings', true);
        //get MyFatoorah-Signature from request headers
        $request_headers = apache_request_headers();
        log_message('error', 'my fatoorah  Webhook | request_headers  --> ' . var_export($request_headers, true));
        log_message('error', 'my fatoorah  Webhook | request_headers  --> ' . var_export($request_headers['Host'], true));
        $MyFatoorah_Signature = $request_headers['Myfatoorah-Signature'];
        log_message('error', 'my fatoorah  Webhook | Invalid Server Signature  --> ' . var_export($MyFatoorah_Signature, true));

        $payment_settings = get_settings('payment_method', true);
        $secret = $payment_settings['myfatoorah__secret_key'];
        // $secret = 'XyXEaQw97JFXQDFibyybAWE6aXujBvoHw3+5BvCRbKl8YOWYHTmX3fn+PSnn0UslQlgIh5xnej5MeLg5onRvTg==';

        //Get webhook body content
        $body = (file_get_contents("php://input"));

        $data = json_decode($body, true);

        //Log data to check the result

        log_message('error', $body);

        // error_log(PHP_EOL . date('d.m.Y h:i:s') . ' - ' . $body, 3, './webhook.log');

        //Validate the signature
        $this->validateSignature($data, $secret, $MyFatoorah_Signature);

        //Call $data['Event'] function
        if (empty($data['Event'])) {
            exit();
        } else {

            log_message('error', $data['Data']['PaymentId']);
            $txn_id = (isset($data['Data']['PaymentId'])) ? $data['Data']['PaymentId'] : "";

            if (!empty(($data['Data']['PaymentId']))) {
                if (!empty($txn_id)) {
                    $transaction = fetch_details('transactions', ['txn_id' => $txn_id], '*');
                }
                $amount = $data['Data']['InvoiceValueInBaseCurrency'];
                // $amount = ($amount / 100);
            } else {
                $amount = 0;
                $currency = (isset($data['Data']['PayCurrency'])) ? $data['Data']['PayCurrency'] : "";
            }

            if (!empty($transaction)) {
                $order_id = $transaction[0]['order_id'];
                $user_id = $transaction[0]['user_id'];
            } else {
                $order_id = 0;
                $order_id = (isset($data['Data']['UserDefinedField'])) ? $data['Data']['UserDefinedField'] : $data['Data']['UserDefinedField'];
            }

            $this->load->model('transaction_model');
            // if ($request['event'] == 'payment.authorized') {
            //     $currency = (isset($request['payload']['payment']['entity']['currency'])) ? $request['payload']['payment']['entity']['currency'] : "INR";
            //     $this->load->library("razorpay");
            //     $response = $this->razorpay->capture_payment($amount * 100, $txn_id, $currency);
            //     return;
            // }
            if ($data['Event'] == 'TransactionsStatusChanged') {
                if ($data['Data']['TransactionStatus'] == "FAILED") {



                    if (!empty($order_id)) {
                        // update_stock($order['order_data'][0]['product_variant_ids'], $order['order_data'][0]['quantity'], 'plus');
                        update_details(['active_status' => 'cancelled'], ['order_id' => $order_id], 'order_items');
                    }
                    /* No need to add because the transaction is already added just update the transaction status */
                    if (!empty($transaction)) {
                        $transaction_id = $transaction[0]['id'];
                        update_details(['status' => 'failed'], ['id' => $transaction_id], 'transactions');
                    }
                    $response['error'] = true;
                    $response['transaction_status'] = $data['Data']['TransactionStatus'];
                    $response['message'] = "Transaction is failed. ";
                    log_message('error', 'Razorpay Webhook | Transaction is failed --> ' . var_export($data['Data']['TransactionStatus'], true));
                    echo json_encode($response);
                    return false;
                } else if ($data['Data']['TransactionStatus'] == "SUCCESS") {


                    if ($data['Event'] == 'TransactionsStatusChanged') {
                        $order_id = $data['Data']['UserDefinedField'];
                        $order_data = fetch_orders($order_id);
                        $user_id = (isset($order_data['order_data'][0]['user_id'])) ? $order_data['order_data'][0]['user_id'] : "";
                    }
                    if (!empty($order_id)) {
                        /* To do the wallet recharge if the order id is set in the patter */
                        if (strpos($order_id, "wallet-refill-user") !== false) {
                            if (!is_numeric($order_id) && strpos($order_id, "wallet-refill-user") !== false) {
                                $temp = explode("-", $order_id);
                                if (isset($temp[3]) && is_numeric($temp[3]) && !empty($temp[3] && $temp[3] != '')) {
                                    $user_id = $temp[3];
                                } else {
                                    $user_id = 0;
                                }
                            }

                            $data['transaction_type'] = "wallet";
                            $data['user_id'] = $user_id;
                            $data['order_id'] = $order_id;
                            $data['type'] = "credit";
                            $data['txn_id'] = $txn_id;
                            $data['amount'] = $amount;
                            $data['status'] = "success";
                            $data['message'] = "Wallet refill successful";
                            log_message('error', 'My fatoorah user ID -  transaction data--> ' . var_export($data, true));


                            $this->transaction_model->add_transaction($data);
                            log_message('error', 'My Fatoorah user ID - Add transaction --> ' . var_export($txn_id, true));

                            $this->load->model('customer_model');
                            if ($this->customer_model->update_balance($amount, $user_id, 'add')) {
                                $response['error'] = false;
                                $response['transaction_status'] = $data['Data']['TransactionStatus'];
                                $response['message'] = "Wallet recharged successfully!";
                                log_message('error', 'My fatoorah user ID - Wallet recharged successfully --> ' . var_export($order_id, true));
                            } else {
                                $response['error'] = true;
                                $response['transaction_status'] = $data['Data']['TransactionStatus'];
                                $response['message'] = "Wallet could not be recharged!";
                                log_message('error', 'My Fatoorah Webhook | wallet recharge failure --> ' . var_export($data['Data']['TransactionStatus'], true));
                            }
                            echo json_encode($response);
                            return false;
                        } else {

                            /* process the order and mark it as received */
                            $order = fetch_orders($order_id, false, false, false, false, false, false, false);
                            if (isset($order['order_data'][0]['user_id'])) {
                                $user = fetch_details('users', ['id' => $order['order_data'][0]['user_id']]);
                                $overall_total = array(
                                    'total_amount' => $order['order_data'][0]['total'],
                                    'delivery_charge' => $order['order_data'][0]['delivery_charge'],
                                    'tax_amount' => $order['order_data'][0]['total_tax_amount'],
                                    'tax_percentage' => $order['order_data'][0]['total_tax_percent'],
                                    'discount' => $order['order_data'][0]['promo_discount'],
                                    'wallet' => $order['order_data'][0]['wallet_balance'],
                                    'final_total' => $order['order_data'][0]['final_total'],
                                    'otp' => $order['order_data'][0]['otp'],
                                    'address' => $order['order_data'][0]['address'],
                                    'payment_method' => $order['order_data'][0]['payment_method'],
                                );

                                $overall_order_data = array(
                                    'cart_data' => $order['order_data'][0]['order_items'],
                                    'order_data' => $overall_total,
                                    'subject' => 'Order received successfully',
                                    'user_data' => $user[0],
                                    'system_settings' => $system_settings,
                                    'user_msg' => 'Hello, Dear ' . ucfirst($user[0]['username']) . ', We have received your order successfully. Your order summaries are as followed',
                                    'otp_msg' => 'Here is your OTP. Please, give it to delivery boy only while getting your order.',
                                );

                                if (isset($user[0]['email']) && !empty($user[0]['email'])) {
                                    send_mail($user[0]['email'], 'Order received successfully', $this->load->view('admin/pages/view/email-template.php', $overall_order_data, true));
                                }
                                /* No need to add because the transaction is already added just update the transaction status */
                                if (!empty($transaction)) {
                                    $transaction_id = $transaction[0]['id'];
                                    update_details(['status' => 'success'], ['id' => $transaction_id], 'transactions');
                                } else {
                                    /* add transaction of the payment */
                                    $amount = ($data['Data']['InvoiceValueInBaseCurrency']);
                                    $data = [
                                        'transaction_type' => 'transaction',
                                        'user_id' => $user_id,
                                        'order_id' => $order_id,
                                        'type' => 'my fatoorah',
                                        'txn_id' => $txn_id,
                                        'amount' => $amount,
                                        'status' => 'success',
                                        'message' => 'order placed successfully',
                                    ];
                                    $this->transaction_model->add_transaction($data);
                                }

                                update_details(['active_status' => 'received'], ['order_id' => $order_id], 'order_items');
                                $status = json_encode(array(array('received', date("d-m-Y h:i:sa"))));
                                update_details(['status' => $status], ['order_id' => $order_id], 'order_items', false);

                                // place order custome notification on payment success

                                $custom_notification = fetch_details('custom_notifications', ['type' => "place_order"], '');
                                $hashtag_order_id = '< order_id >';
                                $string = json_encode($custom_notification[0]['title'], JSON_UNESCAPED_UNICODE);
                                $hashtag = html_entity_decode($string);
                                $data1 = str_replace($hashtag_order_id, $order_id, $hashtag);
                                $title = output_escaping(trim($data1, '"'));
                                $hashtag_application_name = '< application_name >';
                                $string = json_encode($custom_notification[0]['message'], JSON_UNESCAPED_UNICODE);
                                $hashtag = html_entity_decode($string);
                                $data2 = str_replace($hashtag_application_name, $system_settings['app_name'], $hashtag);
                                $message = output_escaping(trim($data2, '"'));

                                $fcm_admin_subject = (!empty($custom_notification)) ? $title : 'New order placed ID #' . $order_id;
                                $fcm_admin_msg = (!empty($custom_notification)) ? $message : 'New order received for  ' . $system_settings['app_name'] . ' please process it.';
                                $user_fcm = fetch_details('users', ['id' => $user_id], 'fcm_id,mobile,email,platform_type');
                                // Step 1: Group by platform
                                $groupedByPlatform = [];
                                foreach ($user_fcm as $item) {
                                    $platform = $item['platform_type'];
                                    $groupedByPlatform[$platform][] = $item['fcm_id'];
                                }

                                // Step 2: Chunk each platform group into arrays of 1000
                                $user_fcm_ids = [];
                                foreach ($groupedByPlatform as $platform => $fcmIds) {
                                    $user_fcm_ids[$platform] = array_chunk($fcmIds, 1000);
                                }

                                $user_fcm_id[0] = $user_fcm_ids[0]['fcm_id'];
                                // $user_fcm_id[0][] = $user_fcm[0]['fcm_id'];
                                $firebase_project_id = $this->data['firebase_project_id'];
                                $service_account_file = $this->data['service_account_file'];
                                if (!empty($user_fcm_id) && isset($firebase_project_id) && isset($service_account_file) && !empty($firebase_project_id) && !empty($service_account_file)) {
                                    $fcmMsg = array(
                                        'title' => $fcm_admin_subject,
                                        'body' => $fcm_admin_msg,
                                        'type' => "place_order",
                                    );
                                    send_notification($fcmMsg, $user_fcm_id, $fcmMsg);
                                }
                                notify_event(
                                    'place_order',
                                    ["customer" => [$user_fcm[0]['email']]],
                                    ["customer" => [$user_fcm[0]['mobile']]],
                                    ["orders.id" => $order_id]
                                );
                                // update_stock($order['order_data'][0]['product_variant_ids'], $order['order_data'][0]['quantity'], 'plus');
                            }
                        }
                    } else {
                        log_message('error', 'My Fatoorah Order id not found --> ' . var_export($data['data'], true));
                        /* No order ID found */
                    }

                    $response['error'] = false;
                    $response['transaction_status'] = $data['Data']['TransactionStatus'];
                    $response['message'] = "Transaction successfully done";
                    echo json_encode($response);
                    return false;
                }
            }


            // $this->$data['Event']($data['Data']);

        }
    }


    public function validateSignature($body, $secret, $MyFatoorah_Signature)
    {

        if ($body['Event'] == 'RefundStatusChanged') {
            unset($body['Data']['GatewayReference']);
        }
        $data = $body['Data'];

        //1- Order all data properties in alphabetic and case insensitive.
        uksort($data, 'strcasecmp');

        //2- Create one string from the data after ordering it to be like that key=value,key2=value2 ...
        $orderedData = implode(
            ',',
            array_map(
                function ($v, $k) {
                    return sprintf("%s=%s", $k, $v);
                },
                $data,
                array_keys($data)
            )
        );

        //4- Encrypt the string using HMAC SHA-256 with the secret key from the portal in binary mode.
        //Generate hash string
        $result = hash_hmac('sha256', $orderedData, $secret, true);

        //5- Encode the result from the previous point with base64.
        $hash = base64_encode($result);

        error_log(PHP_EOL . date('d.m.Y h:i:s') . ' - Generated Signature  - ' . $hash, 3, './webhook.log');
        error_log(PHP_EOL . date('d.m.Y h:i:s') . ' - MyFatoorah-Signature - ' . $MyFatoorah_Signature, 3, './webhook.log');

        //6- Compare the signature header with the encrypted hash string. If they are equal, then the request is valid and from the MyFatoorah side.
        if ($MyFatoorah_Signature === $hash) {
            error_log(PHP_EOL . date('d.m.Y h:i:s') . ' - Signature is valid ', 3, './webhook.log');

            // log_message('error', $body);
            // log_message('error', $result);

            log_message("error", "SIGNATURE MATCHED");
            return true;
        } else {
            error_log(PHP_EOL . date('d.m.Y h:i:s') . ' - Signature is not valid ', 3, './webhook.log');
            exit;
        }
    }


    // ------------------------------------------------ MyFatoorah PAYMENT GATEWAY END ------------------------------------------


    //shiprocket webhook
    public function spr_webhook()
    {
        $shiprocket_settings = get_settings('shipping_method', true);
        $token = $shiprocket_settings['webhook_token'];
        $this->load->library(['Shiprocket']);
        $request = file_get_contents('php://input');

        log_message('error', 'Shiprocket file webhook--> ' . var_export($request, true));

        if ($request === false || empty($request)) {
            $this->edie("Error in reading Post Data");
        }
        $request = json_decode($request, true);
        log_message('error', 'Shiprocket webhook--> ' . var_export($request, true));

        if (isset($_SERVER['HTTP_X_API_KEY']) && !empty($_SERVER['HTTP_X_API_KEY'])) {
            if ($token == $_SERVER['HTTP_X_API_KEY']) {
                if (isset($request['awb']) && !empty($request['awb'])) {

                    if (strtolower($request['current_status']) == "delivered") {
                        $order_details = fetch_details('order_tracking', ['awb_code' => $request['awb']], 'order_id');
                        if (!empty($order_details)) {
                            $order_id = $order_details[0]['order_id'];
                            log_message('error', 'Shiprocket webhook order id --> ' . var_export($order_id, true));
                            if (!empty($order_id)) {
                                $status = json_encode(array(array('delivered', date("d-m-Y h:i:sa"))));
                                update_details(['active_status' => 'delivered'], ['id' => $order_id], 'orders');
                                update_details(['status' => $status], ['id' => $order_id], 'orders', false);
                                $res['error'] = false;
                                $res['message'] = "order Updated successfully";
                                echo json_encode($res);
                                return false;
                            } else {
                                $res['error'] = true;
                                $res['message'] = "order not updated";
                                echo json_encode($res);
                                return false;
                            }
                        } else {
                            $res['error'] = true;
                            $res['message'] = "order not found";
                            echo json_encode($res);
                            return false;
                        }
                    } else if (strtolower($request['current_status']) == "canceled") {
                        $order_details = fetch_details('order_tracking', ['awb_code' => $request['awb']], 'order_id');
                        if (!empty($order_details)) {
                            $order_id = $order_details[0]['order_id'];
                            log_message('error', 'Shiprocket webhook order id --> ' . var_export($order_id, true));
                            if (!empty($order_id)) {
                                $status = json_encode(array(array('cancelled', date("d-m-Y h:i:sa"))));
                                update_details(['active_status' => 'cancelled'], ['id' => $order_id], 'orders');
                                update_details(['status' => $status], ['id' => $order_id], 'orders', false);
                                $res['error'] = false;
                                $res['message'] = "order Updated successfully";
                                echo json_encode($res);
                                return false;
                            } else {
                                $res['error'] = true;
                                $res['message'] = "order not updated";
                                echo json_encode($res);
                                return false;
                            }
                        } else {
                            $res['error'] = true;
                            $res['message'] = "order not found";
                            echo json_encode($res);
                            return false;
                        }
                    }
                } else {
                    $res['error'] = true;
                    $res['message'] = "awb not found";
                    echo json_encode($res);
                    return false;
                }
            } else {
                $res['error'] = true;
                $res['message'] = "token is  not veified";
                echo json_encode($res);
                return false;
            }
        } else {
            $res['error'] = true;
            $res['message'] = "token is required";
            echo json_encode($res);
            return false;
        }
    }

    // ------------------------------------------------ Instamojo PAYMENT GATEWAY ------------------------------------------


    public function instamojo_webhook()
    {
        $this->load->library(['instamojo']);
        $system_settings = get_settings('system_settings', true);
        $request = file_get_contents('php://input');

        // $request = json_decode($request, true);

        log_message('error', 'Shiprocket file webhook--> ' . var_export($request, true));
        log_message('error', 'Shiprocket file webhook--> ' . var_export($_POST['purpose'], true));


        $txn_id = (isset($_POST['payment_id'])) ? $_POST['payment_id'] : "";

        if (!empty($txn_id)) {

            $transaction = fetch_details('transactions', ['txn_id' => $txn_id], '*');

            $amount = $_POST['amount'];
        } else {
            $amount = 0;
        }

        if (!empty($transaction)) {
            $order_id = $_POST['purpose'];
            log_message('error', 'razorpay Webhook | transaction order id --> ' . var_export($order_id, true));
            $user_id = $transaction[0]['user_id'];
        } else {
            $order_id = 0;
            $order_id = ($order_id = $_POST['purpose']) ? $order_id = $_POST['purpose'] : $order_id = $_POST['purpose'];
            $order_data = fetch_orders($order_id);
            $user_id = (isset($order_data['order_data'][0]['user_id'])) ? $order_data['order_data'][0]['user_id'] : "";
        }

        $this->load->model('transaction_model');
        if ($_POST['status'] == 'Credit' || $_POST['status'] == 'credit') {

            if (!empty($order_id)) {
                /* To do the wallet recharge if the order id is set in the patter */
                if (strpos($order_id, "wallet-refill-user") !== false) {
                    if (!is_numeric($order_id) && strpos($order_id, "wallet-refill-user") !== false) {
                        $temp = explode("-", $order_id);
                        if (isset($temp[3]) && is_numeric($temp[3]) && !empty($temp[3] && $temp[3] != '')) {
                            $user_id = $temp[3];
                        } else {
                            $user_id = 0;
                        }
                    }

                    $data['transaction_type'] = "wallet";
                    $data['user_id'] = $user_id;
                    $data['order_id'] = $order_id;
                    $data['type'] = "credit";
                    $data['txn_id'] = $txn_id;
                    $data['amount'] = $amount;
                    $data['status'] = "success";
                    $data['message'] = "Wallet refill successful";

                    $this->transaction_model->add_transaction($data);

                    $this->load->model('customer_model');
                    if ($this->customer_model->update_balance($amount, $user_id, 'add')) {
                        $response['error'] = false;
                        $response['transaction_status'] = $_POST['status'];
                        $response['message'] = "Wallet recharged successfully!";
                    } else {
                        $response['error'] = true;
                        $response['transaction_status'] = $_POST['status'];
                        $response['message'] = "Wallet could not be recharged!";
                    }
                    echo json_encode($response);
                    return false;
                } else {

                    /* process the order and mark it as received */
                    $order = fetch_orders($order_id, false, false, false, false, false, false, false);

                    if (isset($order['order_data'][0]['user_id'])) {
                        $user = fetch_details('users', ['id' => $order['order_data'][0]['user_id']]);
                        $overall_total = array(
                            'total_amount' => $order['order_data'][0]['total'],
                            'delivery_charge' => $order['order_data'][0]['delivery_charge'],
                            'tax_amount' => $order['order_data'][0]['total_tax_amount'],
                            'tax_percentage' => $order['order_data'][0]['total_tax_percent'],
                            'discount' =>  $order['order_data'][0]['promo_discount'],
                            'wallet' =>  $order['order_data'][0]['wallet_balance'],
                            'final_total' =>  $order['order_data'][0]['final_total'],
                            'otp' => $order['order_data'][0]['otp'],
                            'address' =>  $order['order_data'][0]['address'],
                            'payment_method' => $order['order_data'][0]['payment_method']
                        );

                        $overall_order_data = array(
                            'cart_data' => $order['order_data'][0]['order_items'],
                            'order_data' => $overall_total,
                            'subject' => 'Order received successfully',
                            'user_data' => $user[0],
                            'system_settings' => $system_settings,
                            'user_msg' => 'Hello, Dear ' . ucfirst($user[0]['username']) . ', We have received your order successfully. Your order summaries are as followed',
                            'otp_msg' => 'Here is your OTP. Please, give it to delivery boy only while getting your order.',
                        );
                        if (isset($user[0]['email']) && !empty($user[0]['email'])) {
                            send_mail($user[0]['email'], 'Order received successfully', $this->load->view('admin/pages/view/email-template.php', $overall_order_data, TRUE));
                        }
                        /* No need to add because the transaction is already added just update the transaction status */
                        if (!empty($transaction)) {
                            $transaction_id = $transaction[0]['id'];
                            update_details(['status' => 'success'], ['id' => $transaction_id], 'transactions');
                        } else {
                            /* add transaction of the payment */
                            $amount = ($request['payload']['payment']['entity']['amount'] / 100);
                            $data = [
                                'transaction_type' => 'transaction',
                                'user_id' => $user_id,
                                'order_id' => $order_id,
                                'type' => 'razorpay',
                                'txn_id' => $txn_id,
                                'amount' => $amount,
                                'status' => 'success',
                                'message' => 'order placed successfully',
                            ];
                            $this->transaction_model->add_transaction($data);
                        }

                        update_details(['active_status' => 'received'], ['order_id' => $order_id], 'order_items');
                        $status = json_encode(array(array('received', date("d-m-Y h:i:sa"))));
                        update_details(['status' => $status], ['order_id' => $order_id], 'order_items', false);

                        // place order custome notification on payment success

                        $custom_notification = fetch_details('custom_notifications', ['type' => "place_order"], '');
                        $hashtag_order_id = '< order_id >';
                        $string = json_encode($custom_notification[0]['title'], JSON_UNESCAPED_UNICODE);
                        $hashtag = html_entity_decode($string);
                        $data1 = str_replace($hashtag_order_id, $order_id, $hashtag);
                        $title = output_escaping(trim($data1, '"'));
                        $hashtag_application_name = '< application_name >';
                        $string = json_encode($custom_notification[0]['message'], JSON_UNESCAPED_UNICODE);
                        $hashtag = html_entity_decode($string);
                        $data2 = str_replace($hashtag_application_name, $system_settings['app_name'], $hashtag);
                        $message = output_escaping(trim($data2, '"'));

                        $fcm_admin_subject = (!empty($custom_notification)) ? $title : 'New order placed ID #' . $order_id;
                        $fcm_admin_msg = (!empty($custom_notification)) ? $message : 'New order received for  ' . $system_settings['app_name'] . ' please process it.';
                        $user_fcm = fetch_details('users', ['id' => $user_id], 'fcm_id,mobile,email,platform_type');
                        // Step 1: Group by platform
                        $groupedByPlatform = [];
                        foreach ($user_fcm as $item) {
                            $platform = $item['platform_type'];
                            $groupedByPlatform[$platform][] = $item['fcm_id'];
                        }

                        // Step 2: Chunk each platform group into arrays of 1000
                        $user_fcm_ids = [];
                        foreach ($groupedByPlatform as $platform => $fcmIds) {
                            $user_fcm_ids[$platform] = array_chunk($fcmIds, 1000);
                        }

                        $user_fcm_id[0] = $user_fcm_ids[0]['fcm_id'];
                        // $user_fcm_id[0][] = $user_fcm[0]['fcm_id'];
                        $firebase_project_id = $this->data['firebase_project_id'];
                        $service_account_file = $this->data['service_account_file'];
                        if (!empty($user_fcm_id) && isset($firebase_project_id) && isset($service_account_file) && !empty($firebase_project_id) && !empty($service_account_file)) {
                            $fcmMsg = array(
                                'title' => $fcm_admin_subject,
                                'body' => $fcm_admin_msg,
                                'type' => "place_order",
                            );
                            send_notification($fcmMsg, $user_fcm_id, $fcmMsg);
                        }
                        notify_event(
                            'place_order',
                            ["customer" => [$user_fcm[0]['email']]],
                            ["customer" => [$user_fcm[0]['mobile']]],
                            ["orders.id" => $order_id]
                        );
                        update_stock($order['order_data'][0]['product_variant_ids'], $order['order_data'][0]['quantity'], 'plus');
                    }
                }
            } else {
                log_message('error', 'Razorpay Order id not found --> ' . var_export($request, true));
                /* No order ID found */
            }

            $response['error'] = false;
            $response['transaction_status'] = $request['event'];
            $response['message'] = "Transaction successfully done";
            echo json_encode($response);
            return false;
        } elseif ($_POST['status'] == 'Failed' || $_POST['status'] == 'failed') {
            //$order = fetch_orders($order_id, false, false, false, false, false, false, false);

            if (!empty($order_id)) {
                // update_stock($order['order_data'][0]['product_variant_ids'], $order['order_data'][0]['quantity'], 'plus');
                update_details(['active_status' => 'cancelled'], ['order_id' => $order_id], 'order_items');
            }
            /* No need to add because the transaction is already added just update the transaction status */
            if (!empty($transaction)) {
                $transaction_id = $transaction[0]['id'];
                update_details(['status' => 'failed'], ['id' => $transaction_id], 'transactions');
            }
            $response['error'] = true;
            $response['transaction_status'] = $_POST['status'];
            $response['message'] = "Transaction is failed. ";

            echo json_encode($response);
            return false;
        } else {
            $response['error'] = true;
            $response['transaction_status'] = $_POST['status'];
            $response['message'] = "Transaction could not be detected.";
            echo json_encode($response);
            return false;
        }
    }

    // ------------------------------------------------ PHONEPE PAYMENT GATEWAY ------------------------------------------

    public function phonepe_webhook()
    {
        $this->load->library(['Phonepe']);
        $system_settings = get_settings('system_settings', true);
        $request = file_get_contents('php://input');

        $request = (json_decode($request, 1));
        $request = (isset($request['response'])) ? $request['response'] : "";
        log_message('error', 'phonepe file webhook--> ' . var_export($request, true));
        if (!empty($request)) {

            $request = base64_decode($request);
            $request = json_decode($request, 1);
            // log_message('error', 'phonepe server webhook--> ' . var_export($_SERVER, true));

            $txn_id = (isset($request['data']['merchantTransactionId'])) ? $request['data']['merchantTransactionId'] : "";
            if (!empty($txn_id)) {
                $transaction = fetch_details('transactions', ['txn_id' => $txn_id], '*');
                if (empty($transaction)) {
                    $transaction = fetch_details('transactions', ['order_id' => $txn_id], '*');
                }
                $amount = $request['data']['amount'] / 100;
            } else {
                $amount = 0;
            }
            if (!empty($transaction)) {
                $user_id = $transaction[0]['user_id'];
                $transaction_type = (isset($transaction[0]['transaction_type'])) ? $transaction[0]['transaction_type'] : "";
                $order_id = (isset($transaction[0]['order_id'])) ? $transaction[0]['order_id'] : "";
                log_message('error', 'Phonepe Webhook | transaction_type --> ' . var_export($transaction_type, true));
                log_message('error', 'Phonepe Webhook | transaction order id --> ' . var_export($order_id, true));
            } else {
                log_message('error', 'Phonepe transaction id not found in local database--> ' . var_export($request, true));
                die;
            }

            $status = (isset($request['code'])) ? $request['code'] : "";

            $this->load->model('transaction_model');

            $check_status = $this->phonepe->check_status($txn_id);
            $txn_id = $transaction[0]['txn_id'];
            if ($check_status['success'] == true) {
                if ($status == 'PAYMENT_SUCCESS') {
                    $data['status'] = "success";
                    if ($transaction_type == "wallet") {
                        $data['status'] = "success";
                        $data['message'] = "Wallet refill successful";

                        $this->transaction_model->update_transaction($data, $txn_id);

                        $this->load->model('customer_model');
                        if (!$this->customer_model->update_balance($amount, $user_id, 'add')) {

                            log_message('error', 'Phonepe Webhook | couldn\'t update in wallet balance  --> ' . var_export($request, true));
                            die;
                        }

                        return false;
                    } elseif ($transaction_type == "transaction") {
                        $data['message'] = "Payment received successfully";

                        update_details(['active_status' => 'received'], ['order_id' => $order_id], 'order_items');
                        $order_status = json_encode(array(array('received', date("d-m-Y h:i:sa"))));
                        update_details(['status' => $order_status], ['order_id' => $order_id], 'order_items', false);
                        update_details(['status' => 'received'], ['id' => $order_id], 'orders', false);
                    }
                    $this->transaction_model->update_transaction($data, $txn_id);
                } elseif ($status == "BAD_REQUEST"  || $status == "AUTHORIZATION_FAILED" || $status == "PAYMENT_ERROR" || $status == "TRANSACTION_NOT_FOUND" || $status == "PAYMENT_DECLINED" || $status == "TIMED_OUT") {
                    $data['status'] = "failed";
                    if ($transaction_type == "wallet") {
                        $data['status'] = "failed";
                        $data['message'] = "Wallet could not be recharged!";

                        $this->transaction_model->update_transaction($data, $txn_id);
                    } elseif ($transaction_type == "transaction") {
                        update_details(['active_status' => 'cancelled'], ['order_id' => $order_id], 'order_items');
                        $data = fetch_details('order_items', ['id' => $order_id], 'product_variant_id,quantity');
                        update_stock($data[0]['product_variant_id'], $data[0]['quantity'], 'plus');
                        $order_status = json_encode(array(array('cancelled', date("d-m-Y h:i:sa"))));

                        update_details(['status' => $order_status], ['order_id' => $order_id], 'order_items', false);
                        update_details(['status' => 'cancelled'], ['id' => $order_id], 'orders', false);

                        $data['message'] = "Payment couldn't be processed!";
                    }
                    $this->transaction_model->update_transaction($data, $txn_id);
                }
            } else {
                log_message(
                    'error',
                    'Phonepe transaction id not found in phonepe--> ' . var_export($request, true)
                );
            }
        } else {
            log_message('error', 'No Request Found--> ' . var_export(
                $request,
                true
            ));
        }
    }
}