skip to Main Content

I create a woordpress plugin that generates a code, links it to a downloadable virtual product. I use this code, once validated to create a woocommerce order in php. When I change the order status the email is never sent to the customer. However, on the production site, customers receive confirmation emails correctly. (The plugin is not on the production site).

I tried to do the status change with :
$order->set_status('completed')
$order->update_status('completed')
I’ve tried to do it manually in the commands dashboard, but it doesn’t change anything.

What I’d like is for the plugin to create a woocommerce order with the customer’s email address when the code is validated. (the customer doesn’t have to have an account to order) The order goes directly to Shipping, and the download email is sent. The customer opens the e-mail and downloads the file. I don’t understand what the problem is, if someone has already come across this problem or if someone has an idea I’d love to hear from you.

I’ll share my code with you:

function ode_cd_traitment_download_code_form()
{
  if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['code']) && isset($_POST['email'])) {
    $code = sanitize_text_field($_POST['code']);
    $email = sanitize_text_field($_POST['email']);
    $remaining_uses = remaining_uses($code);
    $validation_result = ode_cd_validate_data_download_form($code, $email, $remaining_uses);

    if (!empty($validation_result)) {
      return $validation_result;
    } else {
      if (ode_cd_code_exists_in_database($code)) {
        decrement_uses($code);
        $new_remaining_uses = remaining_uses(($code));

        ode_cd_create_order($code, $email);

        wp_redirect(home_url("/test-page/?success=true&remaining_uses=$new_remaining_uses"));
        exit;
      } else {
        return "Le code renseigner est inconnue de notre service.";
      }
    }
  }
}
add_action('init', 'ode_cd_traitment_download_code_form');

function ode_cd_create_order($code, $email)
{

  $product_id = get_product_id_by_unique_code($code);

  $order = wc_create_order();
  $product = wc_get_product($product_id);
  $order->add_product($product, 1);
  $order->set_billing_email($email);
  //$order->set_status('completed');
  $order->save();
  // $order->update_status('completed');
  //$order->save();
}

Have a nice day and thanks in advance to those who reply.

2

Answers


  1. First, you should use woocommerce_init hook instead of WordPress init hook.

    Try the following function replacement code:

    add_action('woocommerce_init', 'ode_cd_traitment_download_code_form');
    function ode_cd_traitment_download_code_form()
    {
        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['code']) && isset($_POST['email'])) {
            $code = sanitize_text_field($_POST['code']);
            $email = sanitize_text_field($_POST['email']);
            $remaining_uses = remaining_uses($code);
            $validation_result = ode_cd_validate_data_download_form($code, $email, $remaining_uses);
    
            if (!empty($validation_result)) {
                return $validation_result;
            } else {
                if (ode_cd_code_exists_in_database($code)) {
                    decrement_uses($code);
                    $new_remaining_uses = remaining_uses(($code));
    
                    if( ode_cd_create_order($code, $email) ) {
                        wp_redirect(home_url("/test-page/?success=true&remaining_uses=$new_remaining_uses"));
                        exit;
                    } else {
                        return "Un problème est survenu lors de la creation de la commande.";
                    }
                } else {
                    return "Le code renseigné est inconnu de notre service.";
                }
            }
        }
    }
    
    function ode_cd_create_order( $code, $email ){
        $product_id = get_product_id_by_unique_code($code);
    
        if ( ! $code || ! ($product_id > 0) || ! is_email($email) ) {
            return false;
        }
    
        $order = wc_create_order();
        $order->set_customer_user_agent( wc_get_user_agent() );
        $order->add_product(wc_get_product($product_id), 1);
        $order->set_billing_email($email);
        $order->set_status('completed');
    
        // Calculate totals, save order data to the database and returns the order total amount
        return $order->calculate_totals(); 
    }
    

    It should work.

    I have tested the code inside ode_cd_create_order() function with a real email and a valid product ID:

    • An order is created with completed status
    • Email notifications are sent:
      • to the admin (new order email)
      • to the costumer (order completed email)
    Login or Signup to reply.
  2. Sorry for the delay.
    Thanks for your reply. You were right, I wasn’t using the right hook. I tried to implement your code and in the entire context of my plugin the code crashed when the function is called. I just modified the hook, used ‘wp_loaded’ and it works.

    Thanks again for taking the time to help me, and have a nice day.

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