Skip to content

Instantly share code, notes, and snippets.

@danielbitzer
Last active Oct 6, 2021
Embed
What would you like to do?
AutomateWoo - Action function to change subscription next payment date
<?php
/**
* AutomateWoo action function to extend a subscription by 3 months.
*
* A note will be added to the subscription.
*
* Ensures that the dates near the end of the month are logically handled and do not shift to the start of the following month.
*
* Custom action function docs: https://automatewoo.com/docs/actions/custom-functions/
*
* @param $workflow AutomateWoo\Workflow
*/
function my_extend_subscription_automatewoo_action( $workflow ) {
// Valid options are: day, week, month or year
$date_period = 'month';
// E.g. extend by 3 months.
$number_of_periods = 3;
$subscription = $workflow->data_layer()->get_subscription();
$payment_date = $subscription->get_date( 'next_payment' );
if ( ! $payment_date ) {
return;
}
$payment_date_timestamp = wcs_date_to_time( $payment_date );
$new_payment_date_timestamp = wcs_add_time( $number_of_periods, $date_period, $payment_date_timestamp );
// Update the next payment date
$subscription->update_dates(
array(
'next_payment' => gmdate( 'Y-m-d H:i:s', $new_payment_date_timestamp ),
)
);
// Add note to subscription
$subscription->add_order_note(
sprintf(
'Subscription next payment date was extended from %s to %s by workflow: %s',
gmdate( wc_date_format(), $payment_date_timestamp ),
gmdate( wc_date_format(), $new_payment_date_timestamp ),
$workflow->get_title()
)
);
}
@leightona

This comment has been minimized.

Copy link

@leightona leightona commented Apr 2, 2020

Thanks again for putting this together Dan, very useful in the current COVID-19 situation to look after our customers with extensions.

I was also looking at this function which may be useful to incorporate to ensure there is no variable day shift across the varied month lengths. May be useful for people who need to ensure the next payment occurs on the same day, just in a different month.

https://www.php.net/manual/fr/datetime.modify.php

format('d'); $m = 12 * (0 <= $months?1:-1); for ($a = 1;$a < $years;++$a) { $date = addMonths($date, $m); } $months -= ($a - 1) * $m; $init = clone $date; if (0 != $months) { $modifier = $months . ' months'; $date->modify($modifier); if ($date->format('m') % 12 != (12 + $months + $init->format('m')) % 12) { $day = $date->format('d'); $init->modify("-{$day} days"); } $init->modify($modifier); } $y = $init->format('Y'); if ($leap && ($y % 4) == 0 && ($y % 100) != 0 && 28 == $init->format('d')) { $init->modify('+1 day'); } return $init; } $d = addMonths($d, +3); echo $d->format('Y-m-d') . "\n"; ?>
@danielbitzer

This comment has been minimized.

Copy link
Owner Author

@danielbitzer danielbitzer commented Apr 3, 2020

Glad I could help!

There should be no variable day shift, the day will always be the same in the different month. BUT, I just updated the function so that it accounts for dates at the end of the month in the same way WC Subscriptions normally does. More info: https://docs.woocommerce.com/document/subscriptions/faq/#what-about-subscriptions-purchased-on-the-last-day-of-the-month

@wgfinley

This comment has been minimized.

Copy link

@wgfinley wgfinley commented Apr 22, 2020

Hey Dan. I have a client that's looking to extend all current memberships by one year. This would seem to fit but I'm trying to figure out a trigger for it. Any suggestions?

@danielbitzer

This comment has been minimized.

Copy link
Owner Author

@danielbitzer danielbitzer commented Apr 23, 2020

Hey wgfinley, I'd recommend reaching out to support https://woocommerce.com/contact-us/
At the moment, We don't have a way to extend memberships via AutomateWoo.

@wgfinley

This comment has been minimized.

Copy link

@wgfinley wgfinley commented Apr 23, 2020

Thanks Dan, I should clarify, I was looking to extend subscriptions and not memberships (although those are tied into subscriptions). I did send in a ticket as Support had initially steered me this direction with my first inquiry. I think the part I'm not getting is how to do the custom trigger to kick this off.

@danielbitzer

This comment has been minimized.

Copy link
Owner Author

@danielbitzer danielbitzer commented Apr 24, 2020

You probably don't need a custom trigger. Have you see this example here? https://automatewoo.com/docs/examples/pause-monthly-subscriptions-renewals-for-three-months/
You can trigger the workflow 1 day before subscription renewal.

@magdakubis

This comment has been minimized.

Copy link

@magdakubis magdakubis commented May 18, 2020

Thank you, it worked great!

@magdakubis

This comment has been minimized.

Copy link

@magdakubis magdakubis commented Feb 7, 2021

Dan-
EDIT: code works on php. 7.1, does not work on 7.4 :(
I'd like to extend a quarterly subscription by 1 month (so when the customer purchases a quarterly subscription, their 1st recurring payment date will be 4 months out, instead of 3). However, I'd like to limit this to only new subscribers. In the Automate Woo workflow, I've added "parent" under subscription order types. Unfortunately it did not work when I tested it. Currently I have php 7.4. It worked on 7.1.
The product is a variable subscription product - I've only selected the quarterly variable for this. Is there anything I can do to limit it like that? Thank you.
Screen Shot 2021-02-07 at 10 10 58 AM

@SanderCi

This comment has been minimized.

Copy link

@SanderCi SanderCi commented May 3, 2021

Hi Dan, I don't get how you can moodify your snippet to move the 'next_payment' day to the first day of each month...
Thank's

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment