skip to Main Content

Is the wc order_key always unique?

The API call to /wp-json/wc/v3/orders results in ->
{.. "id" : 123,…, "order_key": "wc_order_ru4mFC4nNfDAE",…}.

The following code shows the set_order_key function in the wc_order class. They use a substring but I cant figure out the source of $value.

public function set_order_key( $value ) {
    $this->set_prop( 'order_key', substr( $value, 0, 22 ) );
}

I want to use the order_key to sync the database of a remote telegram bot, that handles subscription tables.

2

Answers


  1. In short: NO, it is not really random.

    The explanation goes deep down into the WooCommerce function and calls on how the order is being generated, but ultimately depends on a cryptographically secure pseudo-random PHP function – random_int().

    A simple search and trace in the WooCommerce plugin (Version: 6.7.0) in VSCode reveals the following call stack:

    1. includes/wc-order-functions.php:158 wc_generate_order_key()
    2. wp-includes/pluggable.php:2564 wp_generate_password()
    3. wp-includes/pluggable.php:2564 wp_rand()
    4. PHP native library random_int().

    As the ultimate function is pseudo-random, instead of genuinely random (which is not always possible), it only offers a very low probability for duplicates, but such possibility is never eliminated.

    Whether this function has fulfilled your randomness requirements depends on your intended use case. But WooCommerce’s approach to getting a substring could be a dealbreaker for you. The ‘randomness’ for resulting permutations is limited by a set_order_key() > substr(len=22), maxing out resulting outcome count permutates up to wp_generate_password() charset ^ 22. In the end, the number is still limited, rather than a theoretical infinite.

    For your use case, since you’re developing integration with another platform, you may take over the authority on your end and generate a new subscription id on your database (possibly on another table), feed your ID back into woo-commerce and store it via update_post_meta(). In this case, you’re set free from the above permutation limit and have your own story.

    Feel free to let me know if this changes in the future and I’ll update my answer.

    23 Jul, 2022

    Login or Signup to reply.
  2. In practice, yes, you can rely on it being unique, specifically for orders. Keep in mind these random strings are not used cryptographically. And the maximum possible rate at which orders are created is not enough to reach a meaningful collision probability.

    The order key is generated in this class which handles saving orders. It’s created every time you don’t pass the order key as an argument (I guess the default behavior when a user places an order).

    class OrdersTableDataStore extends Abstract_WC_Order_Data_Store_CPT implements WC_Object_Data_Store_Interface, WC_Order_Data_Store_Interface {
        // ...
        /**
         * Method to create an order in the database.
         *
         * @param WC_Order $order
         */
        public function create( &$order ) {
            if ( '' === $order->get_order_key() ) {
                $order->set_order_key( wc_generate_order_key() );
            }
        // ...
        }
    // ...
    }
    

    The substr is just to put an upper limit to the size of custom IDs. 22 is more than enough to avoid collisions. WooCommerce itself only uses 13 character long order keys. However there are 62 possible characters. This yields 62 ^ 13 possibilities, or

    200,028,539,268,669,788,905,472
    

    Let’s say your store amazingly has made it to 1 billion orders. If it’s perfectly randomly distributed, the chance for having encountered a single collision is just 0.0002499%. A more reasonable number like 10 thousand orders gives you a chance of 0.000000000000022%. You can verify these calculations here (use 1000000000, 62, and 13 as parameters).

    The chance to collide with a recently generated value is even lower than this. The value was likely generated many, many years ago (assuming a realistic rate at which orders are created).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search