php - Problem with sending a user's order data through an HTTP Request in Wordpress / Woocommerce

one text

Hello everyone and sorry in advance for grammatical mistakes. I want to send an order's details through an HTTP request after a purchase is completed/Order is placed.

( WordPress With Woocommerce Plugin )

Here's what I've done so far:

  1. I've placed a PHP snippet to send the HTTP request in ./wp-content/themes/flatsome/woocommerce/checkout
  2. I've also edited my theme's default thankyou.php to collect and then send $order_id to the snippet mentioned in #1.

The Problem I'm facing: Once user places an order and is sent to the thankyou page (receipt page) I get the following errors:

Warning : Trying to access array offset on value of type null in .\wp-content\themes\flatsome\woocommerce\checkout\snippet.php on line 64

Indicating that the $Order_id variable failed to pass a value. However Once the page is refreshed once, the error goes away, the variable gets a value and the request is sent correctly.

Here's the PHP code to get Order details from database using the $Order_id value and then translate it to the desired variables that the API accepts Below:

//Snippet.php

<?php

function conection()
{
    $host = "hostname";
    $user = "DB_user";
    $pass = "DB_password";
    $db = "DB_name";
    $conn = mysqli_connect($host, $user, $pass, $db);
    return $conn;
}


function send_data($order_id)
{
    $conection = conection();
    $get_product_id = (int) get_product_id($order_id);

    $query = "SELECT `max_price`, `stock_quantity` FROM `wp_wc_product_meta_lookup` WHERE `product_id` = '$get_product_id'";
    $result = mysqli_query($conection, $query);

    if ($result) {
        $row = mysqli_fetch_assoc($result);
        $max_price = (float) $row['max_price'];
        $stock_quantity = (int) $row['stock_quantity'];

        $max_price = $max_price * 10;


        $data = array(
            'api_id' => $get_product_id,
            'price' => $max_price,
            'price_off' => '0',
            'inventory' => $stock_quantity,
            'inventory_check' => '1',
        );

        $data_string = json_encode($data);
        $ch = curl_init('https://WEBSERVICE.com');
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt(
            $ch,
            CURLOPT_HTTPHEADER,
            array(
                'Content-Type: application/json',
                'Content-Length: ' . strlen($data_string),
                'token: API_TOKEN'
            )
        );
        $result = curl_exec($ch);
        curl_close($ch);
    }
}


function get_product_id($order_id)
{
    $conection = conection();
    $query = "SELECT `product_id` FROM `wp_wc_order_product_lookup` WHERE `order_id` = '$order_id'";
    $result = mysqli_query($conection, $query);
    $row = mysqli_fetch_assoc($result);
    return $row['product_id'];
}

And below is the thankyou.php code I've modified to: a: Require the snippet.php file and b: Send the $order_id value to snippet.php

<?php

// Here's where i require the snippet.php file:
require_once('snippet.php');

defined( 'ABSPATH' ) || exit;
?>

<div class="row">

    <?php if ( $order ) :

        do_action( 'woocommerce_before_thankyou', $order->get_id() ); ?>

        <?php if ( $order->has_status( 'failed' ) ) : ?>
        <div class="large-12 col order-failed">
            <p class="woocommerce-notice woocommerce-notice--error woocommerce-thankyou-order-failed"><?php esc_html_e( 'Unfortunately your order cannot be processed as the originating bank/merchant has declined your transaction. Please attempt your purchase again.', 'woocommerce' ); ?></p>

            <p class="woocommerce-notice woocommerce-notice--error woocommerce-thankyou-order-failed-actions">
                <a href="<?php echo esc_url( $order->get_checkout_payment_url() ); ?>" class="button pay"><?php esc_html_e( 'Pay', 'woocommerce' ); ?></a>
                <?php if ( is_user_logged_in() ) : ?>
                    <a href="<?php echo esc_url( wc_get_page_permalink( 'myaccount' ) ); ?>" class="button pay"><?php esc_html_e( 'My account', 'woocommerce' ); ?></a>
                <?php endif; ?>
            </p>
        </div>

        <?php else : ?>
    <div class="large-7 col">

    <?php
    $get_payment_method = $order->get_payment_method();
    $get_order_id       = $order->get_id();

    ?>
    <?php do_action( 'woocommerce_thankyou_' . $get_payment_method, $get_order_id ); ?>
    <?php do_action( 'woocommerce_thankyou', $get_order_id );  ?>

    </div>

        <div class="large-5 col">
            <div class="is-well col-inner entry-content">
                <p class="success-color woocommerce-notice woocommerce-notice--success woocommerce-thankyou-order-received"><strong><?php echo apply_filters( 'woocommerce_thankyou_order_received_text', esc_html__( 'Thank you. Your order has been received.', 'woocommerce' ), $order ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></strong></p>

                <ul class="woocommerce-order-overview woocommerce-thankyou-order-details order_details">

                    <li class="woocommerce-order-overview__order order">
                        <?php esc_html_e( 'Order number:', 'woocommerce' ); ?>
                        <strong><?php echo $order->get_order_number(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></strong>
                    </li>

                        <li class="woocommerce-order-overview__date date">
                            <?php esc_html_e( 'Date:', 'woocommerce' ); ?>
                            <strong><?php echo wc_format_datetime( $order->get_date_created() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></strong>
                        </li>

                        <?php if ( is_user_logged_in() && $order->get_user_id() === get_current_user_id() && $order->get_billing_email() ) : ?>
                            <li class="woocommerce-order-overview__email email">
                                <?php esc_html_e( 'Email:', 'woocommerce' ); ?>
                                <strong><?php echo $order->get_billing_email(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></strong>
                            </li>
                        <?php endif; ?>

                    <li class="woocommerce-order-overview__total total">
                        <?php esc_html_e( 'Total:', 'woocommerce' ); ?>
                        <strong><?php echo $order->get_formatted_order_total(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></strong>
                    </li>

                    <?php
                    $payment_method_title = $order->get_payment_method_title();
                    if ( $payment_method_title ) :
                        
                    ?>
                        <li class="woocommerce-order-overview__payment-method method">
                            <?php esc_html_e( 'Payment method:', 'woocommerce' ); ?>
                            <strong><?php echo wp_kses_post( $payment_method_title ); ?></strong>
                        </li>
                    <?php endif; ?>

                </ul>

                <div class="clear"></div>
            </div>
        </div>

        <?php endif; ?>

    <?php else : ?>

        <p class="woocommerce-notice woocommerce-notice--success woocommerce-thankyou-order-received"><?php echo apply_filters( 'woocommerce_thankyou_order_received_text', esc_html__( 'Thank you. Your order has been received.', 'woocommerce' ), null ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p>

    <?php endif; ?>

</div>

//Here's where I send the order id.
<?php send_data($get_order_id); ?>

As I mentioned at first, the first time a user lands on the thankyou page the variable gets a NULL value, but as soon as a screen refresh takes place everything works in order. (Note: I've tried this on a local machine as well as a VPS but still, the same thing happens.)


Update: So we narrowed down the problem. It's basically that when my function tries to retrieve information from the database using the $get_order_id value, it returns NULL. Meaning at the moment of my function trying to access the table with the specified order id, it has not been created yet. hence why after a screen refresh everything works in order.

So I guess now the question is: Where and When does WordPress/Woocommerce insert the new table for a fresh order. So that I can put my function after that piece of code.

Source