The Most Useful WooCommerce Subscriptions Hooks

Diagram of WordPress action hooks branching off a central WooCommerce subscription lifecycle timeline

Why This Matters

WooCommerce Subscriptions is built on the same action/filter hook system as WordPress and WooCommerce core, which means almost anything about how a subscription behaves can be customized without editing the plugin's own files — the safe, update-proof way to change behavior. The hooks below cover the situations that come up most often in real custom development work.

Reacting to a Status Change

woocommerce_subscription_status_{status} fires whenever a subscription moves into a specific status, and is the most general-purpose hook for custom logic — granting or revoking access to something outside WooCommerce's own product/order system, for example.

add_action( 'woocommerce_subscription_status_active', function( $subscription ) {
    $user_id = $subscription->get_user_id();
    // Example: grant access to a custom membership feature.
    update_user_meta( $user_id, 'has_active_subscription', 'yes' );
} );

add_action( 'woocommerce_subscription_status_cancelled', function( $subscription ) {
    $user_id = $subscription->get_user_id();
    update_user_meta( $user_id, 'has_active_subscription', 'no' );
} );

Running Logic Before a Renewal Payment

woocommerce_scheduled_subscription_payment fires right before WooCommerce Subscriptions attempts to charge the renewal — useful for adjusting the renewal amount dynamically, or for a final validation check before money changes hands.

add_action( 'woocommerce_scheduled_subscription_payment', function( $amount_to_charge, $subscription ) {
    // Example: log every renewal attempt for later auditing.
    error_log( sprintf(
        'Renewal attempt for subscription #%d: charging %s',
        $subscription->get_id(),
        $amount_to_charge
    ) );
}, 10, 2 );

Acting After a Successful Renewal

woocommerce_subscription_payment_complete fires once a renewal payment has actually succeeded — the right place for anything that should only happen after money has been captured, such as extending access to a third-party service via API.

add_action( 'woocommerce_subscription_payment_complete', function( $subscription ) {
    // Example: sync renewed status to an external system.
    my_external_service_extend_access( $subscription->get_customer_id() );
} );

Common Mistakes

  • Using woocommerce_subscription_payment_complete for anything that must happen before payment. By the time this fires, the charge has already succeeded — too late to cancel or adjust it.
  • Forgetting the priority/argument-count parameters on add_action() when a hook passes more than one argument, silently dropping the second parameter.
  • Hooking into WooCommerce core order hooks instead of the subscription-specific ones and then having to manually check whether the order is actually a renewal — the subscription hooks already do that filtering for you.

Where to Go Deeper

These three cover the majority of real customization requests, but WooCommerce Subscriptions exposes many more hooks for finer control — switching between plans, resubscribing after cancellation, and trial-period logic each have their own dedicated actions. For anything beyond a small snippet, especially logic that touches money or access control, it's worth having it reviewed rather than deployed straight to a live store.

Need a custom subscription feature built properly — tested against failed payments, retries and edge cases, not just the happy path? See custom WooCommerce development.

Available for new projects

NEXT STEP

Rather have it fixed than keep reading?

Based in Bangladesh — serving clients worldwide. Tell me what's happening and you'll have a reply within one working day.

  • Reply within one working day
  • Fixed quote before work starts
  • UK, EU and US hours covered