I need to add an API endpoint in my WordPress plugin that will write to the database, etc. I want it to be triggered by a remote system that will call this new API.
However, I’d like to use the built-in WooCommerce REST authentication, the auth set up here:
(And no, those credentials don’t work, anymore).
Is there a way to do this? To add a custom HTTP endpoint that will use the auth from WooCommerce and then run some arbitrary code that I want to run?
Or is there a way to add a hook on an existing WooCommerce API endpoint to run before that endpoint executes? I just need a way to use the existing WooCommerce REST API auth to trigger some updates I need to run in my plugin.
3
Answers
You can add a route under the Woocommerce endpoint to use this key/secret authentication system.
Here’s a working example:
This will:
https://example.com/wp-json/wc/test
is_user_logged_in()
andwp_get_current_user()
will depend on the correct combination of key/secret. If correct, a the associated user will be "authentified" as for WordPress.[true, WP_user_object]
, if incorrect key[false, Empty_user_object]
.my_awesome_func()
is not reached in this case. I believe it’s like wp-login, custom error message when correct login (key), nice ^^’)You then need to secure your route by your rules:
if(!is_user_logged_in()) return false
wp_get_current_user()->ID
WP_REST_Request $request
parameter to handle GET or POST HTTP parameters.So it could look like:
It seems there may be proper ways to add a Woocommerce REST API endpoint (couldn’t find proper documentation about it…). But I tested this and it worked, at least to use the Woocommerce key/Secret authentication system, which I believe is applied under the
/wc/
endpoint.Note: careful adding routes to the wc endpoints, as you may override an existing route endpoint. Eg: adding
/product/mytest
could conflict with an official Woocommerce route that handles/product/[product_id]
.Note 2: I first tested with a custom WordPress REST API route, and passing Woocommerce key/secret to see if WordPress could see me correctly authenticated and identified. But it didn’t work (WP uses the core API auth system). So I moved to the Woocommerce API endpoint.
Note 3: You could achieve the same using the WordPress REST API with a custom route, and a "machine to machine" authentication plugins like Oauth, application password, JWT… like described on WP REST API authentication documentation page.
A bit late but with reflection we can use WC auth logic to validate custom API routes.
If you would like do add this authentication checks to other routes globally, f.e. core WP routes, you can use
add_filter('rest_dispatch_request', function ( $intendedResponse, $request, $route )
filter and try to match passed$route
param with regex or some other way.Just putting my two cents in…
I was wondering if there’s another way to add a new API endpoint which uses WooCommerce consumer key and secret authorization, avoiding possible collisions with WooCommerce
/wc/
endpoints, and not resorting to using reflection.The answer is in the
is_request_to_rest_api
function included in theWC_REST_Authentication
class. In order to use WooCommerce authentication method, the endpoint namespace of third-party plugins should start withwc-
.E.g.:
Please note the
wc-myprefix/v1
namespace of the new route (starting withwc-
), and the use of thecurrent_user_can
function in the permission callback. It’s the call to this function that triggers the actual authentication.And if you’re like me and don’t really want anybody telling you how your endpoint namespace should be named, there’s a handy filter (
woocommerce_rest_is_request_to_rest_api
) that you can use to implement your own logic to determine whether the call is to a rest API endpoint (i.e. check for your own particular endpoint namespace).