Allow user to pause WooCommerce Subscription

by Sarah   Last Updated April 16, 2018 12:08 PM

We want to allow users on our store to pause their daily subscriptions for one, two or three weeks from their account area. They can also unpause once they have paused to revert to their normal payment date (or the current date, if that has passed).

My code is below. It alters the post meta for _schedule_next_payment. If you pause your subscription, the set_payment_date function deletes the existing post meta for that ID and key, and adds a new one.

The 'next payment date' then shows correctly in the admin and the customer area, but I've found that this change doesn't seem to be enough and orders are still generated while the subscription should be paused. Anyone know what I am missing? It seems to be only the next repeat order that is still generated, and then subsequent days' orders are (correctly) not getting generated.

I think it might be a woocommerce_scheduled_subscription_payment task in Tools...Scheduled Action for the subscription that stays even when I change the post meta. What is the best way for me to delete that?

<?php

class WCS_Pause_Abstract

{
    public function run() {
        add_action('wp_loaded', [$this, 'check_pause_subscription'], 1000);
    }

    public function check_pause_subscription() {

        if ( isset( $_GET['pause_subscription'] ) && isset( $_GET['subscription_id'] ) && isset( $_GET['_wpnonce'] )  ) {

            $user_id      = get_current_user_id();
            $subscription = wcs_get_subscription( $_GET['subscription_id'] );
            $pause   = $_GET['pause_subscription'];

            if ( $this->validate_request( $user_id, $subscription, $pause, $_GET['_wpnonce'] ) ) {
                if ($pause == 'reset') {
                    $this->unpause_subscription($subscription, $pause);
                }
                else {
                    $this->pause_subscription($subscription, $pause);
                }
                wp_safe_redirect( $subscription->get_view_order_url() );
                exit;
            }

        }
    }

    protected function validate_request( $user_id, $subscription, $pause, $nonce ) {
        $subscription = ( ! is_object( $subscription ) ) ? wcs_get_subscription( $subscription ) : $subscription;

        if ( ! wcs_is_subscription( $subscription ) ) {
            wc_add_notice( __( 'That subscription does not exist. Please contact us if you need assistance.', 'woocommerce-subscriptions' ), 'error' );
            return false;

        } elseif ( ! empty( $wpnonce ) && wp_verify_nonce( $wpnonce, $user_id . $subscription->get_id() . 'pause_subscription' ) === false ) {
            wc_add_notice( __( 'Security error. Please contact us if you need assistance.', 'woocommerce-subscriptions' ), 'error' );
            return false;

        } elseif ( ! user_can( $user_id, 'edit_shop_subscription_status', $subscription->get_id() ) ) {
            wc_add_notice( __( 'That doesn\'t appear to be one of your subscriptions.', 'woocommerce-subscriptions' ), 'error' );
            return false;
        }

        return true;
    }

    protected function pause_subscription($subscription, $pause) {

        switch ($pause) {
            case '1-week' :
                $add_time = '+1 week';
                break;
            case '2-weeks' :
                $add_time = '+2 weeks';
                break;
            case '3-weeks' :
                $add_time = '+3 weeks';
                break;
            default : 
                $add_time = false;
        }

        if (!$add_time) {
            wc_add_notice( __( 'Invalid subscription request.', 'woocommerce-subscriptions' ), 'error' );
            return false;
        }

        $normal_timestamp = strtotime($subscription->calculate_date('next_payment'));
        $pause_date = date( 'Y-m-d H:i:s', strtotime($add_time, $normal_timestamp) );
        $this->set_payment_date($subscription, $pause_date);
        $subscription->add_order_note( 'Customer paused subscription for '. $add_time );        
        wc_add_notice( __( 'Successfully paused subscription.', 'woocommerce-subscriptions' ), 'success' );
        return true;

    }

    protected function set_payment_date($subscription, $date) {
        delete_post_meta($subscription->get_id(), '_schedule_next_payment');
        update_post_meta($subscription->get_id(), '_schedule_next_payment', $date);
    }

    protected function unpause_subscription($subscription, $pause) {
        if ($pause != 'reset') {
            wc_add_notice( __( 'Invalid subscription request.', 'woocommerce-subscriptions' ), 'error' );
            return false;
        }

        $this->reset_payment_date($subscription);
        wc_add_notice( __( 'Successfully reset subscription payment date.', 'woocommerce-subscriptions' ), 'success' );
        $subscription->add_order_note( 'Customer unpaused/reset payment date of subscription.' );
        return true;              
    }

    protected function reset_payment_date($subscription) {

        delete_post_meta($subscription->get_id(), '_schedule_next_payment');

        $reset_date = $subscription->calculate_date('next_payment');
        $today = date('Y-m-d H:i:s', strtotime('+ 2 hours'));

        if ($reset_date < $today) {
            $reset_date = $today;
        }

        update_post_meta($subscription->get_id(), '_schedule_next_payment', $reset_date);
    }

    protected function find_next_payment_date($subscription) {
        $next_payment_date = $subscription->get_date('next_payment');
        if (!$next_payment_date) $next_payment_date = $subscription->calculate_date('next_payment');
        return $next_payment_date;
    }

}

$pause = new WCS_Pause_Abstract();
$pause->run();


Related Questions






WooCommerce WC_Subscription Get from Order ID

Updated April 14, 2016 08:03 AM