Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Customers and the My account area

A customer is an ordinary WordPress user with the customer role. Their addresses and purchase history are available through the WC_Customer object, and the personal area is on the My account page (/my-account/). You can add your own tab there — for example, a list of the customer's reviews.

Where to write the code

Create the includes/account.php file and include it in acme-shop.php.

Reading a customer

// wp-content/plugins/acme-shop/includes/account.php
add_action('woocommerce_account_dashboard', function () {
    $customer = new WC_Customer(get_current_user_id());
 
    printf(
        '<p>Orders: %d, total %s. Shipping city: %s.</p>',
        $customer->get_order_count(),
        wc_price($customer->get_total_spent()),
        esc_html($customer->get_shipping_city() ?: 'not set')
    );
});

The constructor takes a user ID. The woocommerce_account_dashboard hook prints a block on the first tab of the account — log in and open /my-account/ to see the line.

Properties

MethodWhat it returns
get_email()The email address
get_first_name(), get_last_name()The first and last name
get_billing_phone()The phone
get_billing(), get_shipping()An address as an array
get_order_count()The number of orders
get_total_spent()The total of paid orders
get_is_paying_customer()Whether there was at least one paid order

Addresses are stored in user meta — the wp_usermeta table, keys like billing_city and shipping_postcode.

Changing and your own data

// wp-content/plugins/acme-shop/scripts/update-customer.php
$customer = new WC_Customer(7);
 
$customer->set_billing_phone('+49 30 1234567');
$customer->update_meta_data('acme_birthday', '1990-05-14');
$customer->save();
 
echo $customer->get_meta('acme_birthday') . PHP_EOL;

The rule is the same: set_..., then save(). Run the file with wp eval-file — it prints the saved date. The current customer on the site is WC()->customer: the object exists for a guest too, whose ID is 0.

A tab in the account

A tab consists of three parts: an address, a menu item and content.

// wp-content/plugins/acme-shop/includes/account.php
add_action('init', function () {
    add_rewrite_endpoint('my-reviews', EP_ROOT | EP_PAGES);
});
 
add_filter('woocommerce_account_menu_items', function (array $items): array {
    $logout = $items['customer-logout'];
    unset($items['customer-logout']);
 
    $items['my-reviews'] = 'My reviews';
    $items['customer-logout'] = $logout;
 
    return $items;
});

The first function registers the /my-account/my-reviews/ address. The filter adds a menu item before Log out. After adding the code open Settings → Permalinks and press Save Changes — otherwise the new address returns 404.

The tab content

// wp-content/plugins/acme-shop/includes/account.php
add_action('woocommerce_account_my-reviews_endpoint', function () {
    $reviews = get_comments([
        'user_id' => get_current_user_id(),
        'post_type' => 'product',
        'status' => 'approve',
    ]);
 
    if (!$reviews) {
        echo '<p>You have not left any reviews yet.</p>';
 
        return;
    }
 
    echo '<ul>';
 
    foreach ($reviews as $review) {
        printf(
            '<li><a href="%s">%s</a>: %s</li>',
            esc_url(get_permalink($review->comment_post_ID)),
            esc_html(get_the_title($review->comment_post_ID)),
            esc_html($review->comment_content)
        );
    }
 
    echo '</ul>';
});

The hook name is assembled from the tab address: woocommerce_account_ + my-reviews + _endpoint. A product review is a WordPress comment on a post of the product type. Leave a review for the mug and open the My reviews tab: a link to the product and the text appear in the list.

Removing a tab

add_filter('woocommerce_account_menu_items', function (array $items): array {
    unset($items['downloads']);
 
    return $items;
});

The Downloads tab is not needed in a shop without digital products.

Common mistake

The tab was added, the menu item is visible, but the page opens with a 404 error. WordPress keeps address rules in the database and does not know about the new one. Re-save permalinks in the admin panel — once after adding add_rewrite_endpoint().

Thanks for reading!

Donate to the site — we work hard for you.