Commerce License
Provides a framework for selling access to site resources such as roles through Commerce products.
commerce_license
Install
composer require 'drupal/commerce_license:^3.0'
composer require 'drupal/commerce_license:8.x-2.0'
Overview
Commerce License allows the creation of products that sell access to some aspect of the site. This could be a role, publication of a node, or any other type of access controlled by custom license type plugins.
When a product is purchased, a License entity is created for the user. The nature of what a License entity grants is handled by License type plugins, with each License entity associated with one License type plugin. Product variations that sell a License have a configured License type plugin field value that acts as a template to create the License when a user purchases that product variation.
The module provides comprehensive workflow management for licenses including states like new, pending, active, suspended, expired, revoked, and canceled. It integrates with Commerce Checkout to ensure only authenticated users can purchase licenses, and optionally integrates with Commerce Recurring for subscription-based license renewals.
Features
- License entity type with configurable workflow states (new, pending, active, renewal_in_progress, suspended, expired, revoked, canceled, failed)
- Role license type plugin that grants/revokes user roles when licenses are activated/deactivated
- Flexible license expiration system with Unlimited, Rolling Interval, and Fixed Reference Date Interval period plugins
- Entity traits for product variations ('Provides a license') and order items ('Provides an order item type for use with licenses')
- Automatic license activation on order payment or order placement (configurable per product variation type)
- License renewal support allowing customers to repurchase before expiration within a configurable window
- Cron-based automatic license expiration with Advanced Queue integration for reliable processing
- Email notifications sent to users when their licenses expire
- License dashboard providing status report of configuration requirements and validation
- Views-based admin interface for managing all licenses with filtering and bulk operations
- Commerce Log integration for tracking license state changes
- Optional Commerce Recurring integration for subscription-based licenses that automatically renew
- Existing rights checking to prevent users from purchasing licenses they already have
- Protection of granted roles on user edit forms to prevent manual removal of licensed roles
Use Cases
Membership Site with Role-Based Access
Create a membership site where users purchase access to premium content. Configure a 'Premium Member' role with appropriate permissions, create a product variation with the license trait that grants this role, set an expiration period (e.g., 1 year rolling interval), and when users purchase the product, they automatically receive the role for the configured period. The role is automatically removed when the license expires.
Software License Sales
Sell time-limited software licenses where the license grants a role that provides access to download or support areas. Use the rolling interval expiration to provide licenses valid for a set period from purchase. Customers receive email notifications when licenses expire and can repurchase to renew.
Subscription-Based Access with Commerce Recurring
Create recurring subscription products where licenses automatically renew with payment. Configure the product variation with both the license trait and subscription trait, set license expiration to 'Unlimited', and choose a billing schedule. The subscription handles payment and renewal, while the license handles access. When a subscription is canceled, the license is automatically canceled.
Annual Membership with Fixed Renewal Date
Implement memberships that all expire on the same date (e.g., December 31st) regardless of when purchased. Use the 'Interval based on reference date' expiration type with a reference date of January 1st and a 1-year interval. All licenses expire at year end, creating synchronized renewal periods.
Early Renewal Window
Allow customers to renew their licenses before expiration. Configure the product variation type with 'Allow renewal before expiration' enabled and set the renewal window (e.g., 30 days). Customers with active licenses within the renewal window can repurchase to extend their license; their expiration date extends from the current expiration rather than from the renewal date.
Tips
- Use the License Dashboard at /admin/commerce/config/licenses/dashboard to validate your entire license configuration chain from checkout flow to products.
- For testing, create a simple checkout flow with minimal steps but ensure guest checkout is disabled.
- When using Commerce Recurring for subscriptions, always set the license expiration to 'Unlimited' as the subscription controls the lifecycle.
- The Role license type protects granted roles on user edit forms, preventing accidental removal of licensed roles by administrators.
- License state transitions are logged to Commerce Log when enabled, providing an audit trail of license changes.
- Custom license types can be created by implementing LicenseTypeInterface - useful for granting access to custom functionality beyond roles.
- The expiration email template (commerce-license-expire.html.twig) can be overridden in your theme to customize notification emails.
Technical Details
Admin Pages 7
/admin/commerce/licenses
View and manage all licenses in the system. Provides a filterable table listing all licenses with columns for ID, Label, License Type, Owner, State, Granted date, Expires date, and Updated date. Supports bulk operations including delete.
/admin/commerce/config/licenses
License configuration section providing access to License Dashboard and License Types management.
/admin/commerce/config/licenses/dashboard
Displays a comprehensive status report validating the complete license configuration chain. Shows the status of checkout flows, order types, order item types, product variation types, product types, and products to ensure all components are properly configured for selling licenses.
/admin/commerce/config/licenses/license-types
Manage fields, form and display settings for license entities by license type bundle.
/admin/commerce/licenses/{commerce_license}
View a single license entity showing all fields including type, owner, state, licensed product variation, expiration type, created/granted/renewed/expires timestamps, and activity log.
/admin/commerce/licenses/{commerce_license}/edit
Edit form for license entities. Displays owner information, license state with available transitions, timestamps (expires, renewed, granted, changed, created), and license-type-specific fields.
/admin/commerce/licenses/add/{type}
Administrative form for manually creating a new license. This bypasses the normal product purchase flow and should only be used by administrators who understand the implications.
Permissions 9
Hooks 2
hook_commerce_license_type_info_alter
Modify the list of available License Type plugins. Can be used to remove plugins or change plugin labels.
hook_commerce_license_period_info_alter
Modify the list of available License Period plugins. Can be used to remove plugins or change plugin labels.
Troubleshooting 6
Verify that the checkout flow does not allow guest checkout (Login pane must have 'Guest checkout: Not allowed'). Check that the order item type has the 'Provides an order item type for use with licenses' trait. Use the License Dashboard at /admin/commerce/config/licenses/dashboard to validate your configuration.
Ensure the product variation's 'Activate license when order is placed' setting matches your expected behavior. If using asynchronous payment gateways, licenses activate on payment confirmation via the ORDER_PAID event.
The existing rights checker should prevent this. Verify the license type plugin implements ExistingRightsFromConfigurationCheckingInterface and the checkUserHasExistingRights() method returns appropriate results.
Ensure cron is running regularly. Check that the Advanced Queue module is properly configured and the 'commerce_license' queue is being processed. The commerce_license.cron service queues expiration jobs during cron, and Advanced Queue processes them.
Verify the license has the correct role configured in its license_role field. Check that the user entity is being saved properly by the Role license type plugin's grantLicense() and revokeLicense() methods.
Ensure the license expiration is set to 'Unlimited' when using subscriptions. The subscription controls the lifecycle; the license should not expire independently. Verify the LicenseSubscriptionType plugin is handling subscription events.
Security Notes 5
- The 'administer commerce_license' permission is marked as 'restrict access' and should only be granted to trusted administrators.
- The 'access commerce_license overview' permission is also restricted as it provides access to view all licenses in the system.
- License type plugins can escalate user privileges (e.g., granting administrative roles). The module validates that only allowed license types can be selected on product variations.
- The admin forms for creating/editing licenses directly should only be used by developers who understand the implications - changing values can break license state consistency.
- Guest checkout must be disabled for license-selling checkout flows to ensure licenses are always associated with authenticated users.