6

I would like to change the next payment date of active subscriptions after the Initial (first) order was created.

current code which does not work. Why? What am i missing?

//fires when new order payment is complete (NOT RENEWAL but original order!)
add_action('woocommerce_payment_complete', 'fm_upate_next_payment_datetime');

function fm_upate_next_payment_datetime ( $order_id ) {

if (WC_Subscriptions_Order::order_contains_subscription( $order_id ) == false) return;      
$subscription_key = WC_Subscriptions_Manager::get_subscription_key( $order_id, $product_id
= '');

 //hard code next payment date...(must be in future)
$next_payment = date( 'Y-m-d H:i:s', '2016-05-20 00:10:10' );

//set the new payment date  
WC_Subscriptions_Manager::set_next_payment_date( $subscription_key, $user_id = '', $next_payment );

}
SgtPepperAut
  • 123
  • 1
  • 3
  • 10

6 Answers6

5

what you said and also we need to set a start date! (can be NOW) but if its not passed it will throw an error. Got it to work like this:

function saveNewDate($post_id) {

    $subscription = wcs_get_subscription( $post_id );
    $dates        = array();

    $datetime           = current_time( 'timestamp', true );
    $dates[ 'start' ] = date( 'Y-m-d H:i:s', $datetime );
    $datetime = strtotime( "08/23/2016 23:30" );
    $dates['next_payment'] = date( 'Y-m-d H:i:s', $datetime );

    try {
        $subscription->update_dates( $dates, 'gmt' );
        wp_cache_delete( $post_id, 'posts' );
    } catch ( Exception $e ) {
        wcs_add_admin_notice( $e->getMessage(), 'error' );
    }
}
SgtPepperAut
  • 123
  • 1
  • 3
  • 10
4

working solution for me is (see also https://docs.woocommerce.com/document/subscriptions/develop/functions/#section-4):

function update_next_payment_date($subscription) {
    $date = new DateTime('2021-05-28');
    $date->setTime(8, 55);

    $subscription_next_payment_date = date_format($date, 'Y-m-d H:i:s'); // = '2021-05-28 08:55:00'

    $new_dates = array(
        'start' => $subscription->get_date('start'),
        'trial_end' => $subscription->get_date('trial_end'),
        'next_payment' => $subscription_next_payment_date,
        'last_payment' => $subscription->get_date('last_payment'),
        'end' => $subscription->get_date('end'),
    );

    $subscription->update_dates($new_dates);
}
vorwerg-ni
  • 157
  • 1
  • 5
1

I believe that this doesn't work because you are calling $subscription_key using an empty variable $product_id.
In your function, with this code, you have no value for $product_id.

You should pass it by reference or extracting from the function.

fantaghirocco
  • 4,761
  • 6
  • 38
  • 48
1

Woocommerce subscription changed next payment date 3 days ago:

add_action('woocommerce_thankyou', 'nextpaymentdatechange', 10, 1);  

function nextpaymentdatechange( $order_id ){
    if ( wcs_order_contains_subscription( $order_id ) ) {
        $subid = $order_id + 1;
        $nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
        $threedays_ago = date( 'Y-m-d H:i:s', strtotime( '-3 days', strtotime( $nextdate )) );
        update_post_meta( $subid , '_schedule_next_payment', $threedays_ago, $nextdate );
    }
}
Axel Podehl
  • 4,034
  • 29
  • 41
sagar
  • 11
  • 2
1
add_action('woocommerce_thankyou', 'nextpaymentdatechange', 10, 1);  

function nextpaymentdatechange( $order_id ){
    if ( wcs_order_contains_subscription( $order_id ) ) {
        $subid = $order_id + 1;
        $nextdate = get_post_meta( $subid, '_schedule_next_payment', true );
        $threedays_ago = date( 'Y-m-d H:i:s', strtotime( '-3 days', strtotime( $nextdate )) );
        update_post_meta( $subid , '_schedule_next_payment', $threedays_ago);
    }
}

Please, don't use 4 values in update_post_meta().

Only use 3 values by changing this :

update_post_meta( $subid , '_schedule_next_payment', $threedays_ago, $nextdate );

to :

update_post_meta( $subid , '_schedule_next_payment', $threedays_ago);
Littm
  • 4,923
  • 4
  • 30
  • 38
Wprog_dy
  • 67
  • 5
  • 1
    Thank you for your contribution. While this code may solve the OP's issue, it's best to add context, or explain why/how this code fixes the problem. SO is valuable for learning and sharing knowledge (as opposed to bring a code providing service for individual problems). This way future visitors can learn, and apply this info to their own issues, or prevent them in the first place. Links to source documentation as follow up info is also encouraged. (Also, why do you ask the user to "please" pass in 3 values, not 4? If that's by definition, state this fact, and possibly include a doc link.) – SherylHohman May 11 '20 at 08:53
0

This may be helpful for someone. If you want to change the subscription's next payment date for a specific product, then follow this code:

add_action( 'woocommerce_checkout_subscription_created', 'sw_custom_subscriptions_next_payment', 10, 3);
function sw_custom_subscriptions_next_payment( $subscription, $order, $recurring_cart ) {
  
  $order_items  = $subscription->get_items();
  $product_id   =  [];

  // Loop through order items
  foreach ( $order_items as $item_id => $item ) {
    // To get the subscription variable product ID and simple subscription  product ID
    $product_id[] = $item->get_product_id();
  }

  if ( in_array( 7856, $product_id ) ) {
    $new_dates = array(
      'next_payment' => date( 'Y-m-d H:i:s', strtotime( '+3 years', time() ) )
    );
  
    $subscription->update_dates($new_dates, 'site');
  }
}

Reference: https://stackoverflow.com/a/67420195/8498688

To change the first renewal date on Cart and checkout pages, follow the below steps:

1- Remove the native filter hook

// Remove WCS native subscription first renewal date callback from cart/order totals on checkout page
remove_filter( 'wcs_cart_totals_order_total_html', 'wcs_add_cart_first_renewal_payment_date');

2- Add custom callback

add_filter( 'wcs_cart_totals_order_total_html', 'sw_add_cart_first_renewal_payment_date', 10, 2 );
function sw_add_cart_first_renewal_payment_date( $order_total_html, $cart ) {

    if ( 0 !== $cart->next_payment_date ) {
    $product_id = [];
    foreach( $cart->get_cart() as $key => $cart_item ){
      $product_id[] = $cart_item['product_id'];
    }

    if ( in_array( TRIENNUAL_SUBSCRIPTION_PRODUCT_ID, $product_id ) ) {
      $first_renewal_date = date_i18n( wc_date_format(), wcs_date_to_time( '+3 years' ) );
    } else {
      $first_renewal_date = date_i18n( wc_date_format(), wcs_date_to_time( get_date_from_gmt( $cart->next_payment_date ) ) );
    }
        // translators: placeholder is a date
        $order_total_html .= '<div class="first-payment-date"><small>' . sprintf( __( 'First renewal: %s', 'woocommerce-subscriptions' ), $first_renewal_date ) . '</small></div>';
    }

    return $order_total_html;
}