Skip to main content
Robert Michalski

Notifying external systems on WordPress actions

Lets say you have a product or service, an app, webapp, premium newsletter or similar as an independent system, either a custom developed system or a third-party system that you pay for. If you're using WordPress for login, user management or payments, the "external" system needs a way to find out what the user should be allowed to do.

One way is for the external system to check with WordPress each time something requiring user credentials or permissions happens. Depending on how often it needs to check, this can cause a significant load on the WordPress site, slowing it down or even making it unavailable, e.g. causing 502 errors. This can be solved by caching the results of requests made to WordPress in the external system, even a couple of seconds could help a lot. However, if the WordPress system goes down for some reason, crashing, maintenance or heavy load, then either the external system will experience errors, or the customers will not get access to what they paid for.

A better way is to store information about the customers and what they have access to in the external system, then let the WordPress system update that information in the external system. For instance when a user updates their information for example name, email, or when a customer has made a payment, or canceled either an order or a subscription.

First create functions to send information to the external system, e.g. calling the API of the external system.

function YOUR_PREFIX_update_user_in_webapp($payload, $external_id) {
    $id = empty($external_id) ? '' : '/' . $external_id;

    $response = wp_remote_request(
        '' . $id,
            'method' => empty($id) ? 'POST' : 'PUT',
            'data' => wp_encode_json($payload),
            'headers' => [
                'Accept': 'application/json'
                'Content-Type': 'application/json'

    ... // Detect errors, log success or failure.

    $body = json_decode(wp_remote_retrieve_body($response));
    $external_id = $body->id; // Whatever property containing id of the resource in the external system.

    return $external_id; // Returns id of new user from the external system.

Then create a function to gather and prepare all necessary data that the external system requires.

function YOUR_PREFIX_update_user_in_webapp_on_user_changes($user_id) {
    // Gather all necessary data
    $user = get_userdata($user_id);
    ... // Get more info, eg. user meta fields, subscription, order, custom fields.
    ... // Get their purchased membership level, product sku or some other identifier that tells the external system what to grant access to.
    ... // Remember to set level, access or permissions info to a default value, in case they cancelled, asked for a refund or didn't renew.

    // Transform data to the format expected by the external system.
    $payload = [
        'email' => $user['user_email'],
        //'level' => ...,
        //'permissions' => ...,
        //'product_sku' => ...,

    $external_id = get_user_meta($user_id, 'my_external_system_id', true); // Try getting existing id for identifying the user in the external system.

    $response_id = YOUR_PREFIX_update_user_in_webapp($payload, $external_id);

    if (!empty($response_id)) {
        // When the response is successful,
        // save the id of the created resource in user_meta,
        // to be able to find the user in the external system.
        update_user_meta($user_id, 'my_external_system_id', $response_id);
    } else {
        ... // Log any errors, schedule job to try again later, whatever is necessary.

Sending notifications from WordPress on user events #

Setup action hooks for user related events and call your new functions.

The following WordPress action hooks can be used to accomplish this.

add_action('user_register', 'YOUR_PREFIX_update_user_in_webapp_on_user_changes',  10, 1);
add_action('profile_update', 'YOUR_PREFIX_update_user_in_webapp_on_user_changes',  10, 1);
add_action('delete_user', function($user_id) {
    $response = wp_remote_delete('');
    ... // check success and log on failure
}, 10, 1)

Sending notifications after successful WooCommerce payment events #

After a user has completed a payment and become a customer, the external system needs to be notified to allow access to the purchased digital goods.

If it was a one time payment or for life-time access, then our work is done... But hold-on, what if the customer cancels the order or wants a refund? Then the external system must be notified about the cancellation or the refund of the order. Or the payment grants access to the product or service for a limited period of time, like a month or a year, but the customer decides not to renew?

The following WordPress action hooks can be used to accomplish this.

Note: The on-hold status should only be used if the customer should lose access to the product or service as soon as possible, until they renew successfully. Order first gets a status of pending then on-hold, processing and last completed or failed, so they might lose access for a short while during a renewal payment.

function YOUR_PREFIX_update_user_in_webapp_on_order_status($order_id) {
    $order = wc_get_order($order_id);
    $user_id = $order->get_user_id();

//add_action('woocommerce_payment_complete', 'YOUR_PREFIX_update_user_in_webapp_on_order_status',  10, 2);
add_action('woocommerce_payment_complete_order_status_completed', 'YOUR_PREFIX_update_user_in_webapp_on_order_status',  10, 2);
add_action('woocommerce_order_status_failed', 'YOUR_PREFIX_update_user_in_webapp_on_order_status',  10, 2);
add_action('woocommerce_order_status_cancelled', 'YOUR_PREFIX_update_user_in_webapp_on_order_status',  10, 2);
add_action('woocommerce_order_status_refunded', 'YOUR_PREFIX_update_user_in_webapp_on_order_status',  10, 2);
//add_action('woocommerce_order_status_on-hold', 'YOUR_PREFIX_update_user_in_webapp_on_order_status',  10, 2);

Sending notifications on WooCommerce Subscriptions events #

The easiest way to handle notification of an external system with WooCommerce Subscriptions is to use only woocommerce_subscription_status_updated with a clever handler.

function YOUR_PREFIX_update_user_in_webapp_on_subscription_status($subscription, $new_status, $old_status) {
    if (in_array($new_status, ['completed', 'cancelled', 'refunded'], true)) {
        $user_id = $subscription->get_user_id(); // WC_Subscription is an extension of WC_Order

add_action('woocommerce_subscription_status_updated', 'YOUR_PREFIX_update_user_in_webapp_on_subscription_status',  10, 3);