SfSkills Domains Docs GitHub

Home / devops / isv-license-management-and-trialforce

isv-license-management-and-trialforce

Use when an ISV partner is wiring license enforcement, trial provisioning, or feature-flag distribution into a managed package — covers License Management App (LMA) install and registration, Lead/License object. NOT for general managed-package version creation, ancestor pinning, or PostInstall handler design — use devops/managed-package-development.

Open the skill folder on GitHub


ISV License Management and Trialforce

Activate this skill when an ISV partner is designing or troubleshooting the license-and-trial surface of a Salesforce managed package — the cross-org channels by which the partner's License Management Org (LMO) controls what a subscriber org can do, how trial provisioning is delivered, and how runtime feature flags are flipped after the package has been installed. This is the partner ↔ subscriber plane, not the in-package code plane.


Before Starting

Gather this context before proposing any change:


Core Concepts

Concept 1 — The License Management App (LMA) is the ISV's seat-of-truth

The LMA is a free Salesforce-published managed package that the ISV installs in their License Management Org. It creates two key custom objects:

Salesforce updates the License record automatically when a subscriber installs, upgrades, or uninstalls. The ISV adjusts seat counts and expiration dates as part of their billing process. Subscriber orgs query their license state through the platform — if a license is expired or suspended, the package's components stop being usable in that org. The LMA is the only supported way to enforce subscription billing on a 1GP managed package, and is required for AppExchange Checkout.

The LMA is registered with a package via AppExchange Publishing → Package form using the sfLma__License_Management_Org__c setting on the package record. Once registered, every subsequent install of any version of that package writes to the same License Management Org.

Concept 2 — Trialforce splits provisioning into TMO + TSO + Template

Trialforce is the trial-org provisioning service. It uses three distinct org roles:

For non-CRM solutions, the Environment Hub can create TSOs without a TMO. CRM solutions and any partner that wants custom branding still require a TMO.

Concept 3 — Feature Parameters are the LMA's runtime switchboard

Feature Parameters (FP) are package-scoped key/value records that flow between the LMO and the subscriber org without requiring a package upgrade. They come in three types — FeatureParameterBoolean, FeatureParameterDate, FeatureParameterInteger — and in two directions:

Feature Parameters are not real-time. Propagation runs on a Salesforce-managed schedule (typically minutes, not seconds) in both directions. Critical decisions — whether a transaction is allowed — must not depend on a Feature Parameter that was flipped seconds ago. They are configuration, not authorization.

Concept 4 — AppExchange Checkout sits on top of the LMA, not next to it

AppExchange Checkout adds e-commerce (credit-card billing, subscription renewals, self-service signup) to AppExchange listings. It does not replace the LMA — every Checkout purchase still creates a License record in the partner's LMA. Checkout adds a Subscription record (in the partner's billing system) and pushes lifecycle events (renewal, cancellation, upgrade) into the LMA. If the LMA is misconfigured, Checkout signups appear to succeed but the partner can't actually enforce or track the subscription.


Common Patterns

Pattern 1 — Register-then-track LMA wiring

When to use: The package is approaching first AppExchange listing or first paid release.

How it works:

  1. Install the LMA managed package in a fresh License Management Org (recommended: the Partner Business Org or a dedicated production org — never a sandbox).
  2. In the partner-side packaging org (1GP) or DX project (2GP), upload the package version and capture the 04t... package version ID.
  3. In the AppExchange Publishing Console, open the listing's package record and set the License Management Org to the LMO from step 1. The LMO must be in a Salesforce edition that supports the LMA (Enterprise+).
  4. Verify by installing the package into a throwaway sandbox and confirming a sfLma__License__c record is auto-created in the LMO within 2–3 minutes.
  5. In the LMA, set the Default License Type (Trial / Active / Free) and Default Seats for the package. These apply to every new install until manually overridden.
  6. Build a scheduled job in the LMO that watches sfLma__License__c for Status='Suspended' and notifies the customer-success team — the LMA does not include outbound notifications.

Why not skip the LMA: Without LMA registration, the partner has no view of installs, no way to enforce expiration, and no path to AppExchange Checkout. Adding the LMA later requires a Salesforce-side reconciliation case for existing installs.

Pattern 2 — Trialforce template lifecycle for a CRM solution

When to use: The package is a CRM-overlay solution and the partner wants AppExchange-listing-driven trials.

How it works:

  1. Request a TMO via partner-portal case (Partner Programs & Benefits → ISV Technology Request).
  2. From the TMO, create a TSO (or use Environment Hub for non-CRM).
  3. In the TSO, install the managed package, configure users, load representative sample data, set up custom branding (if approved).
  4. From the TMO, create a Trialforce Template — the wizard takes a snapshot of the TSO. Snapshot creation can take hours.
  5. Submit the template for Salesforce approval. Templates aren't usable until approved.
  6. In the AppExchange Partner Console, connect the TMO and link the approved template to the listing's trial method.
  7. After every package update that ships a UI or schema change, rebuild the TSO state and re-snapshot — old templates issue trials with the old code.

Why not skip the template re-approval: Trial signups from a stale template land prospects in an org that doesn't match the current sales demo and silently locks the partner into supporting an old code path.

Pattern 3 — LmoToSubscriber Feature Parameter for one-customer feature flip

When to use: A specific subscriber needs a feature enabled for them only — without shipping a new package version.

How it works:

  1. In the package source, define a FeatureParameterBoolean (e.g. Enable_Beta_Reports) with a defaultValue of false and direction LmoToSubscriber.
  2. In subscriber-side Apex that gates the feature, call System.FeatureManagement.checkPackageBooleanValue('namespace', 'Enable_Beta_Reports') and branch on the result.
  3. Release the package version. Existing subscribers receive false (the default).
  4. To flip for one customer: in the LMO, open their sfLma__License__c record, find the related Feature Parameter record (created automatically when the FP was added to a registered version), and set Value__c = true.
  5. Within the propagation window (minutes), the customer's Apex sees true on the next call.

Why not a custom field on a Custom Setting: Custom Settings live in the subscriber's data — the partner has no cross-org write path without the LMA. Feature Parameters are the only sanctioned cross-org config channel.


Decision Guidance

SituationRecommended ApproachReason
Partner is shipping a free, non-paid 2GP managed package and never plans to monetizeSkip the LMA; use the standard 2GP install flowLMA registration is recommended but not required for free packages, and adds operational overhead
Partner is selling licenses and wants to enforce subscription expirationRegister with the LMA in a dedicated production LMO; rely on Salesforce's automatic License-status enforcementSubscription enforcement without the LMA requires custom Apex license checks and breaks AppExchange Checkout
Partner needs branded login screens during trialTMO with custom branding; TSO + Template; CRM-trial requires TMOEnvironment-Hub-only TSOs cannot do custom branding; TMO is the only supported branded path
Partner needs to flip a feature for one customer without a releaseLmoToSubscriber Feature ParameterCustom Settings can't be written cross-org; new package version is too heavy for a single-customer flip
Partner wants telemetry on how many subscribers are using a featureSubscriberToLmo Feature Parameter (Boolean for usage flag, Integer for counter)LMA telemetry without FPs requires hand-rolled callouts; FPs use the platform-native channel
Partner is moving an existing LMA to a new LMOSalesforce-side reconciliation case via Partner CommunityDirect LMA replication is unsupported and orphans existing Licenses
Trial method needs IDs/passwords for a non-Salesforce signup formSignupRequest API with TMO-backed templateAppExchange-listing trial doesn't support custom signup forms
Beta package version needs SubscriberToLmo Feature Parameter testingNot testable; promote to released version firstBeta package versions can't register with the LMA, so the FP propagation channel is inactive

When a request lands that involves any of: LMA setup, Trialforce setup, Feature Parameter design, AppExchange Checkout, or license enforcement in a managed package, follow these steps:

  1. Identify which org is which. Get the partner to label PBO, LMO, TMO, TSO, packaging org, and DX-hub explicitly. Half of all ISV-licensing tickets resolve once the org map is correct.
  2. Confirm package generation and trial method. 1GP vs 2GP and trial-method choice gate every downstream decision; capture both before recommending anything.
  3. Audit current LMA state. If an LMA exists, query sfLma__Package__c and sfLma__License__c counts and statuses; if not, plan the registration sequence per Pattern 1.
  4. Map Feature Parameters to direction and consumer. For every requested feature flag, decide direction (LmoToSubscriber or SubscriberToLmo) and where in the subscriber Apex it's read. Don't add an FP without a confirmed reader.
  5. Validate the change in a sandbox-installed test subscriber org. Install the package into a throwaway test org, confirm License record creation, exercise the FP propagation, and only then ship.
  6. Document the per-customer override path. Write down (in the partner's runbook) exactly which LMA fields a CSM edits to flip an FP, set seats, or extend an expiration — operational handoff is where most LMA setups go wrong months later.

Review Checklist


Salesforce-Specific Gotchas

  1. Only released package versions can register with the LMA. Beta versions install but do not create License records, and they do not propagate Feature Parameters. Do not test the LMA wiring with a beta — it will appear silently broken.
  2. Default License Type defaults to nothing useful. If the partner forgets to set the default on sfLma__Package__c, every new install creates a License record with no Type set, and the package's components are usable indefinitely until a human edits the License — there is no built-in trial-expiration safety net.
  3. Feature Parameter propagation is not real-time. Salesforce-managed schedules push values in both directions on the order of minutes. Code that flips an FP and then immediately reads it in the same transaction will get the old value.
  4. Feature Parameter limit is 200 per package. The 200-FP cap is per registered package version. Partners who ship a large feature matrix must consolidate into Integer/Date FPs (bitmask, date-cohort) rather than one Boolean per feature.
  5. Trialforce Templates expire when the underlying TSO is deleted or the Salesforce edition changes. A TSO downgrade or deletion silently invalidates downstream Templates, and trials created from an invalidated template fail at signup.
  6. Subscriber Apex cannot debug PostInstall failures. When Feature Parameters or LMA wiring fails on install, the Automated Process user runs the PostInstall script and the partner has no debug log unless the LMA's Subscriber Support Console is set up — set it up before the first paid customer install.
  7. Moving the LMA between orgs is unsupported in the Setup UI. The partner-portal case is the only supported migration path. Partners who manually replicate sfLma__License__c records will have broken propagation for the migrated subscribers.

Output Artifacts

ArtifactDescription
LMA registration runbookStep-by-step: install LMA → upload package → register LMO → verify with test install → set defaults → wire suspension alerts
Trialforce architecture diagramTMO ↔ TSO ↔ Template flow with arrows for who-creates-who, plus the trial-method choice that consumes the Template
Feature Parameter inventoryPer-FP table: name, type, direction, default value, reader location, and operational owner in the LMO
Org-role label mapNames every org (PBO, LMO, TMO, TSO, packaging, DX hub) so subsequent troubleshooting starts from a known state

Package files