You can create as many custom license fields and meta-data to associate with your product keys as you need. You can use these license fields for your own back-office purposes (to track users, companies, resellers, etc.). You can also use license fields in your application. After the user has activated, you can read the custom field values within your app even if the customer is not connected to the internet.
You can use these fields to limit parts of your app, license individual components or modules, time-limit your app or individual parts of it, etc. With license fields you have absolute control over every piece of your order process and your app.
A few of the big advantages of custom license fields is that:
You can read them inside your app and the customer doesn't need to be connected to the internet at all. This means that even if the customer used offline activation everything will work.
The custom license fields can be changed by you at any time — even after the customer has already activated your app.
The custom license fields cannot be modified by the customer because the data is cryptographically signed along with the activation data. That means if a customer tried to change the custom license field data they would no longer be activated (because the signature would no longer match the data).
All of this means that custom license fields are a secure and flexible tool to help sell your app.
This article covers the following topics (click to skip to the topic):
There are no bounds to what you can do with license fields. Here are just a few concrete examples of how our customers are using license fields:
Fields for the customer information (company name, company VAT, etc.)
Fields for reseller-specific ID's
Using the fields to enable certain features & plugins in their app depending on what the customer purchased.
Using the fields to sell their software on a renewal basis (e.g. free updates for a year after purchase with the ability to renew).
In short, you can use the license fields for everything from storing meta-data alongside your product keys to limiting specific features in your app based on what a customer purchased.
Adding a custom license field is as simple as clicking the "Custom license fields" link on your dashboard or on the sidebar:
You'll be presented with a page that lists all of your current custom license fields and where you add, edit, and remove your custom fields for that version of your software. Click the "Create a new license field" link on that page to begin the process of creating a new license field:
There are 4 basic types of fields: strings, dates & times, integers, and a checkbox.
Strings are the default field type. You can store any data you want in the string field types — there's no limitation.
The Date / Time field types are stored in the form YYYY-MM-DD hh:mm:ss
. If you're entering the field data using LimeLM, you'll get a nice date / time picker shown to the right. If you're using web API then you must make sure the data is in the form YYYY-MM-DD hh:mm:ss
.
With the integer license field type you're limited to entering only integers.
With the checkbox license field type you're limited to either a "checked state" or an "unchecked state". If you've set the custom license field tobe "readable from your app" then when you call TA_GetFeatureValue()
in TurboActivate or TF_GetFeatureValue()
in the TurboFloat Library then these are the possible return values:
Unchecked: a string "0" is returned.
Checked: a string "1" is returned.
You can specify what the default value for a custom license field is. This is useful for cases where you have a predictable "common default" for most users and you want to save time from entering the same values over and over again when creating product keys.
And in the case of the "Date / Time" data type, you can specify either absolute times or relative times (relative to when the product key is created). This is especially useful for time-based or SaaS licensing. By using a "relative time" default, you can just let LimeLM generate the date/time for you, rather than calculating it yourself.
When a user activates your app then all of the license field data is sent along with cryptographically-signed activation data. This means as soon as a user has activated you can use the TurboActivate function TA_GetFeatureValue()
to get the field value. If the customer is activated then they don't need an active internet connection to use the TA_GetFeatureValue()
function.
If the customer is using floating licensing (TurboFloat) instead of node-locked licensing (TurboActivate), then when the customer activates their TurboFloat Server instance then, like with TurboActivate, all of the license field data is sent along with cryptographically-signed activation data. So, when your app requests a license lease from the TurboFloat Server, all of the custom license fields are available from within your app using the TF_GetFeatureValue()
function.
There are many ways you can use license fields in your application, here are just 2 examples:
A common use of license fields is to make it easy to sell sub-modules or components to your customer. For instance, let's say you're selling your main app "YourApp" and 2 optional subcomponents "ExtensionX" and "ExtensionY". In this example we're going to keep it simple and just say the extensions can either be enabled or disabled (and thus we're going to use the "Checkbox" datatype).
If you haven't already, add your product to LimeLM.
Create a new field with the name "ExtensionX", the type of "Checkbox", leave the "Required field" checkbox checked, and leave "Readable from your app?" checked.
Do the same for "ExtensionY".
Now, when you create product keys for "YourApp" either using the LimeLM interface or the limelm.pkey.generate web API function then you'll be able to check the "ExtensionX" and "ExtensionY" checkboxes.
Inside your application you can read the field value to see if the extensions are enabled. That is, to see if the users have purchased your components use the TA_GetFeatureValue()
function. A simple example in C# looks like this:
if (ta.GetFeatureValue("ExtensionX") == "1")
{
// the user has purchased your ExtensionX
//TODO: enable the extension
}
else
{
// tell the user that they can buy ExtensionX on your website
}
Another popular use of license fields is to limit parts of the app by time. For instance, selling the app (or parts of the app) on a subscription basis. We cover one possibility in the "SaaS and time-limited licensing" article.
The way you limit your app, or any individual part of it, by time is to create a license field of the "Date / Time" type. For example, let's say I create a field named "updates_expires" to represent the date on which the customer can no longer receive free updates.
The way to check if the date has expired is to use the TA_GetFeatureValue()
function in tandem with the TA_IsDateValid()
function. A simple example in C# looks like this:
if (ta.IsDateValid(ta.GetFeatureValue("updates_expires"),
TurboActivate.TA_DateCheckFlags.TA_HAS_NOT_EXPIRED))
{
// the updates_expires date hasn't yet been reached
}
else
{
// the update period has expired
}
You can also use these license fields on your server. If you're using license fields to limit updates to your customers, then you can use these fields to choose whether to send an update file to the customer. Here's a broad overview of how it would be done:
When your app requests the update file from your server, pass along the customer's product key as part of the request.
On the server, get the product key ID for the product key using the limelm.pkey.getID API function.
Get the field values of the product key using the limelm.pkey.getDetails API function.
Verifying the "update_expires" field value is a date later than today.
Deliver the update file requested OR throw an error (403 error code).
This particular example of limiting updates on the server side has a fully written example. If you're using PHP or ASP.NET (C# or VB.NET) use the "\PHP\limit-updates\index.php" file or the "limit-updates.aspx" file for ASP.NET (get the Web API pack on your API page).
At some point the customer's subscription will expire, in the next section we cover how to update custom license fields, with an example of setting a new expiration date for the product key and how to read that new value in your app.
A common use for custom license fields is selling components that can be purchased later, or selling your app (or just parts of it) on a subscription basis. In either case you'll need to change that custom license fields for a product key, and then read those changes inside your app.
The simplest way to change the custom license fields for a product key is to login to your LimeLM account, search for the product key, edit the key, enter the new custom license fields, and click the "Save changes" button.
When you change the field data for a product key (either within your LimeLM dashboard or using the limelm.pkey.setDetails web API function) the changes are reflected immediately on the servers, but they are not reflected immediately on the customer's machine. Why not? Because the customer is not continually connected to the activation servers.
When are the changes to the custom license fields reflected on the customer's machine? Whenever your app reverifies with the activation servers.
If your app is using TurboActivate, then this reverification with the activation servers (and thus downloading of the custom license fields data) happens in the following cases:
If you're following the TurboActivate integration examples then you'll be calling the TA_IsGenuineEx()
function at the start of your app. The TA_IsGenuineEx()
function reverifies with the activation servers every nDaysBetweenChecks
. So, if you set that "nDaysBetweenChecks
" value to 30, then every 30 days your customers will get the latest custom license fields from the activation servers.
If you're using the TA_IsGenuine()
function then a succesful call will result in getting the latest custom license fields from the servers. Note: you should not call TA_IsGenuine()
on every start of your app — use TA_IsGenuineEx()
.
Re-activating your app using either online activation (TA_Activate()
) or offline activation (TA_ActivationRequestToFile()
and TA_ActivateFromFile()
) will get the latest custom license fields.
If your app is using TurboFloat, then this reverification with the activation servers (and thus downloading of the custom license fields data) happens in the following cases:
When the TurboFloat Server re-verifies with the activation servers based on the <isgenuine .../> element in the configuration file.
Or if the customer wants to re-activate immediately, they can: Activating the TurboFloat Server. The customer doesn't need to deactivate first. All they have to do is stop their instance of the TurboFloat Server and then re-activate online using the -a
commandline switch. Or to activate offline they need to use the -a -areq="C:\Location\To\Save\ActivationRequest.xml"
to get a new activation request file to submit to you.
Let's continue with the example from above. In this example let's also say that a customer purchases "YourApp" but doesn't initially buy your optional components (ExtensionX or ExtensionY). Then after using your program a while, the customer decides to buy your "ExtensionX" optional component.
Here's how you handle the subtleties of enabling optional components for a customer:
The first thing you need to do is either create a new purchase page that allows users to purchase components for their existing licenses, or modify your existing purchase page to accept the customer's product key for upgrades.
Now that the customer has purchased your optional component "ExtensionX" you will have to edit the product key to enable the "ExtensionX" license field. You can either manually edit the product key in your LimeLM dashboard. Or you can use the limelm.pkey.setDetails web API function to set the new field value. And because you modified the purchase page in Step 1 to accept the customer's existing product key, you can automatically set the new custom license field(s) for that product key using the LimeLM web API.
After the user has purchased the new component and you've set the field value for the customer's product key, now you just have to get this latest field value to your customer. If you followed our "Using TurboActivate" articles with the accompanying example source code then you're likely using TA_IsGenuineEx()
or TurboActivate.IsGenuine(x, y, z)
. If you are, then every nDaysBetweenChecks
TurboActivate will contact the activation servers, reverify the license data, and also download any new custom license field data. This means that, by default, your app will eventually get the latest custom license field data.
But what about the case where the customer purchased a new feature of your app (enabled by a custom license field), and they don't want to wait nDaysBetweenChecks
to actually start using that feature? Well, in that case we recommend adding a dialog somewhere in your application that lets the customer re-check with the activation servers immediately. One way many of our customers do this is by adding a "Recheck license" button to their "about box" in their app and then re-check with the activation servers using one of the methods listed above.
Do not force the customers to re-check with the activation servers every time your app runs. Although it seems like an easy solution, it's really overkill, hammers our activation servers, and forces legit customers to always have an active internet connection. Instead use the recommendations above.
Let's say that instead of having a custom license field for a static component, like the example above, you have a custom license field with an expiration date. For example, you might want to sell your app, or a part of your app, on a monthly subscription and every month you will charge the customer's credit card. If the charge succeeds you'll update the custom license field with a new expiration date.
So, how do you handle this?
The way you handle it is similar to how you handle it in the previous example.
Similar to step 1 in the previous example you'll want to modify your purchase page to set the initial expiration date custom license field. You'll also want to either make a script on your website, or use some third party payment platform, to ensure every month (or however often you want to bill) your customers' payment methods are charged and you update the custom license field with the new expiration date.
Inside your app you can use our TA_GetFeatureValue()
and TA_IsDateValid()
functions to both read the custom license field and to check whether it is expired. See "Example #2: SaaS or time limited restrictions" above for an example of using these functions.
When the subscription has expired, rather than just exiting your app, instead use it as an opportunity to up-sell your customer (and get them to renew their subscription). Give them a link to purchase a renewal on your website, and give them the option to re-check their license immediately (as described in the example above).
When you use either the limelm.pkey.generate or limelm.pkey.setDetails web API functions you can set the field values by using the feature_name[]
and feature_value[]
arguments. For example let's say you have 2 fields that you want to set:
first_feature set with the value professional.
update_expires set with the value 2012-06-25 04:13:16.
To generate a product key you would urlencode the field names and values as follows:
...?method=limelm.pkey.generate&feature_name[]=first_feature&feature_value[]=professional&feature_name[]=update_expires&feature_value[]=2012-06-25%2004%3A13%3A16