1

I have a Woocommerce site running Woocommerce Subscriptions plugin.

The site only has one simple subscription, limited to one per user. I want to allow the user to set their own start time and subscription frequency, based on selections made in a dropdown box added during the checkout process.

I have added the checkout fields correctly, and they are simple select boxes:

    <select name="frequency" id="choose_frequency">
       <option value="week">Weekly</option>
       <option value="2week">Fortnightly</option>
       <option value="monthly">Monthly</option>
    </select>

    <select name="start-date" id="sub_start_date">
        <option value="22 Apr 2021">Thursday, 22 April 2021</option>
        <option value="29 Apr 2021">Thursday, 29 April 2021</option>
        <option value="6 May 2021">Thursday, 6 May 2021</option>
    </select>

I need to get the value, convert it to the correct meta, and then update the subscription before it has been created.

I've tried to update the meta using woocommerce_checkout_update_order_meta:

//Update the order meta with custom fields values
add_action('woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta');
function customise_checkout_field_update_order_meta($order_id){
    $subscriptions_ids = wcs_get_subscriptions_for_order( $order_id );
    foreach( $subscriptions_ids as $subscription_id => $subscription_obj ){
        update_post_meta($subscription_id, '_schedule_start',date('Y-m-d h:i:s',$_POST['sub_start_date']));
    }
}

and also tried wcs_create_subscription:

// set start subscription date on checkout page
add_action('wcs_create_subscription', 'cc_wcs_create_subscription');
function cc_wcs_create_subscription($subscription){
    $order_id = $subscription->order->id;
    $subscription_id = $subscription->get_id();
    if($subscription_id  && $_POST['sub_start_date']){
                update_post_meta($subscription_id, '_schedule_start',date('Y-m-d h:i:s',$_POST['sub_start_date']));
    }
}

... I've even tried updating the frequency with AJAX:

jQuery(document).on('change','select#choose_frequency',function(){
    var cur_val = jQuery(this).val();
    jQuery.ajax({
            type:'post',
            url:woocommerce_params.ajax_url,
            data:{'action':'cc_update_product_subscription','productid':1086,'cur_val':cur_val},
            success:function(result){
                jQuery(document.body).trigger("update_checkout");
            }
    });
});
// update subscription frequency on checkout page
add_action('wp_ajax_cc_update_product_subscription','cc_update_product_subscription');
add_action('wp_ajax_nopriv_cc_update_product_subscription','cc_update_product_subscription');
function cc_update_product_subscription(){
    if($_POST['cur_val'] == 'week'){
        update_post_meta($_POST['productid'],'_billing_interval','1');
        update_post_meta($_POST['productid'],'_billing_period','week');        
    }
    if($_POST['cur_val'] == '2week'){
        update_post_meta($_POST['productid'],'_billing_interval','2');
        update_post_meta($_POST['productid'],'_billing_period','week');
    }
    if($_POST['cur_val'] == 'monthly'){
        update_post_meta($_POST['productid'],'_billing_interval','1');
        update_post_meta($_POST['productid'],'_billing_period','month');
    }
    
    die();
}

Nothing seems to be working. The checkout is still processing through to completion, but the subscription details are not updated to reflect those selected by the user. What am I doing wrong?

EDIT:

Following Loic's suggestion,I played around the code a little further. I realised that the fields I added to the checkout were not done correctly, so let's take that scenario out for a bit, and try to hard-code a date as a test...

So, I tried this code:

add_action( 'woocommerce_checkout_create_subscription', 'checkout_custom_fields_update_subscription_meta', 10, 3 );
function checkout_custom_fields_update_subscription_meta( $subscription, $order, $recurring_cart ) {
   
        $date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end'); // Subscription date types
        $dates      = array(); // Initializing

        // Loop through subscription date types
        foreach( $date_types as $date_type ) {
            $date = $subscription->get_date($date_type); // Get current date from type
            
            // For "start" date type (or "schedule start")
            if ( 'start' === $date_type ) {
                $dates[$date_type] = '2021-05-20 00:00:00';
            }

            // For other date types (keep original data)
            else {
                $dates[$date_type] = $date;
            }
        }
        $subscription->update_dates($dates); // Update dates
        $subscription->save(); // Save to database and refresh caches
    
}

And I got the error message: "The next_payment date must occur after the start date."

So I tried this:

add_action( 'woocommerce_checkout_create_subscription', 'checkout_custom_fields_update_subscription_meta', 10, 3 );
function checkout_custom_fields_update_subscription_meta( $subscription, $order, $recurring_cart ) {
   
        $date_types = array('start', 'trial_end', 'next_payment', 'last_payment', 'end'); // Subscription date types
        $dates      = array(); // Initializing

        // Loop through subscription date types
        foreach( $date_types as $date_type ) {
            $date = $subscription->get_date($date_type); // Get current date from type
            
            // For "start" date type (or "schedule start")
            if ( 'start' === $date_type ) {
                $dates[$date_type] = '2021-05-20 00:00:00';
            }
            // For "next_payment" date type
            elseif ( 'next_payment' === $date_type ) {
                $dates[$date_type] = '2021-05-29 00:00:00';
            }
            // For other date types (keep original data)
            else {
                $dates[$date_type] = $date;
            }
        }
        $subscription->update_dates($dates); // Update dates
        $subscription->save(); // Save to database and refresh caches
    
}

This processed the checkout, however neither start date or next payment date was saved, it defaulted back to start date being today (when ordered) and payment date being 2 weeks after that (default setting).

Any ideas?

user2115227
  • 147
  • 2
  • 9
  • 24

0 Answers0