The model
All vendor/order/product write paths reachable from the app go through one rule set (mam_wc_pv_authorization):
- The actor is resolved server-side (the app-token user via
mam_user_id(), falling back to the WP session user) — never from request parameters. manage_woocommerceacts as the store-manager override on every check.- Vendor-scoped operations require the actor to be staff of that vendor (via
WC_Product_Vendors_Utils::get_all_vendor_data). - Everything is deny by default, and every final decision passes through a filter so a site can loosen or tighten any rule.
Each filter receives the computed boolean first; return it unchanged to keep the default rule.
The filters
| Filter | Signature (after $allowed) |
Gates | Default rule |
|---|---|---|---|
mam_wc_pv_user_can_manage_vendor |
$user_id, $vendor_id |
Vendor profile/staff/location writes; “is this my store?” | Store manager, or staff of $vendor_id |
mam_wc_pv_user_can_manage_order |
$user_id, $order_id |
Vendor-side order ops: refund, cancel, status change, manual settle | Store manager, or staff of a vendor that owns a line item in the order |
mam_wc_pv_user_is_order_customer |
$user_id, $order_id |
Customer-side order ops (cancellation requests) | Actor is the order’s customer |
mam_wc_pv_user_can_view_order |
$user_id, $order_id |
Read access to order details/PII | Anyone who may manage it, its customer, or the driver assigned via assigned_to_driver order meta |
mam_wc_pv_user_can_manage_product |
$user_id, $product_id |
Product create/edit/availability writes | Store manager, staff of the product’s vendor, or the product’s post author; non-product post types always denied |
mam_wc_pv_user_can_manage_location |
$user_id, $post_id |
pv-location writes |
Store manager, staff of the location’s vendor (mam-pv-id meta), or the post author; non-pv-location posts always denied |
mam_wc_pv_user_can_approve_vendor |
$user_id, $vendor_id |
Vendor approval / role elevation | Store manager only |
mam_wc_pv_user_can_assign_role |
$user_id, $role, $vendor_id |
Role grants from the Staff Manager | Role in the mam_pv_assignable_roles whitelist; vendor-admin role only for store managers or a vendor admin on their own vendor |
All run apply_filters( $name, bool $allowed, int $user_id, … ) and expect a boolean back.
When they fire
On every corresponding app form submission or AJAX call — vendor profile saves, staff edits, product/location writes, order refund/cancel/settle, vendor approval. They are decision points, not notifications: returning false blocks the operation with a “Not authorized” response.
Example — extend order management to a custom role
add_filter( 'mam_wc_pv_user_can_manage_order', function ( $allowed, $user_id, $order_id ) {
if ( ! $allowed && user_can( $user_id, 'mam_dispatcher' ) ) {
$allowed = true; // dispatchers may work any order
}
return $allowed;
}, 10, 3 );
Example — tighten product edits to vendor admins only
add_filter( 'mam_wc_pv_user_can_manage_product', function ( $allowed, $user_id, $product_id ) {
if ( $allowed && ! user_can( $user_id, 'manage_woocommerce' ) ) {
$user = get_userdata( $user_id );
$allowed = $user && in_array( 'wc_product_vendors_admin_vendor', (array) $user->roles, true );
}
return $allowed;
}, 10, 3 );
Notes
- These filters are escape hatches; returning
trueunconditionally removes a security boundary. Always preserve$allowedfor cases you don’t intend to change. - Resolve actors with
mam_wc_pv_authorization::acting_user_id()if you call the static check methods yourself. - For a simple “is this user on this vendor?” membership test, use the lighter
mam_pv_check_userfilter instead.
Related articles
- Hook:
mam_pv_check_user - Hook:
mam_pv_assignable_roles - Recipe: Staff manager configuration
Metadata
| Field | Value |
|---|---|
| Article type | Hook Reference |
| Plugin slug | mam-woocommerce-product-vendors |
| Applies to plugin version | 26.19.1+ |
| Category | Extending MAM Suite |
| Hook type | filter (one per decision) |
| Audience | PHP developer / integrator |
| Last verified | 2026-06-10 |
