How to Restrict a WooCommerce Orders Table by WordPress Role

A single WooCommerce store typically needs at least three different views of order data: customers see only their own orders in read-only mode, shop managers see all orders and can edit status, and admins see everything including cost and margin columns. TableCrafter handles all three with separate table configurations and role-gated column visibility. This guide walks through each role configuration in full. 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. 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. WooCommerce processes over 7 billion dollars in orders monthly across all installations (WooCommerce, 2024).
What Is the Three-Table Strategy?
The cleanest approach is to create three separate table configurations sharing the same WooCommerce Orders data source. Each config is tuned for one role's needs:
- Table A: Customer view, current-user-filtered, read-only, minimal columns
- Table B: Shop Manager view, all orders, status editable, no cost columns
- Table C: Admin view, all orders, all columns including cost/margin, bulk actions
You then place the appropriate shortcode on the appropriate page, with each page restricted to the right role. Alternatively, you can use a single page and render all three shortcodes, TableCrafter's own role checks ensure each user sees only the table they have permission to view.
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.
What Is Role 1: Customer, Read-Only, Own Orders Only?
Table Configuration
Go to TableCrafter → Tables → Add New in your WordPress admin. In the Table Name field, enter a descriptive label such as WooCommerce Orders, Customer View. A clear, role-specific name matters when you have multiple configurations for the same data source, since the name appears in the admin tables list and helps you identify the right config ID for each shortcode.
For Data Source, select WooCommerce: Orders. This connects the table to WooCommerce's order records. The data source itself returns all orders; customer-level row isolation is applied separately through the hidden filter configured below. Leave the Table ID field empty: TableCrafter assigns an auto-incremented numeric ID on first save. Note that ID after saving as you will need it for the shortcode placement step. Save the table once before proceeding to column configuration.
Columns
The customer-facing column set should contain only information the customer has a legitimate interest in seeing about their own orders. Omit all operational, financial, and business-internal fields.
order_id— link to/my-account/view-order/{order_id}/using the Link display type with the dynamic URL pattern, so customers can access the WooCommerce native order detail page with one click.order_date— display in your site's configured date format. Sort this column descending by default so the most recent order appears first.order_status— render as a badge display type. Map each WooCommerce status (processing, on-hold, completed, cancelled, refunded) to a matching badge color. Set this column as read-only; customers should never be able to modify their own order status.line_item_name— the product name. For multi-item orders this shows the first line item; consider adding a quantity column alongside it.order_total— display in currency format matching your WooCommerce currency settings.
Do not include cost price, margin, internal notes, billing phone, payment gateway tokens, or any business-internal field. If a customer can see a column, they can also export it.
Filters
The customer table requires exactly one filter, and it must be hidden from the user interface. This filter enforces row-level data isolation so that only orders belonging to the currently authenticated customer are returned.
- Source Field:
customer_id - Filter Type: Current User
- Visibility: Hidden
The Current User filter type automatically resolves to the WordPress user ID of the authenticated visitor on each page load. TableCrafter applies this as a server-side condition before data is returned, so customers cannot bypass it by modifying query parameters, shortcode attributes, or browser requests. Because the filter is marked Hidden, no filter input renders in the table header. Customers see only their own orders with no indication that the view is scoped. Do not add any visible filters to this table; the table is intentionally minimal and controlled.
Access Settings
These three settings control who can see the table and what they can do with it. Configure them in the Access & Permissions panel of the table builder before saving.
- Minimum role to view: Customer — logged-out visitors and users below the Customer role see the no-access message instead of any table output.
- Roles that can edit: None — disables inline editing for every user who views this table, including administrators. If an admin needs to correct a customer order, direct them to the WooCommerce order edit screen or the admin-only Table C configuration.
- No Access Message: Please log in to view your orders. — customize this message to match your site's tone and consider including a direct link to the WooCommerce My Account login page.
Setting Roles that can edit to None is important here: even if edit="true" is accidentally added to the shortcode, no edit affordances will render for any visitor because the table-level permission overrides the shortcode parameter.
Shortcode
[tablecrafter id="5" search="true"]
The search="true" parameter enables a global full-text search bar above the table. Customers can type any order detail, product name, date fragment, or amount into the search bar and the table filters instantly without a page reload. This is the only interactive control on the customer table; all column-level filters are hidden through the current-user filter configuration above.
Place this shortcode on a dedicated My Orders page accessible to logged-in customers, or embed it within the WooCommerce My Account template. If you use the My Account page, be aware that WooCommerce already renders its own orders list there; a custom My Orders page avoids presenting duplicate lists to the customer. Set the page visibility to require login at the WordPress page level as an additional layer of access control beyond TableCrafter's own role check.
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.
What Is Role 2: Shop Manager, All Orders, Status Editable?
Table Configuration
Go to TableCrafter → Tables → Add New. Name this configuration WooCommerce Orders, Shop Manager to distinguish it clearly from the customer-facing Table A in the admin list. Set the Data Source to WooCommerce: Orders, the same source as Table A. All three role-specific tables in this guide share the same underlying data source, which means changes to WooCommerce order data are reflected in all three table views without any synchronization step.
Because this configuration does not apply a current-user filter, shop managers see all orders from all customers. That is the intended scope for this role. Confirm this is appropriate for your team's data access policy before deploying. Note the table ID after saving, you will need it for the shop manager shortcode below.
Columns
The shop manager column set is broader than the customer view and includes operational fields needed for order fulfillment. It does not include cost or margin data, which is reserved for the administrator configuration.
order_id— link to the WooCommerce admin order detail screen at/wp-admin/post.php?post={order_id}&action=edit, letting shop managers open the full WooCommerce order editor in one click when they need to take actions not available in the table.order_date— date format, sorted descending by default so the newest orders appear at the top.- Computed:
{billing_first_name} {billing_last_name}, label: Customer — combine two source fields into a single display column. billing_email— rendered as a mailto link for quick customer contact.line_item_name, label: Productline_item_quantity, label: Qtyorder_status— badge display with inline editable dropdown, restricted to the Shop Manager role and above. This is the key edit-enabled column for this role.order_total— currency format showing the sale price the customer paid.
Do not include cost price or margin columns. Shop managers should see what the customer paid, not the cost the business paid. Cost data belongs in the administrator-only Table C.
Filters
Unlike the customer table, the shop manager configuration exposes visible filters that let staff narrow the order list to the work they need to process right now. Configure two filters to be visible by default:
- Status filter: Multi-select dropdown, default value
processing,on-hold— this pre-filters the table to show only actionable orders on page load, reducing noise from completed or cancelled orders. Shop managers can clear the default to see all statuses. - Date range filter: Default to last 30 days — prevents the table from loading a large order history on every page view while keeping recent activity visible without manual date selection.
There is no current-user filter on this table. Shop managers see all orders from all customers, which is the correct scope for this role. Visibility is controlled at the table access level, not the row level.
Access Settings
These settings enforce that only shop managers and administrators can access this table configuration. Customers and lower roles receive the no-access message even if they somehow obtain the page URL.
- Minimum role to view: Shop Manager — users with the Customer, Subscriber, or any lower role see the no-access message rather than any table output.
- Roles that can edit: Shop Manager, Administrator — both roles can activate the inline Status column edit. Customers who reach this page (e.g., via a direct URL) will see the table in read-only mode because they are not in the Edit Roles list.
- No Access Message: Access restricted to shop managers and administrators. — customize to match your site's tone.
Shortcode
[tablecrafter id="6" edit="true" filter="true" search="true" export="true"]
This shortcode activates inline editing (edit="true"), the column filter row (filter="true"), the global search bar (search="true"), and the CSV export button (export="true"). Shop managers can export the current filtered view for reconciliation or reporting without needing admin access to WooCommerce or GF exports.
Place this shortcode on a page restricted to the Shop Manager role. Use WordPress's built-in page visibility (Private or Password Protected) or a membership plugin to add a page-level restriction as a secondary layer beyond TableCrafter's own role check. This prevents the page HTML itself from being served to unauthenticated visitors, even before TableCrafter's role check runs.
What Is Role 3: Administrator, All Orders, All Columns?
Table Configuration
Go to TableCrafter → Tables → Add New. Name this configuration WooCommerce Orders, Admin. Set the Data Source to WooCommerce: Orders, the same source used by Tables A and B. Because all three configurations share a single data source, any update to an order in WooCommerce is immediately visible across all three table views on the next page load.
This configuration is the most permissive: it shows all orders, all columns including cost and margin data, and gives administrators full bulk action controls. Restrict access to this table tightly. Note the table ID after saving, this ID is what you use in the administrator shortcode. Because the admin table includes sensitive business data, test this configuration on a staging environment before deploying to production.
Columns
All columns from the Shop Manager config, plus:
line_item_cost, label: Cost Price (if tracked via a cost-of-goods plugin like WooCommerce Cost of Goods or Profit Margin plugin)- Computed:
{order_total} - {line_item_cost}, label: Gross Profit payment_method_title, label: Payment Methodcustomer_note, label: Customer Note- Any internal order meta fields relevant to your operations
_wc_cog_item_cost (WooCommerce Cost of Goods plugin) and _profit_margin. Add these as meta:_wc_cog_item_cost in the field mapper.
Bulk Actions
Enable Bulk Actions in the toolbar configuration for the admin table. Bulk actions let an administrator select multiple rows using the checkbox column and apply a single operation to all selected orders simultaneously, replacing the need to open and edit each order individually in wp-admin.
Add these bulk actions to the admin configuration:
- Mark as Completed — sets the WooCommerce status to
completedfor all selected orders in a single operation. Useful for batch-processing fulfilled orders at the end of a shift. - Mark as Processing — resets selected orders to
processingstatus, useful when correcting a batch of orders incorrectly marked as completed or when re-opening on-hold orders for fulfillment. - Export Selected — exports only the administrator-selected rows to CSV, not the entire filtered result set. This is useful for sending a subset of orders to a supplier, accountant, or fulfillment partner without exposing the full order history in the export file.
Bulk actions are restricted to the roles listed under Roles that can edit in the Access Settings panel. A shop manager accessing this page would not see bulk action controls even if they somehow bypass the page-level access restriction, because their role is not in the administrator table's Edit Roles configuration.
Access Settings
The administrator table has the most restrictive access settings because it exposes the most sensitive data. These settings ensure that only WordPress administrators can view or interact with it, even if the page URL is discovered by other roles.
- Minimum role to view: Administrator — shop managers, customers, and all lower roles see the no-access message or a blank shortcode output, never any table data.
- Roles that can edit: Administrator — only administrators can activate inline editing or trigger bulk actions. Setting this exclusively to Administrator prevents shop managers from gaining edit access to cost or margin columns even if they reach the admin page.
Additionally, restrict the page itself to administrators at the WordPress level using a plugin or your theme's access controls. This prevents the page HTML from loading at all for non-administrator visitors, which is better practice than relying solely on TableCrafter's output suppression for sensitive business data.
Shortcode
[tablecrafter id="7" edit="true" filter="true" search="true" export="true"]
This shortcode activates the full administrator feature set: inline editing (edit="true"), the column filter row (filter="true"), global search (search="true"), and CSV export (export="true"). Administrators can filter by any column, search across all fields, export the filtered result set including cost and margin data, and use bulk actions to update order statuses across multiple rows at once.
Place this shortcode on a WordPress page with visibility set to Private, or protect it using an administrator-only membership plugin rule. If you use a caching plugin such as WP Rocket or LiteSpeed Cache, add the admin page URL to the cache bypass list. Cached pages can serve a previous user's table output to a different visitor, which is a data leakage risk for any page containing role-restricted content.
How Does Placing All Three Shortcodes Efficiently Work?
If you want a single page that adapts based on who is viewing it, you can place all three shortcodes on the same page. TableCrafter will render each table only if the current user meets its minimum role requirement. A customer visiting the page sees Table A only. A shop manager sees Tables A and B. An admin sees all three.
This approach works but can look odd, a shop manager would see both their management table and the customer orders table. The cleaner approach is to use three separate pages and redirect users to the appropriate page based on role using a plugin like Meow Login Redirects or a small filter in functions.php.
TableCrafter re-fetches this data on each page load by default. If your data source updates infrequently and your site has significant traffic, enable the built-in caching option in the table's Performance tab. This stores the fetched data for a configurable number of minutes and serves it from WordPress transients, reducing API calls to the source and improving page load time for visitors.
How Does Column-Level Role Gating Work?
For cases where the Shop Manager and Admin views differ only in a few columns, you can use a single table config with column-level role gating instead of two separate configs:
In the column settings for a sensitive column (e.g., line_item_cost), set Minimum role to view this column to Administrator. Shop managers will see all other columns but not this one. The column does not appear in the table HTML at all for shop managers, it is not hidden by CSS.
Column-level role gating reduces the number of table configs to maintain but makes the single config more complex. For three clearly distinct views, separate configs are easier to reason about and audit.
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.
How Does Security Considerations Work?
- TableCrafter's role checks fire on every AJAX request, not just the initial page render. A shop manager cannot trigger an admin-only column by modifying AJAX parameters.
- The current-user filter for customer tables is enforced server-side. Customers cannot bypass it by modifying the shortcode or the request.
- Inline edit permissions are checked on the server when the edit request is received, independent of whether the edit UI was rendered. A customer-role user who somehow triggers an edit request will receive a permission-denied response.
- Export requests go through the same permission checks as table data requests. A customer can only export their own orders; a shop manager can export all orders.
What Is Summary: Three-Role Configuration at a Glance?
Each WooCommerce role gets a separate TableCrafter table configuration with different column sets, row visibility scopes, and shortcode attributes. This table summarizes the setup described throughout this guide:
- Customer: current-user filter (sees only their own orders), read-only, 5 columns visible (Order Number, Date, Items, Total, Status), no cost or margin data. Shortcode:
[tablecrafter id="5" search="true"] - Shop Manager: all orders visible, Status column inline-editable, 8 columns (adds Shipping Address, Payment Method, and Customer Name), export enabled, filter controls for Status and Date. Shortcode:
[tablecrafter id="6" edit="true" filter="true" search="true" export="true"] - Administrator: all orders visible, all columns including cost and margin, bulk actions (e.g. mark multiple orders as fulfilled), export enabled. Shortcode:
[tablecrafter id="7" edit="true" filter="true" search="true" export="true"]
Each configuration is independent: changing the column set on the administrator table does not affect the customer table. You can also share the same underlying data source across all three configurations, which means any change to order data is reflected immediately in all three table views without any synchronization step.
Frequently Asked Questions
What Is the Three-Table Strategy?
The cleanest approach is to create three separate table configurations sharing the same WooCommerce Orders data source. Each config is tuned for one role's needs:
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.
This configuration is saved to the WordPress database immediately. There is no draft or preview state for table settings; once you click Save, the change goes live on every page where this table is embedded via shortcode or block.
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.