1

I am using following code for auto register on guest user checkout. However, my "Specific Gateway" after successfully payment will not redirect to the woocommerce thankyou page, so this code will not work. How can I force guest user to register before making a payment on this "Specific Gateway".

function wc_register_guests( $order_id ) {
     // get all the order data
     $order = new WC_Order($order_id);
  
     //get the user email from the order
     $order_email = $order->billing_email;
    
     // check if there are any users with the billing email as user or email
     $email = email_exists( $order_email );  
     $user = username_exists( $order_email );
  
     // if the UID is null, then it's a guest checkout
     if( $user == false && $email == false ){
    
     // random password with 12 chars
     $random_password = wp_generate_password();
    
     // create new user with email as username & newly created pw
     $user_id = wp_create_user( $order_email, $random_password, $order_email );
    
     //WC guest customer identification
     update_user_meta( $user_id, 'guest', 'yes' );
 
     //user's billing data
     update_user_meta( $user_id, 'billing_address_1', $order->billing_address_1 );
     update_user_meta( $user_id, 'billing_country', $order->billing_country );
     update_user_meta( $user_id, 'billing_email', $order->billing_email );
     update_user_meta( $user_id, 'billing_first_name', $order->billing_first_name );
     update_user_meta( $user_id, 'billing_last_name', $order->billing_last_name );
     update_user_meta( $user_id, 'billing_phone', $order->billing_phone );
     update_user_meta( $user_id, 'billing_state', $order->billing_state );
 
      
     // link past orders to this newly created customer
     wc_update_new_customer_past_orders( $user_id );
      }
  
     }
 
     //add this newly created function to the thank you page
     add_action( 'woocommerce_thankyou', 'wc_register_guests', 10, 1 );

For the payment gateway policy requirement, I need to force guests user to register before making a payment on this "Specific Gateway".

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
goomember
  • 11
  • 1

1 Answers1

1

There are some mistakes and missing things in your code.

You can use woocommerce_checkout_order_processed hook, triggered just once the order is saved, but before payment (if any).

Based on How to assign a custom Customer Code to Guest purchasers in WooCommerce answer, try the following revisited code:

// Add "guest" user role
add_action( 'init', 'add_role_guest' );
function add_role_guest() {
    add_role(
        'guest',
        __( 'Guest', 'woocommerce' ),
        array( 'read' => true )
    );
}

// Register guest purchasers
add_action( 'woocommerce_checkout_order_processed', 'process_checkout_guest', 10, 3 );
function process_checkout_guest( $order_id, $posted_data, $order ) {
    $user_id       = $order->get_user_id(); // Get user Id (for guest the value is 0)
    $billing_email = $order->get_billing_email(); // Get email from order

   // Only Guest
    if ( ! $user_id && $billing_email ) {
        // check with the email, if WP_User exist
        $user = get_user_by( 'email', $billing_email );

        // WP_User don't exist
        if (! $user ) {
            // Generating the username
            $username = wc_create_new_customer_username( $billing_email, array(
                'first_name' => $order->get_billing_first_name(),
                'last_name' => $order->get_billing_last_name(),
            ) );

            // Creating user
            $user_id = wp_insert_user( array(
                'user_login' => $username,
                'user_pass'  => wp_generate_password(),
                'first_name' => $order->get_billing_first_name(),
                'last_name'  => $order->get_billing_last_name(),
                'user_email' => sanitize_email($billing_email),
                'role'       => 'guest', // Custom user role
                'meta_input' => array(
                    'guest'              => 'yes',
                    'billing_first_name' => $order->get_billing_first_name(),
                    'billing_last_name'  => $order->get_billing_last_name(),
                    'billing_email'      => $order->get_billing_email(),
                    'billing_phone'      => $order->get_billing_phone(),
                    'billing_company'    => $order->get_billing_company(),
                    'billing_address_1'  => $order->get_billing_address_1(),
                    'billing_address_2'  => $order->get_billing_address_2(),
                    'billing_city'       => $order->get_billing_city(),
                    'billing_postcode'   => $order->get_billing_postcode(),
                    'billing_state'      => $order->get_billing_state(),
                    'billing_country'    => $order->get_billing_country(),
                    'shipping_address_1' => $order->get_shipping_address_1(),
                    'shipping_address_2' => $order->get_shipping_address_2(),
                    'shipping_city'      => $order->get_shipping_city(),
                    'shipping_postcode'  => $order->get_shipping_postcode(),
                    'shipping_state'     => $order->get_shipping_state(),
                    'shipping_country'   => $order->get_shipping_country(),
                ),
            ) );

            // For testing
            if ( is_wp_error( $user_id ) ) {
                error_log( print_r($user_id, true) );
            }

            // Tag the current order with the guest user ID
            $order->update_meta_data('_guest_user_id', $user_id);
            $order->save();

            // Get past orders
            $past_orders = wc_get_orders( array(
                'limit'         => -1, // By batch of 200 orders 
                'status'        => wc_get_is_paid_statuses(),
                'customer'      => $billing_email,
            ) );

            // Tag past orders with this newly created guest user ID
            foreach( $past_orders as $past_order ) {
                if ( ! $past_order->get_meta('_guest_user_id') ) {
                    $past_order->update_meta_data('_guest_user_id', $user_id);
                    $past_order->save();

                }
            }
        } 
        // Guest user exists: Update billing and shipping meta data
        else {
            update_user_meta( $user->ID, 'billing_first_name', $order->get_billing_first_name());
            update_user_meta( $user->ID, 'billing_last_name',  $order->get_billing_last_name());
            update_user_meta( $user->ID, 'billing_email',      $order->get_billing_email());
            update_user_meta( $user->ID, 'billing_phone',      $order->get_billing_phone());
            update_user_meta( $user->ID, 'billing_company',    $order->get_billing_company());
            update_user_meta( $user->ID, 'billing_address_1',  $order->get_billing_address_1());
            update_user_meta( $user->ID, 'billing_address_2',  $order->get_billing_address_2());
            update_user_meta( $user->ID, 'billing_city',       $order->get_billing_city());
            update_user_meta( $user->ID, 'billing_postcode',   $order->get_billing_postcode());
            update_user_meta( $user->ID, 'billing_state',      $order->get_billing_state());
            update_user_meta( $user->ID, 'billing_country',    $order->get_billing_country());
            update_user_meta( $user->ID, 'shipping_address_1', $order->get_shipping_address_1());
            update_user_meta( $user->ID, 'shipping_address_2', $order->get_shipping_address_2());
            update_user_meta( $user->ID, 'shipping_city',      $order->get_shipping_city());
            update_user_meta( $user->ID, 'shipping_postcode',  $order->get_shipping_postcode());
            update_user_meta( $user->ID, 'shipping_state',     $order->get_shipping_state());
            update_user_meta( $user->ID, 'shipping_country',   $order->get_shipping_country());
        } 
    }
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

This code will assign a custom 'guest' user role to each registered guest user.

Each order will be tagged with the guest generated user ID (and also previous orders if any)

If the guest user exists, user billing and shipping data will only be updated.

To target a specific payment method, use an if statement defining the payment ID for the targeted payment gateway, like:

if ( $order->get_payment_method() === 'bacs' ) {
    // The active code HERE
}

See: How to get the ID of a payment method in Woocommerce?

Final note: Doing that is illegal, and even more in European countries. Why? Because you are storing customer data without their consent. If there is a problem or a leak in the related e-commerce site, and if legal authorities discover it, the risk is a large fine and legal proceedings.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399