How to Show WooCommerce Customers Their Own Orders in a Table

TableCrafter's current-user filter lets you display a WooCommerce orders table where each logged-in customer sees only their own orders, order ID, date, status, total, and items, without any custom code. This guide walks through the filter config, role settings, and how to embed the table in the WooCommerce My Account page. WordPress powers 43% of all websites globally (W3Techs, July 2026), and TableCrafter bridges the gap between the data you collect and the tables your users need to see, no custom PHP, no dashboard access required for viewers, and no per-row limits on the free tier. The free version on WordPress.org supports CSV, JSON, Google Sheets, and Excel. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST APIs, inline cell editing, export to CSV/PDF, role-based column visibility, and auto-refresh. Every table embeds on any page with a [tablecrafter] shortcode or the native Gutenberg block. Frontend editing reduces admin support requests by an average of 42% in multi-user WordPress environments (WP Buffs, 2024).
How Does the Current-User Filter Work?
WooCommerce stores the customer's WordPress user ID in the customer_id field on every order. For guest checkouts, customer_id is 0. TableCrafter's WooCommerce source passes the logged-in user's ID to wc_get_orders() via the customer parameter, which WooCommerce resolves against the order's billing email, billing user ID, and stored customer meta. The filter is applied server-side before any data leaves WordPress and cannot be manipulated by the browser. A customer cannot modify the URL or form parameters to see another customer's orders because TableCrafter re-evaluates get_current_user_id() on every request, including AJAX calls triggered by sorting, filtering, and pagination. The current user ID is resolved from the WordPress authentication cookie, not from any client-supplied parameter. When a user is not logged in, the query returns an empty set, and the table renders the configured no-access message instead.
customer_id = 0. Those orders will not appear in any user's current-user-filtered table. If your store uses a guest-to-account flow (WooCommerce's "Create account" option at checkout), orders placed before account creation remain guest orders unless manually reassigned.
Step 1: How Do I Create a Customer Orders Table Config?
Go to TableCrafter → Tables → Add New. Set the data source to the WooCommerce orders source type. Name the table My Orders, Customer View. This will be a separate table configuration from your admin-facing order management table, even though both pull from the same WooCommerce orders data. Keeping them as separate configs is important: the customer view will have different columns (fewer, no internal fields), a current-user filter, and a restricted access role, while your admin view may expose all fields and have no access restriction. Separating them means you can update either config independently. The columns available on an orders source include order ID, date, customer name, order status, total, item count, and payment method — the same fields returned by WooCommerce's wc_get_orders() CRUD API, which TableCrafter uses internally so all WooCommerce hooks and status events fire correctly.
Step 2: How Do I Configure Columns for Customers?
Customers need enough information to track their orders without seeing internal business data. Add these columns:
order_id, Label: Order #. Link to the WooCommerce order detail page (not the admin):/my-account/view-order/{order_id}/order_date, Label: Date, format: MM/DD/YYYYorder_status, Label: Status, Display Type: Badge. Do not enable inline edit.line_item_name, Label: Item(s)line_item_quantity, Label: Qtyorder_total, Label: Total, format: Currency
Do not include billing_email, billing_phone, internal notes, or cost/margin fields. Customers do not need to see their own email in a table, and you do not want to expose data that could be sensitive in a different context.
The configuration you set here applies to every visitor who loads a page containing this table, regardless of whether they are logged in. Role-specific overrides for columns and rows are a separate layer and do not replace these global display settings. Apply global settings first, then add role restrictions as needed for tables that serve multiple user types.
Step 3: How Do I Add the Current User Filter?
Open the Filters tab in the table config. Click Add Filter:
- Source Field:
customer_id - Filter Type: Current User
- Visibility: Hidden (the filter is applied automatically and the customer does not see or interact with it)
Setting visibility to Hidden is important. The filter still runs on every query, but no filter control is rendered in the toolbar. The customer simply sees their own orders with no filter UI to manipulate.
If the result does not match expectations after saving, use the TableCrafter debug log (enable via TableCrafter Settings > Advanced > Debug Mode) to trace exactly which configuration value is being applied for the current request.
This step completes the connection between your data source and the TableCrafter table engine. Once saved, the plugin caches the connection credentials in the WordPress options table and uses them on every subsequent page load. If you update the source configuration later — for example, rotating an API key or changing a sheet URL — return to this step, enter the new value, and save again. The table updates immediately on next load without any shortcode changes.
Step 4: How Do I Set Access Permissions?
In the Access tab, set Allowed Viewer Roles to Customer and leave the edit roles empty. The Customer role is the default WooCommerce role assigned to registered buyers. If your store uses a membership plugin that assigns a different role name, add that role to the list instead. TableCrafter evaluates the allowed_user_roles setting server-side on every request, including AJAX calls for sorting, filtering, and pagination. WordPress administrators always bypass this check and can view the table regardless of configured roles. The role check uses WordPress's standard wp_get_current_user() and compares $user->roles against your configured list. If a user with none of the allowed roles attempts to view the table, the server returns the configured no-access message before any order data is queried.
Set No Access Message to something user-friendly, for example: Please log in to view your orders. with a link to /my-account/. Logged-out visitors see this message rather than an empty table or a PHP error. Test it by opening an incognito window to confirm the message appears as expected.
Step 5: How Do I Configure Sorting and Pagination?
Most customers have between 1 and 50 orders. Set Default Sort to order_date descending so the most recent order appears first. Set Rows per page to 10 or 20 and enable pagination controls. WooCommerce's wc_get_orders() accepts orderby and order parameters natively, so TableCrafter passes your configured sort direction directly to WooCommerce rather than sorting in PHP after the fact. This means sorting on total or date is handled efficiently at the query level.
You can add a visible order status filter to let customers find Completed, Processing, or Refunded orders without scrolling through their full history. Status values come directly from WooCommerce's registered statuses via wc_get_order_statuses(), so any custom order statuses registered by third-party plugins appear automatically in the filter dropdown. This is optional and the right choice depends on whether your customers regularly need to look up orders by a specific status rather than just browsing their history chronologically. Always test sorting and filtering while logged in as a customer-role user, not as an administrator, because admins bypass role restrictions and may see different results.
Step 6: How Do I Place the Shortcode?
[tablecrafter id="5" search="true"]
Search lets customers find a specific order by product name or order ID without scrolling through their full history. It is particularly useful for customers with long order histories. Export is optional: some store owners prefer to let customers download a CSV of their own order history for tax or expense-report purposes, while others leave it disabled to reduce complexity. When export is enabled, the exported file is scoped to the same current-user filter applied to the table, so a customer's CSV contains only their own orders and no one else's data. The shortcode also accepts a per_page override if you want to show more rows on this specific page than the default you configured in the table builder, for example [tablecrafter id="5" search="true" per_page="25"]. Place the shortcode in a WordPress page using the Block Editor's Shortcode block, a Classic Editor text area, or inside a page builder's shortcode widget.
How Does Integrating with the WooCommerce My Account Page Work?
The WooCommerce My Account page is the natural home for a customer orders table. You have two options for embedding it:
Option A: Replace the Default Orders Tab
WooCommerce's default Orders tab in My Account renders a basic HTML table built by the woocommerce_account_orders action. You can replace it with your TableCrafter table by removing the default action handler and substituting your own. Add the snippet to your child theme's functions.php or a site-specific plugin rather than directly to the parent theme, so it survives WooCommerce updates. The priority 5 on add_action ensures your handler runs before any other callbacks that might also hook into woocommerce_account_orders_endpoint:
// Remove the default WooCommerce orders endpoint content
add_action( 'woocommerce_account_orders_endpoint', function() {
// Remove default handler
remove_action( 'woocommerce_account_orders_endpoint', 'woocommerce_account_orders' );
// Output TableCrafter shortcode
echo do_shortcode( '[tablecrafter id="5" search="true"]' );
}, 5 );
This approach keeps the My Account navigation intact and the URL (/my-account/orders/) unchanged, so existing bookmarks and email links continue to work. Customers who already know the WooCommerce orders URL are not disrupted. The default WooCommerce pagination and "View" links are removed along with the default handler, replaced entirely by the TableCrafter table with its own search and pagination controls.
Option B: Add a New Tab
Add a new tab to My Account called Order History or My Orders alongside the default tabs. This is less disruptive than Option A because it preserves the default WooCommerce orders tab as a fallback while introducing the richer TableCrafter table under a separate endpoint. Use the woocommerce_account_menu_items filter to insert your tab label and endpoint slug into the navigation, then use the dynamic woocommerce_account_{endpoint}_endpoint action hook to render the shortcode when the tab is active. Register the endpoint slug itself with add_rewrite_endpoint() on init and flush rewrite rules once. When users click the new tab, WordPress routes to your endpoint action, which calls do_shortcode('[tablecrafter id="5"]'). This approach works cleanly with most My Account page builder overlays (Elementor, WPBakery) because the tab content is rendered in WooCommerce's template system, not outside it. Remove the old Orders tab from the menu if you decide to make the TableCrafter tab the canonical orders view.
Option C: Standalone Page
Create a WordPress page titled My Orders, paste the [tablecrafter id="5" search="true"] shortcode into the page content, and link to it from your theme's header navigation, footer, or a customer dashboard widget. This is the simplest approach and requires zero PHP. Protect the page using TableCrafter's access settings (Allowed Viewer Roles: Customer) so that search engines do not index the page and unauthenticated visitors see your configured no-access message rather than an empty table. Add a prominent link in the WooCommerce order confirmation email (via the woocommerce_email_order_details hook or WooCommerce's email editor) so customers discover the page after their first purchase. This approach decouples the orders view entirely from WooCommerce's My Account framework, which is useful if you are using a headless or highly customized account experience where the standard My Account hooks are not available or are difficult to extend.
[tablecrafter id="5" search="true"] directly inside the page builder layout without touching PHP.
What Customers See?
A logged-in customer visiting the page sees a clean table showing only their own orders, sorted newest first, with order status badges, product names, and totals. The order number column links to the WooCommerce order detail page where they can see the full order, download invoices, or request a return.
A logged-out visitor sees your configured no-access message with a login link. A shop manager visiting the page also sees only their own orders as a customer, because the current-user filter applies to everyone who views this table config. If shop managers need to see all orders, they use a separate table config without the current-user filter.
After completing this step, verify the result by viewing the page as a logged-out visitor in an incognito window. This confirms the table behaves correctly for public visitors rather than reflecting admin-level permissions that may hide configuration issues during initial setup. Check both the rendered output and the browser console for any JavaScript errors.
Frequently Asked Questions
How Does the Current-User Filter Work?
WooCommerce stores the customer's WordPress user ID in the customer_id field on every order. For guest checkouts, customer_id is 0. TableCrafter's Current User filter type adds a WHERE customer_id = {current_user_id} clause to every query at render time. The filter is applied server-side and cannot be manipulated by the browser, a customer cannot modify the URL or form parameters to see another c
What Is TableCrafter?
TableCrafter is a WordPress plugin that turns data from Gravity Forms, Google Sheets, Airtable, Notion, REST APIs, CSV files, and WooCommerce into interactive, sortable, filterable frontend tables. Embed any table on any WordPress page with the [tablecrafter] shortcode or the native Gutenberg block. No PHP or custom development required. The free version supports CSV, JSON, Google Sheets, and Excel. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST APIs, inline cell editing, export to CSV and PDF, role-based column visibility, and auto-refresh.
Does this require PHP or developer skills?
No. TableCrafter is configured entirely through the WordPress admin interface. You choose your data source, map fields to columns, and set display preferences using point-and-click controls. Embedding uses the [tablecrafter] shortcode or the native Gutenberg block.
Is the free version sufficient or do I need Pro?
The free plugin on WordPress.org supports CSV, JSON, Google Sheets, and Excel sources with unlimited tables, rows, and columns. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST API sources, inline cell editing, bulk row actions, export to CSV and PDF, role-based column visibility, and auto-refresh every N seconds.
Ready to try it?
TableCrafter is free on WordPress.org. Pro unlocks inline editing, role-based permissions, and advanced data sources.
Changes take effect immediately after saving. No cache flush or page refresh is required for the new configuration to apply to all shortcode instances of this table.
The column mapping you define here is stored as a JSON configuration in the WordPress database. You can export this configuration using the TableCrafter export tool and import it to another table or another site. This is useful when replicating a table layout across multiple pages or when migrating a table to a staging environment for testing before going live.