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.