Adding and Removing WooCommerce Users | OpsBlu Docs

Adding and Removing WooCommerce Users

Step-by-step guide to managing WooCommerce users, invitations, role assignments, and offboarding processes

Proper user management ensures secure access control, clear responsibilities, and efficient WooCommerce store operations. This guide covers user lifecycle management from invitation to offboarding.

Adding New Users

Method 1: WordPress Admin (Manual)

Add User via Dashboard:

  1. Navigate to Users → Add New

  2. Fill in required fields:

    • Username - Unique, lowercase, no spaces
    • Email - Valid email address
    • First Name / Last Name - For personalization
    • Website - Optional
    • Password - Strong password (use generator)
    • Role - Select appropriate WooCommerce role
  3. Choose WooCommerce role:

    • Administrator - Full store access
    • Shop Manager - Store operations
    • Customer - Can place orders
    • Custom Role - If created
  4. Click Add New User

  5. Optionally check Send User Notification to email login details

Best Practices:

  • Use strong, unique passwords
  • Enable "Send User Notification" for email delivery
  • Document reason for account creation
  • Set review date for access audit

Method 2: Programmatic User Creation

// Create new shop manager
function create_shop_manager($email, $username, $first_name, $last_name) {
    // Check if user already exists
    if (email_exists($email) || username_exists($username)) {
        return new WP_Error('user_exists', 'User already exists');
    }

    // Generate secure password
    $password = wp_generate_password(16, true, true);

    // Create user
    $user_id = wp_create_user($username, $password, $email);

    if (is_wp_error($user_id)) {
        return $user_id;
    }

    // Set user meta
    wp_update_user(array(
        'ID' => $user_id,
        'first_name' => $first_name,
        'last_name' => $last_name,
        'display_name' => $first_name . ' ' . $last_name,
        'role' => 'shop_manager'
    ));

    // Send notification email
    wp_new_user_notification($user_id, null, 'user');

    // Log creation
    error_log(sprintf('Shop Manager created: %s (%s)', $username, $email));

    return $user_id;
}

// Usage
$user_id = create_shop_manager(
    'manager@example.com',
    'storemanager',
    'Jane',
    'Smith'
);

Method 3: Bulk User Import

For adding multiple users:

// Import users from CSV
function import_woocommerce_users($csv_file) {
    if (!file_exists($csv_file)) {
        return new WP_Error('file_not_found', 'CSV file not found');
    }

    $handle = fopen($csv_file, 'r');
    $imported = 0;
    $errors = array();

    // Skip header row
    fgetcsv($handle);

    while (($data = fgetcsv($handle, 1000, ',')) !== false) {
        list($username, $email, $first_name, $last_name, $role) = $data;

        // Validate role
        if (!in_array($role, array('shop_manager', 'customer', 'administrator'))) {
            $errors[] = "Invalid role for {$email}";
            continue;
        }

        // Create user
        $password = wp_generate_password(16, true, true);
        $user_id = wp_create_user($username, $password, $email);

        if (is_wp_error($user_id)) {
            $errors[] = $user_id->get_error_message();
            continue;
        }

        // Update user details
        wp_update_user(array(
            'ID' => $user_id,
            'first_name' => $first_name,
            'last_name' => $last_name,
            'role' => $role
        ));

        // Send welcome email
        wp_new_user_notification($user_id, null, 'user');

        $imported++;
    }

    fclose($handle);

    return array(
        'imported' => $imported,
        'errors' => $errors
    );
}

// CSV format: username,email,first_name,last_name,role
// Example: jsmith,jane@example.com,Jane,Smith,shop_manager

Automatic Customer Account Creation

WooCommerce can automatically create customer accounts during checkout:

Enable Auto Account Creation

Settings:

  1. Navigate to WooCommerce → Settings → Accounts & Privacy
  2. Check Allow customers to create an account during checkout
  3. Check Allow customers to create an account on "My account" page
  4. Optionally check When creating an account, automatically generate an account username
  5. Optionally check When creating an account, send the new user a link to set their password

Customize Auto Account Creation

// Customize auto-generated username
add_filter('woocommerce_new_customer_username', 'custom_customer_username', 10, 1);
function custom_customer_username($username) {
    // Use email prefix + random number
    $email_parts = explode('@', $username);
    $new_username = $email_parts[0] . '_' . wp_rand(1000, 9999);
    return $new_username;
}

// Auto-assign customer role meta based on purchase
add_action('woocommerce_created_customer', 'set_customer_meta_on_registration', 10, 1);
function set_customer_meta_on_registration($customer_id) {
    // Mark as new customer for tracking
    update_user_meta($customer_id, '_is_new_customer', 'yes');
    update_user_meta($customer_id, '_registration_date', current_time('mysql'));

    // Set default preferences
    update_user_meta($customer_id, '_marketing_emails_opt_in', 'yes');
}

Changing User Roles

Via Admin Dashboard

  1. Navigate to Users → All Users
  2. Hover over user → Click Edit
  3. Scroll to Role dropdown
  4. Select new role
  5. Click Update User

Programmatically

// Change user role
function change_user_role($user_id, $new_role) {
    $user = get_user_by('id', $user_id);

    if (!$user) {
        return new WP_Error('invalid_user', 'User not found');
    }

    // Validate role exists
    if (!get_role($new_role)) {
        return new WP_Error('invalid_role', 'Role does not exist');
    }

    // Log role change
    $old_roles = $user->roles;
    error_log(sprintf(
        'User %d role changed from %s to %s',
        $user_id,
        implode(', ', $old_roles),
        $new_role
    ));

    // Change role
    $user->set_role($new_role);

    return true;
}

// Temporary role elevation
function grant_temporary_shop_manager($user_id, $days = 7) {
    $user = get_user_by('id', $user_id);

    // Store original role
    update_user_meta($user_id, '_temp_original_role', $user->roles[0]);
    update_user_meta($user_id, '_temp_role_expiry', time() + ($days * DAY_IN_SECONDS));

    // Elevate to shop manager
    $user->set_role('shop_manager');

    // Schedule role restoration
    wp_schedule_single_event(
        time() + ($days * DAY_IN_SECONDS),
        'restore_user_role',
        array($user_id)
    );
}

add_action('restore_user_role', 'restore_original_role');
function restore_original_role($user_id) {
    $original_role = get_user_meta($user_id, '_temp_original_role', true);

    if ($original_role) {
        $user = get_user_by('id', $user_id);
        $user->set_role($original_role);

        delete_user_meta($user_id, '_temp_original_role');
        delete_user_meta($user_id, '_temp_role_expiry');

        error_log("User {$user_id} role restored to {$original_role}");
    }
}

Removing Users (Offboarding)

Method 1: Delete via Dashboard

  1. Navigate to Users → All Users
  2. Hover over user → Click Delete
  3. Choose option for content:
    • Delete all content - Removes user's products, orders, etc.
    • Attribute all content to - Reassign to another user
  4. Click Confirm Deletion

Important: Be cautious when deleting users with WooCommerce data (products, orders).

Method 2: Programmatic Deletion

// Safe user deletion with content reassignment
function safely_delete_woocommerce_user($user_id, $reassign_to = null) {
    $user = get_user_by('id', $user_id);

    if (!$user) {
        return new WP_Error('invalid_user', 'User not found');
    }

    // Prevent deletion of last administrator
    if (in_array('administrator', $user->roles)) {
        $admin_count = count(get_users(array('role' => 'administrator')));
        if ($admin_count <= 1) {
            return new WP_Error('last_admin', 'Cannot delete last administrator');
        }
    }

    // Get user's content
    $product_count = count(get_posts(array(
        'post_type' => 'product',
        'author' => $user_id,
        'posts_per_page' => -1
    )));

    $order_count = count(wc_get_orders(array(
        'customer_id' => $user_id,
        'limit' => -1
    )));

    // Log deletion
    error_log(sprintf(
        'Deleting user %d (%s) - Products: %d, Orders: %d',
        $user_id,
        $user->user_email,
        $product_count,
        $order_count
    ));

    // Delete user
    if ($reassign_to) {
        require_once(ABSPATH . 'wp-admin/includes/user.php');
        $result = wp_delete_user($user_id, $reassign_to);
    } else {
        $result = wp_delete_user($user_id);
    }

    if ($result) {
        return array(
            'success' => true,
            'products' => $product_count,
            'orders' => $order_count
        );
    }

    return new WP_Error('deletion_failed', 'User deletion failed');
}

Method 3: Deactivate Instead of Delete

For compliance/audit purposes, deactivate instead of deleting:

// Deactivate user instead of deleting
function deactivate_woocommerce_user($user_id, $reason = '') {
    $user = get_user_by('id', $user_id);

    if (!$user) {
        return false;
    }

    // Change to subscriber (minimal permissions)
    $user->set_role('subscriber');

    // Mark as deactivated
    update_user_meta($user_id, '_account_status', 'deactivated');
    update_user_meta($user_id, '_deactivation_date', current_time('mysql'));
    update_user_meta($user_id, '_deactivation_reason', $reason);

    // Prevent login
    add_user_meta($user_id, '_login_disabled', true, true);

    // Log deactivation
    error_log(sprintf(
        'User %d deactivated. Reason: %s',
        $user_id,
        $reason
    ));

    return true;
}

// Prevent deactivated users from logging in
add_filter('authenticate', 'prevent_deactivated_user_login', 30, 3);
function prevent_deactivated_user_login($user, $username, $password) {
    if ($user instanceof WP_User) {
        $deactivated = get_user_meta($user->ID, '_login_disabled', true);

        if ($deactivated) {
            return new WP_Error(
                'account_deactivated',
                'This account has been deactivated. Please contact support.'
            );
        }
    }

    return $user;
}

User Management Best Practices

1. Document User Access

// Log all user additions
add_action('user_register', 'log_user_registration');
function log_user_registration($user_id) {
    $user = get_user_by('id', $user_id);
    $current_user = wp_get_current_user();

    $log_entry = sprintf(
        '[%s] User %s (%s) created by %s. Role: %s',
        current_time('mysql'),
        $user->user_login,
        $user->user_email,
        $current_user->user_login,
        implode(', ', $user->roles)
    );

    // Log to file
    error_log($log_entry);

    // Or log to database
    global $wpdb;
    $wpdb->insert(
        $wpdb->prefix . 'user_access_log',
        array(
            'user_id' => $user_id,
            'action' => 'created',
            'created_by' => $current_user->ID,
            'created_at' => current_time('mysql')
        )
    );
}

2. Enforce Strong Passwords

// Enforce password complexity
add_filter('registration_errors', 'validate_password_strength', 10, 3);
function validate_password_strength($errors, $sanitized_user_login, $user_email) {
    if (isset($_POST['password']) && strlen($_POST['password']) < 12) {
        $errors->add('password_length', 'Password must be at least 12 characters long');
    }

    if (!preg_match('/[A-Z]/', $_POST['password'])) {
        $errors->add('password_uppercase', 'Password must contain at least one uppercase letter');
    }

    if (!preg_match('/[0-9]/', $_POST['password'])) {
        $errors->add('password_number', 'Password must contain at least one number');
    }

    if (!preg_match('/[!@#$%^&*]/', $_POST['password'])) {
        $errors->add('password_special', 'Password must contain at least one special character');
    }

    return $errors;
}

3. Regular Access Audits

// Find inactive users
function find_inactive_users($days = 90) {
    global $wpdb;

    $cutoff_date = date('Y-m-d H:i:s', strtotime("-{$days} days"));

    $inactive_users = $wpdb->get_results($wpdb->prepare("
        SELECT u.ID, u.user_login, u.user_email, um.meta_value as last_login
        FROM {$wpdb->users} u
        LEFT JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = 'last_login'
        WHERE um.meta_value < %s OR um.meta_value IS NULL
    ", $cutoff_date));

    return $inactive_users;
}

// Track last login
add_action('wp_login', 'track_user_last_login', 10, 2);
function track_user_last_login($user_login, $user) {
    update_user_meta($user->ID, 'last_login', current_time('mysql'));
}

4. Offboarding Checklist

When removing a user, complete these steps:

function complete_user_offboarding($user_id, $reassign_to) {
    $checklist = array();

    // 1. Reassign products
    $products = get_posts(array(
        'post_type' => 'product',
        'author' => $user_id,
        'posts_per_page' => -1
    ));

    foreach ($products as $product) {
        wp_update_post(array(
            'ID' => $product->ID,
            'post_author' => $reassign_to
        ));
    }
    $checklist['products_reassigned'] = count($products);

    // 2. Update orders (customer orders stay linked)
    // WooCommerce orders are linked to customer ID, not WordPress user

    // 3. Revoke API keys
    global $wpdb;
    $wpdb->delete(
        $wpdb->prefix . 'woocommerce_api_keys',
        array('user_id' => $user_id)
    );
    $checklist['api_keys_revoked'] = true;

    // 4. Clear sessions
    WC()->session->delete_session($user_id);
    $checklist['session_cleared'] = true;

    // 5. Export user data (GDPR compliance)
    $export_data = wp_privacy_generate_personal_data_export_file($user_id);
    $checklist['data_exported'] = $export_data;

    // 6. Delete user
    $deleted = safely_delete_woocommerce_user($user_id, $reassign_to);
    $checklist['user_deleted'] = !is_wp_error($deleted);

    // Log offboarding
    error_log('User offboarding completed: ' . json_encode($checklist));

    return $checklist;
}

Next Steps