HEX
Server: Apache
System: Linux host60.registrar-servers.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
User: wwwrenee (3804)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: /home/wwwrenee/www/wp-content/plugins/mpesa-woo-rene/src/Utilities.php
<?php

/**
 * @package MPesa For WooCommerce
 * @subpackage WooCommerce Mpesa Gateway
 * @author Osen Concepts < hi@osen.co.ke >
 * @since 0.18.01
 */

namespace Osen\Woocommerce;

use Osen\Woocommerce\Mpesa\C2B;
use Osen\Woocommerce\Mpesa\STK;

class Utilities
{
    public function __construct()
    {
        add_action('init', array($this, 'wc_mpesa_rewrite_add_rewrites'));
        add_filter('query_vars', array($this, 'wc_mpesa_rewrite_add_var'));
        add_action('template_redirect', array($this, 'wc_mpesa_process_ipn'));

        //add_filter('manage_edit-shop_order_columns', 'wcmpesa_new_order_column');
        add_action('manage_shop_order_custom_column', array($this, 'shop_order_payments_table_column_content'), 10);
        add_filter('woocommerce_email_attachments', array($this, 'woocommerce_emails_attach_downloadables'), 10, 3);
        add_action('woocommerce_thankyou_mpesa', array($this, 'request_body'));
        add_action('woocommerce_thankyou_mpesa', array($this, 'validate_payment'));
    }

    public function validate_payment($order_id)
    {
        $mpesa  = get_option('woocommerce_mpesa_settings');
        $idtype = (new C2B)->type;
        $url    = home_url('?pesaipn&order=');
        $url2    = home_url('?lipwa=query&order=');

        if (wc_get_order($order_id)) {
            $order     = new \WC_Order($order_id);
            $total     = $order->get_total();
            $reference = $order_id;
        }

        $type = ($idtype == 4) ? 'Pay Bill' : 'Buy Goods and Services'; ?>
        <style>
            @keyframes wave {
                0%,
                60%,
                100% {
                    transform: initial;
                }

                30% {
                    transform: translateY(-15px);
                }
            }

            @keyframes blink {
                0% {
                    opacity: .2;
                }

                20% {
                    opacity: 1;
                }

                100% {
                    opacity: .2;
                }
            }

            .saving span {
                animation: blink 1.4s linear infinite;
                animation-fill-mode: both;
            }

            .saving span:nth-child(2) {
                animation-delay: .2s;
            }

            .saving span:nth-child(3) {
                animation-delay: .4s;
            }
        </style>
        <section class="woocommerce-order-details" id="resend_stk">
            <input type="hidden" id="current_order" value="<?php echo $order_id; ?>">
            <input type="hidden" id="payment_method" value="<?php echo $order->get_payment_method(); ?>">
            <style>
              .spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;-webkit-animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}
              </style>
              <div id="border-mpesa" style="display: none;padding:5px;border:1px solid #00A699;border-radius:8px;">
                <p class="checking" id="mpesa_receipt" align="center" style="color: #3498db;font-size:120%;padding: 10px;">CONFIRMING PAYMENT<span style='color: #3498db; margin-left: 10px;' class='spinner-border spinner-border' role='status' aria-hidden='true'></span></p>
              </div>
            </div>
            <!-- <br> -->
        </section>
        <?php if (isset($mpesa['enable_c2b']) && $mpesa['enable_c2b'] == 'yes') : ?>
            <section class="woocommerce-order-details" id="missed_stk">
                <table class="woocommerce-table woocommerce-table--order-details shop_table order_details">
                    <thead>
                        <tr>
                            <th class="woocommerce-table__product-name product-name">
                                <?php _e("STK Push didn't work? Pay Manually Via M-PESA"); ?>
                            </th>
                        </tr>
                    </thead>

                    <tbody>
                        <tr class="woocommerce-table__line-item order_item">
                            <td class="woocommerce-table__product-name product-name">
                                <ol>
                                    <li>Select <b>Lipa na M-PESA</b>.</li>
                                    <li>Select <b><?php echo $type; ?></b>.</li>
                                    <?php if ($idtype == 4) : ?>
                                        <li>Enter <b><?php echo (new C2B)->shortcode; ?></b> as business no.</li>
                                        <li>Enter <b><?php echo $reference; ?></b> as Account no.</li>
                                    <?php else : ?>
                                        <li>Enter <b><?php echo (new C2B)->shortcode; ?></b> as till no.</li>
                                    <?php endif; ?>
                                    <li>Enter Amount <b><?php echo round($total); ?></b>.</li>
                                    <li>Enter your M-PESA PIN</li>
                                    <li>Confirm your details and press OK.</li>
                                    <li>Wait for a confirmation message from M-PESA.</li>
                                    <li>After completing the payment, click the button below to recheck order status.</li>
                                    <button class="button alt" onClick="window.location.reload();">Refresh</button>
                                </ol>

                            </td>
                        </tr>
                    </tbody>
                </table>
            </section><?php endif;

            echo <<<JS
            <script id="pesaipn-checker">
                jQuery(document).ready(function($) {
                    $("#border-mpesa").css("border", "1px solid #00A699");
                    $("#border-mpesa").css("border-radius", "8px");
                    $("#confirming").fadeOut(2000);
                    $('#renitiate-form').submit(function(e){
                        e.preventDefault();

                        var form = $(this);

                        $.post(form.attr('action'), form.serialize(), function(response){
                            $("#mpesa_receipt")
                            .html('STK Resent. Confirming payment <span>.</span><span>.</span><span>.</span><span>.</span><span>.</span><span>.</span>');
                        });
                    });

                    var checker = setInterval(() => {
                        if ($("#payment_method").length && $("#payment_method").val() !== 'mpesa') {
                            clearInterval(checker);
                        }

                        if ($("#current_order").length) {
                            var order = $("#current_order").val();
                            if (order.length) {
                                $.get("{$url}" + order, [], function(data) {
                                    if (data.receipt == '' || data.receipt == 'N/A') {
                                        $("#mpesa_receipt").html("CONFIRMING PAYMENT...");
                                        $("#mpesa_receipt").css("color", "#3498db");
                                        $("#loader").show();
                                        $("#renitiate-mpesa-table").fadeOut(2000);
                                    } else {
                                        if ($("#mpesa-receipt-overview").length) {} else {
                                            $(".woocommerce-order-overview").append(
                                                '<li id="mpesa-receipt-overview" class="woocommerce-order-overview__payment-method method">Receipt number: <strong>' +
                                                data.receipt +
                                                '</strong></li>'
                                            );
                                        }

                                        if ($("#mpesa-receipt-table-row").length) {} else {
                                            $(".woocommerce-table--order-details > tfoot")
                                                .find('tr:last-child')
                                                .prev()
                                                .after(
                                                    '<tr id="mpesa-receipt-table-row"><th scope="row">Receipt number:</th><td>' +
                                                    data.receipt +
                                                    '</td></tr>'
                                                );
                                        }

                                        if (data.receipt == 'fail') {
                                            $("#border-mpesa").css("border", "1px solid #FF5A5F");
                                            $("#border-mpesa").css("border-radius", "8px");
                                            $("#mpesa_receipt").html(
                                                '<b>' +
                                                data.note.content +
                                                '</b><i style="margin-left:5px;" class="fa fa-exclamation-circle" aria-hidden="true"></i>'
                                            );
                                            $("#mpesa_receipt").css("color", "#FF5A5F");
                                            $("#loader").hide();
                                            $("#renitiate-mpesa-table").fadeIn(2000);
                                        } else {
                                            $("#border-mpesa").css("border", "1px solid #00A699");
                                            $("#border-mpesa").css("border-radius", "8px");
                                            $("#mpesa_receipt").html(
                                                'Mpesa Payment confirmed. Receipt number: <b>' +
                                                data.receipt +
                                                '</b><i style="margin-left:5px;" class="fa fa-check-circle" aria-hidden="true"></i>'

                                            );
                                            $("#mpesa_receipt").css("color", "green");
                                            $("#loader").hide();
                                            $("#renitiate-mpesa-table").fadeOut(2000);
                                            $("#missed_stk").fadeOut(2000);
                                            $("#renitiate-button").fadeOut(2000);
                                            $("#mpesa_request").fadeOut(2000);
                                            $("#confirming").fadeOut(2000);
                                        }

                                        clearInterval(checker);
                                        return false;
                                    }
                                });
                            }
                        }
                    },
                    100);
                });
            </script>
JS;
    }

    public function wc_mpesa_rewrite_add_rewrites()
    {
        add_rewrite_rule('lipwa/([^/]*)/?', 'index.php?lipwa=$matches[1]', 'top');
    }

    public function wc_mpesa_rewrite_add_var($vars)
    {
        array_push($vars, 'lipwa');
        return $vars;
    }

    public function wc_mpesa_process_ipn()
    {
        $mpesa = get_option('woocommerce_mpesa_settings', []);

        if (get_query_var('lipwa')) {
            header("Access-Control-Allow-Origin: *");
            header("Content-Type: Application/json");

            $action = get_query_var('lipwa', 'something_ominous');

            switch ($action) {
                case "request":
                    $order_id   = sanitize_text_field($_POST['order']);
                    $order      = new \WC_Order($order_id);
                    $total      = $order->get_total();
                    $phone      = $order->get_billing_phone();
                    $first_name = $order->get_billing_first_name();
                    $last_name  = $order->get_billing_last_name();
                    $result     = (new STK)->request($phone, $total, $order_id, get_bloginfo('name') . ' Purchase', 'WCMPesa');
                    $post       = wc_mpesa_post_id_by_meta_key_and_value('_order_id', $order_id);
                    if (wc_get_order($order_id)) {
                      $request_id = $result['MerchantRequestID'];
                      $checkoutid = $result['CheckoutRequestID'];
                      $order->update_status('pending');
                      update_post_meta($order_id, '_request_id', $request_id);
                      update_post_meta($post, '_request_id', $request_id);
					  update_post_meta($post, '_checkout_id', $checkoutid);
                      update_post_meta($order_id, '_checkout_id', $checkoutid);
                      update_post_meta($order_id, '_receipt', 'N/A');
                    }
                    wp_send_json($result);
                    break;
                case "validate":
                    exit(wp_send_json(
                        (new STK)->validate()
                    ));
                    break;

                case "query":
                      $order_id  = sanitize_text_field($_GET['order']);
                      $order     = new \WC_Order($order_id);
                      $checkoutRequestID = get_post_meta($order_id, '_checkout_id', 1);
                      $merchantRequestID = get_post_meta($order_id, '_request_id', 1);
                      $result    = (new STK)->query($checkoutRequestID);
                      if (wc_get_order($order_id)) {
                         if ($order->get_status() === 'completed' || $order->get_status() === 'failed' || $order->get_status() === 'processing') {
                          exit(wp_send_json(['Error' => 'Order '.$order->get_status()]));
                      }else{
                        update_post_meta($order_id, '_receipt', 'N/A');
                      }

                      if (isset($result['ResultCode'])) {
                        if ($result['ResultCode'] == 0) {
                           $order = new \WC_Order($order_id);
                           $order->set_transaction_id($merchantRequestID);
                           $order->update_status(
                            ($settings['completion'] ?? get_post_meta($order_id, '_order_completion', true)),
                            __("Full M-Pesa Payment Received. Transaction ID {$merchantRequestID}.")
                           );
                           update_post_meta($order_id, '_receipt', $merchantRequestID);
                           $order->save();
                           WC()->cart->empty_cart();
                           /**
                            * Reduce stock levels
                            */

                           // wc_reduce_stock_levels($order_id);
                           exit(wp_send_json(['Success' => 'Payment Complete']));
                        }else{
                          $order->update_status(
                           'failed',
                           __("{$result['ResultDesc']}.")
                          );
                          update_post_meta($order_id, '_receipt', 'fail');
                          exit(wp_send_json(['Error' => $result['ResultDesc']]));

                        }
                        return true;
                      }elseif (isset($result['errorCode'])) {
                        if ($result['errorMessage'] == "The transaction is being processed") {
                          exit(wp_send_json(['Error' => 'Payment being processed']));
                          return;
                        }else {
                          $order->update_status(
                           'failed',
                           __("{$result['errorMessage']}.")
                          );
                          $order->update_status('failed');
                          update_post_meta($order_id, '_receipt', 'fail');
                          exit(wp_send_json(['Error' => $result['errorMessage']]));
                        }
                        return true;
                      }
                      return false;
                      }

                      break;

                case "confirm":
                    $response = json_decode(file_get_contents('php://input'), true);

                    if (!$response || empty($response)) {
                        exit(wp_send_json(
                            ['Error' => 'No response data received']
                        ));
                    }
                    if($_GET['sign'] != 'bc97aba4529d9f0d4575f31345a8dc2134'){
                      exit(wp_send_json(
                          ['Error' => 'Not authorized']
                      ));
                    }

                    $mpesaReceiptNumber = $response['TransID'];
                    $transactionDate    = $response['TransTime'];
                    $amount             = $response['TransAmount'];
                    $BillRefNumber      = $response['BillRefNumber'];
                    $phone              = $response['MSISDN'];
                    $FirstName          = $response['FirstName'];
                    $MiddleName         = $response['MiddleName'];
                    $LastName           = $response['LastName'];

                    $post = wc_mpesa_post_id_by_meta_key_and_value('_reference', $BillRefNumber);
                    if (!$post) {
                        $post_id = wp_insert_post(
                            array(
                                'post_title'   => 'C2B',
                                'post_status'  => 'publish',
                                'post_type'    => 'mpesaipn',
                                'post_author'  => 1,
                            )
                        );

                        update_post_meta($post_id, '_customer', "{$FirstName} {$MiddleName} {$LastName}");
                        update_post_meta($post_id, '_phone', $phone);
                        update_post_meta($post_id, '_amount', $amount);
                        update_post_meta($post_id, '_receipt', $mpesaReceiptNumber);
                        update_post_meta($post_id, '_transaction_id', $mpesaReceiptNumber);
                        update_post_meta($post_id, '_transdate', $transactionDate);
                        update_post_meta($post_id, '_billref', $BillRefNumber);
                        update_post_meta($post_id, '_order_status', 'completed');
                    }

                    $order_id        = get_post_meta($post, '_order_id', true);
                    $amount_due      = get_post_meta($post, '_amount', true);
                    $before_ipn_paid = get_post_meta($post, '_paid', true);

                    if (wc_get_order($order_id)) {
                        $order    = new \WC_Order($order_id);
                        $customer = "{$FirstName} {$MiddleName} {$LastName}";
                    } else {
                        $customer = "MPesa Customer";
                    }

                    $after_ipn_paid = round($before_ipn_paid) + round($amount);
                    $ipn_balance    = $after_ipn_paid - $amount_due;

                    if (wc_get_order($order_id)) {
                        $order = new \WC_Order($order_id);
                        $order->set_transaction_id($mpesaReceiptNumber);
                        if ($ipn_balance == 0) {
                            $order->update_status((isset($mpesa['completion']) ? $mpesa['completion'] : 'completed'), __("Full MPesa Payment Received From {$phone}. Receipt Number {$mpesaReceiptNumber}"));
                            update_post_meta($post, '_order_status', 'complete');
                            $order->set_transaction_id($mpesaReceiptNumber);
                            update_post_meta($order_id, '_receipt', $mpesaReceiptNumber);
                            wc_reduce_stock_levels($order_id);
                            $order->save();

                            $headers = 'From: ' . get_bloginfo('name') . ' <' . get_bloginfo('admin_email') . '>' . "\r\n";
                            wp_mail($order->get_billing_email(), 'Your Mpesa payment', 'We acknowledge receipt of your payment via MPesa of KSh. ' . $amount . ' on ' . $transactionDate . 'with receipt Number ' . $mpesaReceiptNumber . '.', $headers);
                        }
                        elseif ($ipn_balance > 0) {
                            $currency = get_woocommerce_currency();
                            $order->update_status((isset($mpesa['completion']) ? $mpesa['completion'] : 'completed'), __("{$phone} has overpayed by {$currency} {$ipn_balance}. Receipt Number {$mpesaReceiptNumber}"));
                            update_post_meta($post, '_order_status', 'complete');
                            $order->set_transaction_id($mpesaReceiptNumber);
                            update_post_meta($order_id, '_receipt', $mpesaReceiptNumber);
                            wc_reduce_stock_levels($order_id);
                            $order->save();
                        }
                         else {
                            $order->update_status('on-hold');
                            $order->add_order_note(__("{$phone} has underpaid by {$currency} {$ipn_balance}. Receipt Number {$mpesaReceiptNumber}"));
                            update_post_meta($post, '_order_status', 'on-hold');
                        }
                    }

                    update_post_meta($post, '_amount', $amount_due);
                    update_post_meta($post, '_paid', $after_ipn_paid);
                    update_post_meta($post, '_balance', $ipn_balance);
                    update_post_meta($post, '_phone', $phone);
                    update_post_meta($post, '_customer', $customer);
                    update_post_meta($post, '_order_id', $order_id);
                    update_post_meta($post, '_receipt', $mpesaReceiptNumber);

                    exit(wp_send_json((new STK)->confirm()));
                    break;

                case "register":
                    (new C2B)->register(function ($response) {
                        $status = isset($response['ResponseDescription']) ? 'success' : 'fail';
                        if ($status == 'fail') {
                            $message = isset($response['errorMessage']) ? $response['errorMessage'] : 'Could not register M-PESA URLs, try again later.';
                            $state   = 'red';
                        } else {
                            $message = isset($response['ResponseDescription']) ? $response['ResponseDescription'] : 'M-PESA URL registered successfully. You will now receive C2B Payment Notifications.';
                            $state   = 'green';
                        }

                        exit(wp_redirect(
                            add_query_arg(
                                array(
                                    'mpesa-urls-registered' => $message,
                                    'reg-state'             => $state,
                                ),
                                wp_get_referer()
                            )
                        ));
                    });

                    break;

                case "reconcile":
                    $response = json_decode(file_get_contents('php://input'), true);

                    if (!isset($_GET['sign'])) {
                        exit(wp_send_json(['Error' => 'No Signature Supplied']));
                    }
                    $sign = sanitize_text_field($_GET['sign']);

                    if ($sign !== $mpesa['signature']) {
                        exit(wp_send_json(['Error' => 'Invalid Signature Supplied']));
                    }

                    if (!isset($response['Body'])) {
                        exit(wp_send_json(['Error' => 'No response data received']));
                    }

                    $resultCode        = $response['Body']['stkCallback']['ResultCode'];
                    $resultDesc        = $response['Body']['stkCallback']['ResultDesc'];
                    $merchantRequestID = $response['Body']['stkCallback']['MerchantRequestID'];
					$checkoutRequestID = $response['Body']['stkCallback']['CheckoutRequestID'];

                    $post = wc_mpesa_post_id_by_meta_key_and_value('_request_id', $merchantRequestID);
					$post = wc_mpesa_post_id_by_meta_key_and_value('_checkout_id', $checkoutRequestID);
                    //wp_update_post(['post_content' => file_get_contents('php://input'), 'ID' => $post]);

                    $order_id        = get_post_meta($post, '_order_id', true);
                    $amount_due      = get_post_meta($post, '_amount', true);
                    $before_ipn_paid = get_post_meta($post, '_paid', true);

                    if (wc_get_order($order_id)) {
                        $order      = new \WC_Order($order_id);
                        $first_name = $order->get_billing_first_name();
                        $last_name  = $order->get_billing_last_name();
                        $customer   = "{$first_name} {$last_name}";
                        if ($order->get_status() === 'completed' || $order->get_status() === 'failed' || $order->get_status() === 'processing') {
                          exit(wp_send_json(['Error' => 'Order '.$order->get_status()]));
                        }

                        if (isset($response['Body']['stkCallback']['CallbackMetadata'])) {
                            $amount             = $response['Body']['stkCallback']['CallbackMetadata']['Item'][0]['Value'];
                            $mpesaReceiptNumber = $response['Body']['stkCallback']['CallbackMetadata']['Item'][1]['Value'];
                            $balance            = $response['Body']['stkCallback']['CallbackMetadata']['Item'][2]['Value'];
                            $transactionDate    = $response['Body']['stkCallback']['CallbackMetadata']['Item'][3]['Value'];
                            $phone              = $response['Body']['stkCallback']['CallbackMetadata']['Item'][4]['Value'];
                            $after_ipn_paid     = round($before_ipn_paid) + round($amount);
                            $ipn_balance        = $after_ipn_paid - $amount_due;

                            if ($ipn_balance == 0) {
                                update_post_meta($post, '_order_status', 'complete');
                                update_post_meta($post, '_receipt', $mpesaReceiptNumber);
                                update_post_meta($order_id, '_receipt', $mpesaReceiptNumber);
                                $order->update_status('processing');
                                $order->add_order_note(__("Full MPesa Payment Received From {$phone}. Receipt Number {$mpesaReceiptNumber}"));
                                update_post_meta($post, '_order_status', 'processing');


                                // $order->update_status((isset($mpesa['completion']) ? $mpesa['completion'] : 'completed'), __("Full MPesa Payment Received From {$phone}. Receipt Number {$mpesaReceiptNumber}"));

                                $headers[] = 'From: ' . get_bloginfo('name') . ' <' . get_bloginfo('admin_email') . '>' . "\r\n";
                                wp_mail($order->get_billing_email(), 'Your Mpesa payment', 'We acknowledge receipt of your payment via MPesa of KSh. ' . $amount . ' on ' . $transactionDate . '. Receipt number ' . $mpesaReceiptNumber, $headers);
                            } elseif ($ipn_balance < 0) {
                                $currency = get_woocommerce_currency();
                                $order->update_status('processing');
                                $order->add_order_note(__("Full MPesa Payment Received From {$phone}. Receipt Number {$mpesaReceiptNumber}"));
                                update_post_meta($post, '_order_status', 'processing');
                                update_post_meta($post, '_receipt', $mpesaReceiptNumber);

                                $order->save();
                            } else {
                                $order->update_status('on-hold');
                                $order->add_order_note(__("MPesa Payment from {$phone} Incomplete"));
                                update_post_meta($post, '_order_status', 'on-hold');
                            }

                            update_post_meta($post, '_paid', $after_ipn_paid);
                            update_post_meta($post, '_amount', $amount_due);
                            update_post_meta($post, '_balance', $ipn_balance);
                            update_post_meta($post, '_phone', $phone);
                            update_post_meta($post, '_customer', $customer);
                            update_post_meta($post, '_order_id', $order_id);
                            update_post_meta($post, '_receipt', $mpesaReceiptNumber);
                            update_post_meta($post, '_transaction_id', $mpesaReceiptNumber);
                            $order->set_transaction_id($mpesaReceiptNumber);
                            $order->save();
                        } else {
                            $order->update_status('failed');
                            update_post_meta($post, '_receipt', 'fail');
                            update_post_meta($order_id, '_receipt', 'fail');
                            $order->add_order_note(__("{$resultDesc}"));
                        }

                        exit(wp_send_json((new STK)->reconcile()));
                    } else {
                        exit(wp_send_json((new STK)->reconcile(function () {
                            return false;
                        })));
                    }
                    break;

                case "status":
                    $transaction = sanitize_text_field($_POST['transaction']);
                    exit(wp_send_json((new STK)->status($transaction)));
                    break;

                case "result":
                    $response = json_decode(file_get_contents('php://input'), true);

                    $result = $response['Result'];

                    $ResultType               = $result['ResultType'];
                    $ResultCode               = $result['ResultType'];
                    $ResultDesc               = $result['ResultType'];
                    $OriginatorConversationID = $result['ResultType'];
                    $ConversationID           = $result['ResultType'];
                    $TransactionID            = $result['ResultType'];
                    $ResultParameters         = $result['ResultType'];

                    $ResultParameter = $result['ResultType'];

                    $ReceiptNo                = $ResultParameter[0]['Value'];
                    $ConversationID           = $ResultParameter[0]['Value'];
                    $FinalisedTime            = $ResultParameter[0]['Value'];
                    $Amount                   = $ResultParameter[0]['Value'];
                    $ReceiptNo                = $ResultParameter[0]['Value'];
                    $TransactionStatus        = $ResultParameter[0]['Value'];
                    $ReasonType               = $ResultParameter[0]['Value'];
                    $TransactionReason        = $ResultParameter[0]['Value'];
                    $DebitPartyCharges        = $ResultParameter[0]['Value'];
                    $DebitAccountType         = $ResultParameter[0]['Value'];
                    $InitiatedTime            = $ResultParameter[0]['Value'];
                    $OriginatorConversationID = $ResultParameter[0]['Value'];
                    $CreditPartyName          = $ResultParameter[0]['Value'];
                    $DebitPartyName           = $ResultParameter[0]['Value'];

                    $ReferenceData = $result['ReferenceData'];
                    $ReferenceItem = $ReferenceData['ReferenceItem'];
                    $Occasion      = $ReferenceItem[0]['Value'];
                    exit(wp_send_json((new STK)->validate()));
                    break;

                case "timeout":
                    $response = json_decode(file_get_contents('php://input'), true);

                    if (!isset($response['Body'])) {
                        exit(wp_send_json(['Error' => 'No response data received']));
                    }

                    $resultCode        = $response['Body']['stkCallback']['ResultCode'];
                    $resultDesc        = $response['Body']['stkCallback']['ResultDesc'];
                    $merchantRequestID = $response['Body']['stkCallback']['MerchantRequestID'];
                    $checkoutRequestID = $response['Body']['stkCallback']['CheckoutRequestID'];

                    $post = wc_mpesa_post_id_by_meta_key_and_value('_request_id', $merchantRequestID);
					$post = wc_mpesa_post_id_by_meta_key_and_value('_checkout_id', $checkoutRequestID);
                    //wp_update_post(['post_content' => file_get_contents('php://input'), 'ID' => $post]);
                    update_post_meta($post, '_order_status', 'pending');

                    $order_id = get_post_meta($post, '_order_id', true);
                    if (wc_get_order($order_id)) {
                        $order = new \WC_Order($order_id);

                        $order->update_status('pending');
                        $order->add_order_note(__("MPesa Payment Timed Out", 'woocommerce'));
                    }

                    exit(wp_send_json((new STK)->timeout()));
                    break;
                default:
                    exit(wp_send_json((new C2B)->register()));
            }
        }

        if (isset($_GET['pesaipn'])) {
            $response = array('receipt' => '');

            if (!empty($_GET['order'])) {
                $order_id = sanitize_text_field($_GET['order']);
                $post     = wc_mpesa_post_id_by_meta_key_and_value('_order_id', esc_attr($order_id));
                $notes    = wc_get_order_notes(array(
                    'post_id' => $order_id,
                    'number'  => 1
                ) );
                $response = array(
                    'receipt' => get_post_meta($order_id, '_receipt', true),
                    'note'    => $notes[0]
                );
            }

            exit(wp_send_json($response));
        }
    }

    public function wcmpesa_new_order_column($columns)
    {
        $columns['mpesa'] = 'Reinitiate Mpesa';
        return $columns;
    }

    /**
     * Render custom column content within edit.php table on event post types.
     *
     * @access public
     * @param string $column The name of the column being acted upon
     * @return void
     */
    public function shop_order_payments_table_column_content($column_id, $post_id)
    {
        $order_id = get_post_meta($post_id, '_order_id', true);
        switch ($column_id) {

            case 'mpesa':
                $statuses = array(
                    "processing" => "This Order Is Processing",
                    "on-hold"    => "This Order Is On Hold",
                    "complete"   => "This Order Is Complete",
                    "cancelled"  => "This Order Is Cancelled",
                    "refunded"   => "This Order Is Refunded",
                    "failed"     => "This Order Failed",
                );

                echo ($value = get_post_meta($post_id, '_order_status', true))
                    ? '<a href="' . admin_url('post.php?post=' . esc_attr(sanitize_text_field($order_id)) . '&action=edit">' . esc_attr($statuses[$value]) . '</a>')
                    : '<a href="' . admin_url('post.php?post=' . esc_attr(sanitize_text_field($order_id)) . '&action=edit"') . '>Set Status</a>';
                break;
        }
    }

    public function woocommerce_emails_attach_downloadables($attachments, $status, $order)
    {
        if (!is_object($order) || !isset($status)) {
            return $attachments;
        }
        if (empty($order)) {
            return $attachments;
        }
        if (method_exists($order, 'has_downloadable_item')) {
            if (!$order->has_downloadable_item()) {
                return $attachments;
            }
            $allowed_statuses = array('customer_invoice', 'customer_completed_order');
            if (isset($status) && in_array($status, $allowed_statuses)) {
                foreach ($order->get_items() as $item_id => $item) {
                    foreach ($order->get_item_downloads($item) as $download) {
                        $attachments[] = str_replace(content_url(), WP_CONTENT_DIR, $download['file']);
                    }
                }
            }
        }

        return $attachments;
    }

    /**
     * @since 1.20.79
     */
    public function request_body($order_id)
    {
        $c2b = get_option('woocommerce_mpesa_settings');

        if (($c2b['debug'] ?? 'no') == 'yes') {
            echo '
            <section class="woocommerce-order-details" id="mpesa_request">
            <p>Mpesa request body</p>
                <code>' . WC()->session->get('mpesa_request') . '</code>
            </section>';
        }
    }
}