Last updated February 15, 2015. Created on July 11, 2013.
Edited by sja1, larowlan, balintk, bojanz. Log in to edit this page.

This is a documentation page for the Commerce License module.

Getting started

  1. Enable the module and all of its dependencies (ctools, entity, entityreference, entity_bundle_plugin).
  2. Enable advancedqueue if you want to use remote (synchronizabe) licenses.
  3. Enable a module that provides one or more license types. A commerce_license_example module is included that you can use for demonstration purposes.
  4. Go to admin/commerce/config/license and select the product and line item types that should be licensable. This will create the required fields.
    Warning: You NEED to select at least one product type AND one line item type! If no line item types are selected, no licenses will be created during checkout.
  5. Add one or more products and select a license type and duration for each one

Commerce License Role

The commerce_license_role submodule allows roles to be licensed.
The customer receives the role referenced by the purchased license product. Changing $license->product_id (from "Basic Membership" to "Premium Membership", for instance) changes the owner's role.

Usage:

  1. Go to admin/commerce/config/license/role and select the product types that will be used to sell the roles. This will create a commerce_license_role options field on each of the selected product types.
  2. Create a product, select the Role license type, then select the role that should be licensed.

Basic concepts

License

The license is an entity that gets created on checkout, and represents the purchased right to access a resource. A license can be configurable, meaning that it has fields attached which are filled in by the customer (on the add to cart form or during checkout through a checkout pane).
The license is referenced from a line item through a commerce_license entityreference field.
Each line item can have its own licence.
When a line item gets created, the matching license will be created as well. The type of the license to create is determined by looking at the commerce_license_type field on the product.
If the line item gets deleted, its license gets deleted as well.

A license can have one of several statuses, all represented by constants mapping to a numeric value:

  • COMMERCE_LICENSE_CREATED: The license was just created, and the order is still in checkout.
  • COMMERCE_LICENSE_PENDING: (Remote licenses only) The order has been paid, the license is awaiting synchronization.
  • COMMERCE_LICENSE_ACTIVE: The license is active and can be used.
  • COMMERCE_LICENSE_EXPIRED: The license has expired.
  • COMMERCE_LICENSE_REVOKED: The license has been revoked (due to an order cancellation, for instance).

The license has two timestamps, set when the license status is first changed to COMMERCE_LICENSE_ACTIVE:

  • granted: The unix timestamp indicating when the license was granted (set to the current time at that moment).
  • expires: The unix timestamp indicating when the license expires.
    The commerce_license_duration field is looked up on the product, and if it's 0 (meaning "Unlimited"), the expires timestamp is set to 0, indicating that the license never expires.
    If commerce_license_duration is set to a positive value (for example 3600, indicating it should last for an hour), that value is added to the current time and stored in the expires column.

License type

Each license type (entity bundle) is a ctools plugin, represented by a class that inherits either CommerceLicenseBase (local licenses) or CommerceLicenseRemoteBase (remote licenses).
Each license type can define the fields it has by implementing the fields() method.
If missing, the fields and their instances will be created on the next cache clear.

See this blog post for more information.

Configurable license types

A license type is configurable if it returns TRUE from the isConfigurable() method.
Configurable license types define fields that should be filled-in by the customer before or during checkout. There are two ways to allow that:

1) Inline Entity Form
Each line item has a commerce_license reference field. Inline Entity Form allows the license fields
to be edited directly on the line item form ("add to cart" or "order add / edit" admin form).

If Inline Entity Form was already present when Commerce License was installed, the commerce_license reference field was already configured to use it. Otherwise, you will need to go to admin/commerce/config/line-items and click the "manage fields" link for your line item type. First you must change the widget for the "License" field to "Inline Entity Form - Commerce License".

After that, you need to click on the "edit" link for the "License" field, then look for the "Add to cart form settings" section, and click the "Include this field on Add to Cart forms for line items of this type" checkbox. Save your changes and the configurable fields should now appear on the add to cart form on your product display page.

2) "License Information" checkout pane
If enabled, this checkout pane will output a form for each configurable license present in the cart.

Both of these (Inline Entity Form and the checkout pane) call the same methods on the license type class to generate / validate / submit the license form.

Remote licenses types

A remote license type extends the CommerceLicenseRemoteBase base class, which implements the CommerceLicenseSynchronizableInterface.

Every remote license has a "sync_status" field that tracks the synchronization status (needs sync, synced, sync failed).

Once an order has been paid in full, all remote licenses are queued for synchronization and then processed by advancedqueue one by one. The queue worker calls the synchronize() method of each license type class, allowing it to contact the remote service and store the result.

The synchronization queue view at admin/commerce/licenses/sync-queue allows synchronizations to be tracked.

Checkout complete pane

The "License completion message" checkout pane outputs a pane for each found license, allowing
licenses to present the access details to the customer.
If a license hasn't been synchronized yet, the checkout pane refreshes itself until the synchronization happens. If the synchronization doesn't happen after 30 refreshes, it is marked as failed and the refresh is stopped.

License synchronization

For remote licenses, the synchronize method is only called when the synchronization queue is processed.
This means you need to configure your server to have a frequent cron-task that uses drush to process the queue.
You can configure the frequency at which the checkout completion pane refreshes as well as the total time that can elapse before the synchronization is marked as failed (and the refresh stops).
So this means you must configure the cron-task on your server to run more frequently than the time you configure for the total-time. That way the checkout-complete pane will continue to refresh and at some point during the total-time, the cron task will run and process the synchronization queue - at which point the pane will update with the user's license details.
The command your cron task needs to run is as follows:
drush -r /path/to/your/drupal/install -l http://yoursiteurl.com advancedqueue-process-queue commerce_license_synchronization

License expiration

When cron runs, it takes the ids of all expired licenses (expires < REQUEST_TIME), and queues them.
The queue (advancedqueue if present, cron queue otherwise) then processes the licenses one by one, changing their status to COMMERCE_LICENSE_EXPIRED, allowing rules and hooks to respond to the save.
If the license is synchronizable, it is also queued for synchronization, allowing the remote service to be notified if needed.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

jgardezi’s picture

Hi,

I am using this module and try to figure out licenses for a product and a line item product. The license for a product is unlimited period and a license for a line item has an expiry of a month, also they have different prices.

To achieve this I have done the setup in the following way.
Using commerce module I have created a product type "Product Subscription" and the module comes with product type "Product". Now I have created a "Product" and 3 "Product Subscription". After that I have installed Commerce Custom Product module which allow me add "Product Subscription" as a custom line item. In the commerce license settings page (admin/commerce/config/license) I have checked "Product" as a Product type and "Product Subscription" as Line item types. After the checking the checkboxes the "commerce_license" field appears in "Product Subscription" line item.

In the "Product" display, "Product Subscription" list shows up. Add to cart successfully able to add "Product" and "Product Subscription". Now the issue is; After adding to cart, the license for "Product" is generated but not for "Product Subscription". Even after the checkout process their is only one license is generated. Prices get updated correctly. If their are rule missing please let so that the license for "Product Subscription" will also be generated. Otherwise please guide to the alternative approach.

Kind regards,
Javed Gardezi