How do you add customer capability after Woocommerce purchase?

First, you indicated you want to add a capability to a user of your WordPress site. (This is in contrast to adding a capability to a role, as well as being different from adding a role to a user. More about all that is here.) As you’re new to this, I wanted to point that out.

Second, to the code. I don’t know what your ordering process looks like so I can’t advise as to what hook to use. WooCommerce offers a huge number of entry points into its processes. For the sake of argument, let’s say that you want to add the capability when a user of your site completes payment for the order. In such a case, you may want to enter the WooCommerce process when the WC_Order->payment_complete() method is called. You could use the woocommerce_payment_complete action hook (and you already know how to use hooks).

add_action('woocommerce_payment_complete', 'bucktastic_adds_cap');
function bucktastic_adds_cap($order_id) { ... }

This hook passes the order number of a WC_Order that is used in the hook’s callback function. We then have to use this order number to manipulate the order in question. So, let’s grab the order object so we can manipulate the order (and you know how to do that as well).

$order = wc_get_order($order_id);

This could return FALSE, so we’ll have to check that before continuing on in our script. But, let’s say we get the order object. The next thing to do is to try to get the WordPress user of the customer. According to the docs, our WC_Order has a nice little function that will return the user of our site, the WP_User, who is associated with the order:

$user = $order->get_user();

Again, this function could return FALSE, so we’ll have to check for that. Now that we have our user object, we can add a capability to that use. (You already know how to use the WP_User->add_cap() method, and you are suggesting that you want to add the cst11 capability to your website user.) Putting it all together …

add_action('woocommerce_payment_complete', 'bucktastic_adds_cap');

function bucktastic_adds_cap($order_id) {
    // Grab the order, but do not continue if the order number is invalid
    $order = wc_get_order($order_id);
    if($order === FALSE) return;

    // Grab the user, but do not continue if no user could be found
    $user = $order->get_user();
    if($user === FALSE) return;

    // Add the capability to bucktastic's website user.
    $user->add_cap('cst11');
}

I do have some questions for you, because your code represents that you are asking for more help than what you state in your question.

1.) Why are you iterating over all the list items and checking the item number before adding the capability? Are you trying to only add the capability to the user if they purchase a specific item?

2.) Why are you redefining the function add_cap_to_role() to add the capability every time you iterate over an item of the order? (This will definitely throw an error. But it you are coding PHP, so you have a basic understanding of how to code and you already knew this.)

3.) Why are you requiring yourself to call a function to add the capability? (That is the purpose of the callback function, which you can use elsewhere aside from the hook, so to make another function to do the exact same thing is bad coding practice.)

4.) If you are adding a capability to an individual user account, why are you trying to manipulate the role on every purchase? (Please refer to my opening statement for some clarity as to why I’m asking this question.)

EDIT: Here’s a link to some more possible help for you.