Selling digital access and licenses with Drupal Commerce: what the module covers
A team that wants to sell digital access, downloads or licenses on a Drupal store must decide whether to build the entitlement logic in-house or bring in a partner to scope and build it. The decision turns on what the store must grant on purchase and how those grants expire, renew or get revoked. Commerce License is the contributed module in the Drupal Commerce family for this job: according to its Drupal.org documentation, it grants roles, files or remote resources when a purchase is made, handles expiry and can be combined with recurring billing. Drupal and contributed modules hosted on Drupal.org are licensed under GPL-2.0-or-later, and there is no paid edition of Drupal itself, so the cost lies in the work around the module, not in the license.
Confirm the module choice before you estimate scope. Check the module's project page on Drupal.org and the Drupal Commerce version your store runs, including its maintenance status and open issue queue, because these decide whether the module is a sound base for a store that must run for years. Drupal 10 reaches end of life on December 9, 2026, according to the Drupal core release schedule, so a store started now should target the Drupal version it will still run on after that date. Also confirm which grant types the module supports out of the box, since role grants, file delivery and remote resource access are separate pieces of work.
Use the answers to decide the split between your team and a partner. Ask how many product types grant access, which grants expire and who renews them, which external systems must learn when access starts or stops, and how a refund or chargeback reverses a grant. Your team needs Drupal Commerce and custom module skills to own the glue code, while a partner's written scope should name each grant type, its expiry rule, its revocation path and the tests that run before launch. Label any cost comparison as an estimate from your own quotes until the scope is fixed.
What Commerce License does on a purchase
Commerce License connects a completed order to a license record that controls what the customer can reach afterward. The cards below describe the behaviors to confirm in the module documentation for your installed version before you design around them. Each one affects how you map products, scope access and plan renewals.
Role grant on order completion
When an order completes, the module can create a license for the customer and apply the access that the purchased product's license type defines. For a role-based license, that means adding a Drupal role to the customer's account, which then controls which content and features are visible. Check which license types ship with your installed version, whether the role is removed on expiry, and how roles from several licenses combine. Test each case with a sandbox order.
Product variation linked to a license
The license is configured on product variations, so each plan, term or tier can grant different access from the same catalog product. Plan the catalog around this split before building it, because changing the link later can affect customers who already hold licenses. Confirm how the variation-to-license reference is set, whether one variation can grant more than one license, and what happens to active licenses when a variation is unpublished.
File and remote resource grants
Access to files or remote resources usually depends on a role or another access check that your site enforces, so the license module is only one part of the design. Confirm whether your installed version or a companion contributed module provides a file or remote grant, how download URLs are protected, and whether links can be shared outside the account. Decide early how a remote service will learn that a license is active and when it should revoke access.
Expiry and renewal behavior
Licenses can carry an expiration, and the module decides what happens at that point: the grant can be removed, the license marked expired, or a renewal order used to extend it. Confirm which of these your version supports, whether renewal depends on a new order or on a recurring billing module, and whether a grace period can be configured. Expired access that remains visible to customers is a common support complaint, so test the full cycle with a short test term.
License record per customer
Each granted license is stored as a license record tied to the customer and the order that created it, giving support teams one place to check entitlement. Ask which fields the record holds, how administrators and customers see it, whether staff can revoke or transfer it, and how records are exported for accounting or audit. Include these records in your retention and privacy plan, since they link a named person to a purchase.
How a license is granted, checked and ended
A license starts at checkout. A customer adds a product to a cart, the cart becomes an order, and the order is paid through a payment gateway. Only after payment should the order be treated as a grant of access. In a Drupal Commerce design, the order belongs to a customer account, which is a Drupal user, and the purchased product variation determines which license is created. Commerce License provides the link between that purchase and the entitlement, but your team should confirm exactly which order states trigger activation in the module version you choose, because the trigger and the payment state are configured separately.
- Customer account: Decide whether buyers must be logged in before checkout, or whether guest purchases create an account at order completion.
- Order state: Confirm which states count as paid, and what happens to a license when a payment is later refunded or disputed.
- Product mapping: Map each sellable product to the access it grants, such as a role, a file set or a remote resource.
- Multiple items: Define how one order containing several licensed products is split, merged or stacked.
- Failed payments: Confirm that no access is granted for pending, declined or abandoned orders.
Before build, ask the partner to show, in your environment, which order state creates the license and where that state is recorded.
Once a license exists, each request for protected content must decide whether the current user holds an active entitlement. This check is the point where a purchase becomes enforceable, so it deserves the same scrutiny as authentication. The license entity links a user to a product and a status, and the check reads that link on every relevant request. Caching is the common hidden risk: a page cached for anonymous visitors or for a role can outlive a revoked entitlement unless cache contexts and tags reflect the license state.
- Role grants: When a license adds a Drupal role, the role is a fast gate, but it must be removed when the license ends.
- File and remote access: Files and remote resources need checks at delivery time, not only when the page renders.
- Cache behavior: Verify that cached responses vary by user and are invalidated when a license changes.
- Admin bypass: Decide who can see protected content without a license, such as staff, support or testers.
- Shared accounts: Decide whether one license may cover several users, and how seats are counted.
Test the check with a revoked license and a cached page, because that combination is where access control most often fails in production.
Licenses end in one of several ways: a fixed term runs out, a subscription is cancelled or fails to renew, a refund is issued, or an administrator revokes access. Each path should produce the same result, a clear status change that the access check respects. Renewals need particular care when they are billed by a recurring module, because a missed payment should not silently keep access open. Commerce License can work alongside recurring billing, but the handoff between the billing record and the license status must be designed and tested, not assumed.
- Expiry rules: Define whether terms are fixed dates, rolling periods or tied to a subscription cycle.
- Grace periods: Decide whether access continues during a payment retry window, and for how long.
- Renewal events: Confirm which billing events extend, pause or end a license.
- Notifications: Plan emails to customers before expiry and after a failed renewal.
- Audit trail: Keep a record of each status change for support and for reconciliation with finance.
Ask for a written test plan that covers expiry, renewal, failed payment and refund, with the expected access result for each case.
Which license model fits each kind of digital product
This table compares the main ways Drupal Commerce with Commerce License can grant access after purchase: role grants, file access and remote resources, plus fixed-term versus open-ended access. Read each row against the product you sell, then check the rightmost column for what your site must configure and what you should confirm in the module documentation before scoping the build.
| Model | Best fit | What it requires from the site | Confirm before scoping |
|---|---|---|---|
| Role grant | Member areas, gated content, community or course-style access | A dedicated role, a license type that assigns it, and a clear rule for what the role unlocks | Which access checks your theme and views respect the granted role |
| File access | Ebooks, templates, software downloads, recorded media | Private file storage, a file field tied to the product, and access checks on file URLs | How downloads are served and whether direct file links can bypass the license check |
| Remote resource grant | SaaS seats, API keys, external course or portal accounts | A custom integration or plugin that calls the remote system on activation and expiry | Whether a maintained contributed or custom plugin exists for your provider and how failed calls are retried |
| Fixed-term access | Annual subscriptions, time-limited trials, event passes | An expiry period set per product and a scheduled process that revokes access when it ends | How expiry is processed (cron timing, queue handling) and what happens to renewals that arrive late |
| Open-ended access | Lifetime purchases, perpetual downloads | No expiry period, plus a plan for revoking access on refund or chargeback | How refunds and manual revocations are recorded and whether the license can be reactivated |
| License per purchase | One buyer, one set of rights for each order | One license entity created per completed order item | Whether one order with a quantity greater than one creates one license or several |
| License per seat | Team or company plans with multiple named users | A seat count on the product and a way for the buyer to assign and reassign seats | Whether seat assignment and reassignment are supported by the module version you select, or need custom work |
| Recurring access | Memberships that renew each billing period | Link between the license and the billing subscription so renewals extend the expiry date | Which recurring billing module version is stable (see the subscriptions topic) |
Implementation sequence for a licensed product catalog
This sequence turns a licensing idea into a Drupal Commerce catalog that grants and expires access correctly, bills recurring purchases where needed, and hands the running store to the team that will operate it. Each step closes with a written artifact that the next step depends on.
Confirm the product and access model
Business owners, product managers and the implementation lead agree on what each sellable item grants: a Drupal role, access to files, or access to a remote resource such as an API or licensed application. They also agree on who buys (individual accounts, organizations or seats), how long access lasts, and what happens at expiry. The output is a written access matrix that lists each product, what it grants, its duration model, its renewal rule and its revocation trigger. The step is done when product owners sign off the matrix and every grant has a named owner for its remote side, if one exists.
Set up product types and variations
The Drupal Commerce builder configures product types, product variations and the attributes that separate one license tier from another, such as term length or seat count. Fields that carry grant targets, such as the role or file reference, are added to the variation so the grant logic has data to act on. The output is a configured product set in a staging site, reviewed against the access matrix line by line. The step is done when each product in the matrix exists once, with no duplicate or orphaned variations.
Configure grant and expiry rules
The team configures the Commerce License behavior for each product: which role, file or remote resource is granted when an order completes, how the license is activated, and how expiry is calculated from the start date. Rules for renewal, cancellation, refunds and manual revocation are set at the same time, because each one changes when a grant is removed. Choices on whether licenses stay active during a grace period are documented here. The output is a rule table that matches the access matrix. The step is done when the rule table is signed off and each grant and revocation path has a documented trigger.
Connect payment and recurring billing
The payment gateway and, for subscription-style products, the recurring billing module are connected and tested in sandbox mode. The team confirms which events the gateway sends back to Drupal for successful payment, failed renewal and refund, and maps each event to the grant rule from the previous step. Gateway selection and PCI scope are settled before this step, not during it. The output is a test order set covering one-time purchase, renewal, failed renewal and refund. The step is done when each event moves the license to the state the rule table predicts.
Test grant and revocation paths in staging
Testers run each product through the full lifecycle on a staging site that mirrors production configuration: purchase, grant, renewal, expiry, cancellation and refund. Remote resources are exercised with test accounts, and access checks are made from both a logged-in and an anonymous session. Cron and queue runs are checked, because expiry depends on them. The output is a test record listing each scenario, the expected grant or expiry, the observed result and the defect ticket for any mismatch. The step is done when every scenario passes or has an accepted, documented exception.
Launch and hand over the runbook
The catalog moves to production through the release process the client already uses, with a rollback plan and a check that payment and cron jobs run after deployment. A short post-launch review confirms the first real grants and expiries match the test record. The implementation team then writes a runbook covering how to add a product, handle a failed renewal, revoke access by hand and investigate a reported access problem. The output is the runbook and a handover session with the operations team. The step is done when operators have run at least one revocation and one renewal failure drill themselves, and the runbook is stored where they can maintain it.
What drives the effort and cost of a licensing build
This table lists the factors that raise or lower the effort of a Drupal Commerce licensing build, with a way to keep each one under control. Read it before scoping, because most of the cost comes from how many product types, provisioned systems and edge cases the written scope includes.
| Driver | Why it changes effort | How to keep it down |
|---|---|---|
| Number of product types | Each license type can need its own product variation, roles, file access and expiry rules, multiplying configuration and tests. | Start with the smallest set of license types that sell today and add others in later phases. |
| Resource systems to provision | Every remote system (file store, SaaS tenant, API key service) needs its own connector, credentials, error handling and monitoring. | Limit the first release to one or two provisioning targets and confirm each vendor's API for granting and revoking access. |
| Expiry and renewal | Time-based access needs scheduled checks, grace periods and renewal reminders, and it interacts with recurring billing. | Decide whether renewals are handled by Commerce Recurring Framework or manually before designing expiry logic. |
| Refunds and revocations | Each refund or chargeback must remove granted roles or access, and partial refunds need a defined rule. | Write the revocation policy as a short table of outcomes and test each one, rather than coding exceptions as they arise. |
| Tax and invoicing | Tax on digital goods, invoice numbering and VAT or sales tax rules vary by market and add configuration and review. | Confirm the tax treatment of digital goods with your tax advisor and limit launch to the markets you already serve. |
| Migration of existing customers | Existing entitlements must be mapped to new roles, products and expiry dates, which requires reconciliation with the old system. | Export a fixed set of active entitlements, agree the mapping in writing and run a reconciliation report before cutover. |
| Edge-case testing | Concurrent purchases, failed provisioning, payment retries, and clock or time zone changes multiply test cases. | Agree a list of named edge cases in the scope and automate them, so acceptance is based on the list rather than on open-ended review. |
Combining licenses with recurring billing and renewals
A time-limited license and a subscription are two separate records that have to agree, and the first decision is which system owns the billing cycle. In most designs the Commerce Recurring Framework owns the schedule, the payment method and the renewal order, while Commerce License owns the grant: the role, file or remote resource and its expiry date. Each renewal order should extend the existing license rather than create a new one, so that users keep their content, group memberships and remote credentials without a reprovisioning gap. Confirm with your development partner exactly which entity holds the expiry timestamp and which event triggers the extension, because a mismatch here is the usual cause of users who paid but lost access, or who kept access after cancellation.
Failed payments need an explicit policy before launch. Decide how long a customer keeps access after a declined renewal, whether that grace period is enforced by the license expiry date or by a separate state on the subscription, and what the customer sees during it. Remote resources add a second layer: if access is granted through an external API, the grace period has to be mirrored there, and the revocation job must be idempotent so a retry does not remove access that should still exist. Test each path with the payment gateway's sandbox and with simulated expiry dates, including a renewal that succeeds after a retry, a renewal that fails permanently, and a cancellation made mid-cycle.
Before committing to a subscription design, check the stability and maintenance status of every contributed module in the chain on Drupal.org, including the recurring framework, the license module and the gateway connector. A module without a stable release or with stalled maintenance puts your billing logic on code you may have to fork later, which is a cost that rarely appears in the first quote. Ask for the release history, the open issue queue for billing and renewal defects, and the supported Drupal core version. Billing intervals, dunning messages and retry schedules are covered on the sibling subscriptions page, so use that page for those decisions and keep this design focused on how the license and the billing cycle stay in step.
How licensing connects to payments, identity and external systems
A license grant is only as good as the events that trigger it and the systems that check it. Each connection below is a point where a purchase, renewal, sign-in or resource request crosses from Drupal Commerce into another system, and each needs confirming against the module versions you install.
Payment gateways for purchase events
A gateway payment result is what should move an order to completed and grant the license. Decide whether the grant happens on the gateway's success notification, on a return to the site, or both, because a customer can close the browser before the return fires. Confirm which events your chosen gateway module sends, how failed and refunded payments reverse a grant, and whether duplicate notifications are handled without granting twice.
Subscriptions module for renewals
For time-limited access, renewals drive expiry dates. Confirm that the subscription or recurring module you use extends the same license entity on renewal rather than issuing a new one, and that a failed renewal payment leads to a defined grace period rather than an immediate removal. Check the module's stable release status against your installed Drupal Commerce version before you design around it.
Identity of the buyer
Roles and file access attach to a Drupal account, so the buyer's identity must be stable. If customers sign in through a corporate or federated identity provider, the OpenID Connect or SAML Authentication module can create accounts on first sign-in, which means purchase and sign-in must map to the same user. Confirm how the account is matched, how the email address changes, and what happens when an employee leaves the buyer organization.
External resource systems
When the licensed item is a file in object storage or a record in a partner API, the grant must reach that system. Decide whether Drupal issues signed, expiring links or calls the API to provision access, and who revokes it when the license ends. Confirm the API's rate limits, its failure behavior during provisioning, and whether it offers an idempotent grant call so retries do not create duplicate accounts.
Tax and invoicing
Digital goods can carry tax rules that differ from physical goods and by buyer location, so tax calculation sits in the order flow before the grant. Confirm with your tax adviser which rules apply to your sales and which tax module or service you will use. Invoices should reference the order and license terms, and records of granted access should be kept so support teams can answer billing and access questions together.
Questions teams ask before selling licenses on Drupal Commerce
What does a Drupal Commerce licensing build cost, and what drives the price?
Cost depends on the written scope, not on a fixed package. The main drivers are the number of product types, how many access outcomes exist (roles, files, remote resources), the number of payment and renewal paths, and how many external systems must be told about a grant. Drupal and the contributed modules are free under GPL-2.0-or-later, so the spend is on people: planning, configuration, custom code where contributed modules stop, testing and handover. Ask for a quote that separates one-time build work from recurring work such as module updates, monitoring and support. DeployOpen does not publish a price list; a quote follows from the written scope.
How long does it take to build license sales on Drupal Commerce?
The timeline follows the number of decisions still open when the work starts. Teams that have agreed their product rules, access matrix and renewal behavior move faster than teams that are still deciding what a license grants. Other drivers are the number of gateways involved, whether refunds must revoke access automatically, whether recurring billing is part of the first release, and how many remote systems must be called during a grant. Ask for a timeline in the written scope with milestones for each access type, and confirm which dependencies sit with your team.
What must our team provide before a license build starts?
Four inputs prevent most rework: written product rules (what each product grants, for how long, and under which conditions), an access matrix mapping each product to roles, files or remote resources, test accounts for each customer type and role, and a named owner who can approve decisions within the project. Your team should also list the systems that must be updated on purchase, such as a license server or a file store, and provide sandbox credentials for them. Missing owners are the most common cause of delayed sign-off.
Can our internal team build license sales on Drupal Commerce alone?
An internal team can build it if it has Drupal Commerce experience, PHP and Drupal module development skills, and capacity to test payment and access flows end to end. The harder part is the edge cases: partial refunds, failed renewals, chargebacks, plan changes mid-term and access that depends on an external system. Those cases are where a second review of design and code pays off. Decide early whether you will build in-house, use a partner for design and review, or hand the full build to a partner under a fixed-scope agreement. The written scope should name who is responsible for each part.
How are access revocation and refunds handled?
Revocation is a product decision before it is a technical one. Define what happens to access when an order is refunded, disputed, cancelled or left unpaid, and whether access ends immediately, at the end of a paid period or after a grace window. Engineers then map each rule to a Commerce event, a license status change and, where needed, a call to the external resource. Test refunds at the gateway level as well as in the store, because a refund issued in the gateway dashboard may not reach the store unless a webhook or reconciliation job handles it. Confirm the exact behavior of each gateway with its vendor.
What changes after a Drupal Commerce licensing site goes live?
Expect ongoing work in four areas: module and core updates, gateway and API changes, new products or license terms, and monitoring of failed grants and renewals. Drupal core releases follow a published schedule, with bugfix releases on the first Wednesday of each month and security releases on the third Wednesday, so a plan for regular update windows keeps the site supported. Contributed modules that handle licensing or recurring billing need their own review before each update. Operations should also track grant failures so that a customer never pays for access that was not delivered.
Who is responsible for compliance and security of paid access?
Your organization owns its licensing terms, tax treatment, data retention and customer contracts. The build should keep card data out of your application by using the gateway's hosted fields or redirect flows, and the scope of any payment-related controls should be confirmed with your acquirer and assessor. DeployOpen prepares systems, controls and evidence for compliance assessments but does not issue audit reports, attestations or certifications; independent auditors and certification bodies do that. Ask for the access logs, audit trail and test evidence to be included in the handover.
How DeployOpen scopes and delivers a licensing build
Every licensing build starts with a written scope agreed before any configuration begins. For a Drupal Commerce store that grants roles, files or remote resources on purchase, the scope should name each product type, the grant action it triggers, the expiry rule that applies, and the systems that must receive a notification. DeployOpen's engagements are fixed-scope, so the deliverables, the acceptance criteria and the timeline are written down with the client before work starts. Changes to the scope, such as adding a second gateway or a new remote resource type, are handled as written change requests rather than absorbed silently into the original price.
The part of the build most often under-specified is the revocation path. Testing covers the grant path (a completed order assigns the role or access record once and only once), the expiry path (the role or access is removed when the period ends, including after a failed renewal), and the refund and cancellation paths (access is withdrawn when an order is refunded and not re-granted by a retried webhook). Each path is tested against order states that a real store produces, including partial refunds, duplicate payment notifications and orders placed by anonymous buyers who later register. Ask any partner to show the test cases and the results for these paths, not only a demonstration of a successful purchase.
Handover is where licensing builds usually fail after launch, so the documentation should cover the product-to-grant mapping, the cron or queue jobs that process expiry, the logs that show each grant and revocation, and the steps for a support agent to check a customer's entitlement. DeployOpen can continue after launch under an optional retainer for ongoing support, module updates and Drupal upgrades. Retainer scope, response expectations and what happens when a contributed module changes are agreed in writing. Confirm with any provider whether the retainer covers the Drupal core and contributed module updates that affect the grant logic, because those are the changes most likely to break entitlements.

