Hook: the mam_wc_user_can_* authorization filters

Why they exist

Every state-changing order action in mam-woocommerce is deny by default: the acting user is resolved server-side (from the app session/token, never from request parameters) and must pass an ownership or role check before anything happens. These filters are the documented escape hatch for site setups the built-in rules don’t fit — e.g. a concierge role that cancels orders for customers.

The default rules

Scope Allowed when…
(always) the user has the manage_woocommerce capability
customer actions (cancel, feedback, refund) the user is the order’s customer
fulfillment actions (change status, complete) the user is staff of a vendor that owns one of the order’s line items (Product Vendors stores)

The filters

All receive the order action’s current answer first and must return a boolean.

Filter Signature Fires
mam_wc_user_can_change_order_status ( bool $allowed, int $user_id, int $order_id ) on every vendor status-change form submission (single and multi-order — once per order). Can grant or veto.
mam_wc_user_can_complete_order ( bool $allowed, int $user_id, int $order_id ) on the vendor complete-order form submission. Can grant or veto.
mam_wc_user_can_cancel_order ( bool $allowed, int $user_id, int $order_id ) on a customer cancel-order form submission. Can grant or veto.
mam_wc_user_can_submit_order_feedback ( bool $allowed, int $user_id, int $order_id ) on a customer feedback submission. Can grant or veto.
mam_wc_user_can_refund_order ( bool $allowed, int $user_id, int $order_id ) inside the refund-allowed check, only after the ownership/manager checks have failed ($allowed is always false here). Grant-only — the policy checks (order status, Refund settings) still apply afterward.
mam_wc_user_can_submit_order ( bool $allowed, int $user_id ) at the start of order creation, only when no customer could be resolved for the request ($allowed is false, $user_id is 0 or the unresolved id). Grant-only, and note it has no order id — the order doesn’t exist yet.

A denial returns a Not authorized failure to the app and suppresses the action’s notifications.


Example — let a support role cancel any order

add_filter( 'mam_wc_user_can_cancel_order', function ( $allowed, $user_id, $order_id ) {

    if ( ! $allowed && user_can( $user_id, 'mam_support_agent' ) ) {
        $allowed = true;
    }

    return $allowed;
}, 10, 3 );

Example — veto self-completion under a dollar threshold

add_filter( 'mam_wc_user_can_complete_order', function ( $allowed, $user_id, $order_id ) {

    $order = wc_get_order( $order_id );
    if ( $allowed && $order && $order->get_total() > 500 && ! user_can( $user_id, 'manage_woocommerce' ) ) {
        $allowed = false; // big orders need a manager
    }

    return $allowed;
}, 10, 3 );

Notes

  • Be conservative: these gates are the security boundary for app-driven order changes. Grant on role/capability, never on request data.
  • $user_id is the server-resolved acting user; 0 means no user could be resolved.


Metadata

Field Value
Article type Hook Reference
Plugin slug mam-woocommerce
Applies to plugin version 26.19.3+
Category Extending MAM Suite
Hook type filters
Audience PHP developer
Last verified 2026-06-10
Was this article helpful?
Contents

    Need Support?

    Can't find the answer you're looking for? Don't worry we're here to help!