skip to Main Content

I have 1 subscription with 3 variations.
I’m trying to force the first renewal date depending on the variation ID that was purchased.

Variation 1 (876) set to renew every day – I want first re-bill date to be 11/15/2020 12:00AM
Variation 2 (877) set to renew every 2 days – I want first re-bill date to be 2/15/2021 12:00AM
Variation 3 (878) set to renew every 3 days – I want first re-bill date to be 8/15/2021 12:00AM

I thought the below code worked. After the order is created the next bill date DOES show one of the above dates, but it must not be registering with WooCommerce or something, because the renewals are triggering regardless of the above dates.

For my test, I create an order for Variation 1, the next payment date is showing 11/15/2020, but it’s renewing the next day.

Hoping to get some insight from someone smarter than me. Again, the sub’s next bill date is showing the above dates, but renewals are still happening early/before the above dates.


function nextpaymentdatechange( $order_id ){
    $order = wc_get_order( $order_id );
$items = $order->get_items(); 
foreach ( $items as $item_id => $item ) {
   $product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
   if ( $product_id === 876 ) {
        $subid = $order_id + 1;
        $nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
        $new_date = date( 'Y-m-d H:i:s', strtotime( '2020-11-15 07:00:00', strtotime( $nextdate )) );
        update_post_meta( $subid , '_schedule_next_payment', $new_date);
   }
    else{ if ( $product_id === 877 ) {
        $subid = $order_id + 1;
        $nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
        $new_date = date( 'Y-m-d H:i:s', strtotime( '2021-02-15 07:00:00', strtotime( $nextdate )) );
        update_post_meta( $subid , '_schedule_next_payment', $new_date);
    }
         else{
              if ( $product_id === 878 ) {
        $subid = $order_id + 1;
        $nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
        $new_date = date( 'Y-m-d H:i:s', strtotime( '2021-08-03 07:00:00', strtotime( $nextdate )) );
        update_post_meta( $subid , '_schedule_next_payment', $new_date);
    }
         }
        
    }
   }
} ```

2

Answers


  1. To make that work you need first to get WC_Subscription Objects from the order using:

    $subscriptions = wcs_get_subscriptions_for_order( $order_id );
    

    that gives an array of the WC_Subscription Object(s) for the Order, from an order Id.

    Now you can use the WC_Subscription method update_dates($dates), that requires to set an array of all dates types from a subscription that are 'start', 'trial_end', 'next_payment', 'last_payment' and 'end'.

    To get a specific date from a subscription, we use WC_Subscription method get_date($date_type).

    Additionally I use WC_Subscription method can_date_be_updated($date_type), to check if a date type can be updated.

    I am not sure about which ones dates require to be updated as they are likely related.

    You can try the following that should update the related(s) subscription(s) dates from an order, based on your code (the code doesn’t throw errors).

    I thin that you need to change 'next_payment', 'last_payment' and 'end' dates.

    Using the methods update_dates() and save() at the end of the code, allows to change dates, save all required data to database refreshing cached data.

    The function code:

    function nextpaymentdatechange( $order_id ){
        // YOUR SETTINGS: Set in this array your desired dates (value(s)) by product Id (key)
        $dates_for_product = array(
            876 => array(
                'next_payment' => '2020-11-15 07:00:00',
                'last_payment' => '2020-11-16 07:00:00',
            ),
            877 => array(
                'next_payment' => '2021-02-15 07:00:00',
                'last_payment' => '2021-02-16 07:00:00',
            ),
            878 => array(
                'next_payment' => '2021-08-03 07:00:00',
                'last_payment' => '2021-08-04 07:00:00',
            ),
        );
    
        // The date types for subscriptions
        $suscription_date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end');
    
        // Get the subscriptions from the current order Id
        $subscriptions = wcs_get_subscriptions_for_order( $order_id );
    
        // Loop through subscriptions
        foreach ( $subscriptions as $subscription_id => $subscription ) {
            // Loop through items in this subscription
            foreach ( $subscription->get_items() as $item_id => $item ) {
                $product = $item->get_product();
    
                // Loop through defined products dates
                foreach( $dates_for_product as $product_id => $new_dates ) {
                    // If current subscription product id matches
                    if ( $product->get_id() == $product_id ) {
                        $current_product_id = $product_id; // Set current product id
                        break; // Stop the current loop
                    }
                }
                if ( isset($current_product_id) ) {
                    break; // Stop the current loop
                }
            }
    
            // Updating subscription dates
            if ( isset($current_product_id) ) {
                $updated_dates = array(); // Initializing
    
                // Loop through subscription date types
                foreach( $suscription_date_types as $date_type ) {
                    $date           = $subscription->get_date($date_type);
    
                    // For 'next_payment' and 'last_payment' dates
                    if( isset($new_dates[$date_type]) && $subscription->can_date_be_updated($date_type) ) {
                        $updated_dates[$date_type] = $new_dates[$date_type];
                    }
                    // For 'end' date
                    elseif ( $date_type === 'end' && $subscription->can_date_be_updated($date_type) ) {
                        $updated_dates[$date_type] = $new_dates['last_payment']; // ??? Or may be instead: $date;  … (or simply: 0;)
                    }
                    // Other dates
                    else {
                        $updated_dates[$date_type] = $date;
                    }
                }
    
                // Update subscription date, save to database and refresh cached data
                $subscription->update_dates($updated_dates);
                $subscription->save();
            }
        }
    }
    

    Code goes in functions.php file of your active child theme (or active theme). It should works.

    Login or Signup to reply.
  2. if i understand, this :

    function nextpaymentdatechange( $order_id ){
    // YOUR SETTINGS: Set in this array your desired dates (value(s)) by product Id (key)
    $dates_for_product = array(
        588 => array(
            'end' => '2020-12-05 07:00:00',
        ),
    );
    
    // The date types for subscriptions
    $suscription_date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end');
    

    Set automaticaly a end date 05 of december for my product 588 (it’s a simple subscription)?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search