I have similar problem as described on Commerce License Billing: How do I charge or refund a prorated amount when the user's plan changes and the billing cycle is prepaid? by @wizonesolutions, but with different goal.

On a Drupal 7 website with the Commerce License Billing module used for subscriptions, the changing subscriptions plan by saving the new product_id on the license entity ($license->product_id) does in fact update the license and the due amount on the next recurring payment order, however, it does not update the granted and expires fields of the license.

So I tried to get those fields' values from the license, make my calculations and save them together with the whole license entity like so:

    if ($bct == '1') { // hourly
      $target_date = strtotime('+1 hour', REQUEST_TIME);
      $license[arg(1)]->expires = $target_date;
    } elseif ($bct == '2') { // daily
      $target_date = strtotime('+1 day', REQUEST_TIME);
      $license[arg(1)]->expires = $target_date;
    } elseif ($bct == '3') { // monthly
      $target_date = strtotime('+1 month', REQUEST_TIME);
      $license[arg(1)]->expires = $target_date;
    } elseif ($bct == '4') { // quarterly
      $target_date = strtotime('+3 months', REQUEST_TIME);
      $license[arg(1)]->expires = $target_date;
    } elseif ($bct == '5') { // biannually
      $target_date = strtotime('+6 months', REQUEST_TIME);
      $license[arg(1)]->expires = $target_date;
    } else { // biannually
      $target_date = strtotime('+1 year', REQUEST_TIME);
      $license[arg(1)]->expires = $target_date;
    $license[arg(1)]->granted = strtotime("now");
    $license[arg(1)]->product_id = $form_state['storage']['selected_plan'];
    entity_save('commerce_license', $license[arg(1)]);
    drupal_set_message('License has been updated.');

And the admin/commerce/licenses page after saving the license entity shows that all the relevant fields - new product_id, granted and expired fields have been in fact updated.

But the problem is that when expire time comes, the granted field reverts back to initial value and the expired field's value is calculated based on the initial granted field.

In other words, guess I have two billing cycles - hourly and daily - and if an initial order is placed with hourly billing cycle, then license with the following fields is created:

Cycle: Hourly   
Granted: 15 January 2018 - 17:50    
Expires: 15 January 2018 - 18:50

If I update the license with the new product id, granted and expires field then the admin/commerce/licenses shows:

Cycle: Daily    
Granted: 15 January 2018 - 17:52    
Expires: 16 January 2018 - 17:52

And when 16 January 2018 - 17:52 comes and all the relevant cron tasks are processed then the same page shows:

Cycle: Daily    
Granted: 15 January 2018 - 17:52    
Expires: 15 January 2018 - 20:48

Meanwhile bunch of extra orders are charged and the new recurring order with Recurring: Open status are created and then only the license admin page showing the granted and expires fields (with values behind from 16 January 2018 - 17:52) constantly changing with every cron execution:

Cycle: Daily    
Granted: Active 15 January 2018 - 17:52 
Expires: 16 January 2018 - 01:48

So my question is:

If changing the values for the granted and expires fields in license entity does not take effect, where else I should be looking for changing those values?


After monitoring how database tables change with recurring products, I've noticed that saving license with the new data was not sufficient and that the cl_billing_cycle should also be updated with the new granted and expire dates.

I am doing that with a direct database query for now. Let me know if there is a better way to update the cl_billing_cycle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.