In addition to licensing and online activation, LimeLM fully supports timed trials. Timed trials can be used within your application to allow prospective customers to try your application for a limited time.
There are two types of trials:
The difference between these 2 is that a customer using unverified trials can start the trial immediately without verifying with your company or our activation servers. Whereas, with verified trials, your app needs to activate (thus verify) before your customer can use the trial of your app.
In both cases (verified & unverified trials) there's tamper protection and the trial can't be reset by reinstalling your app. But verified trials have even better tamper protection (wiping out the machine totally and reinstalling the operating system won't even reset the trial). Also, in both cases, you can extend the trial if the prospective customer needs more time.
Verified trials allow you to offer trials to your users that are verified with our servers, cryptographically-signed, and locked to that machine, all without having to give your customers a product key ahead of time.
The benefits to verified trials:
The customer can't reset the trial: a verified trial cannot be reset even if the customer completely wipes their device and re-installs their operating system. We accomplish this using our proprietary computer-fingerprinting technology.
You have real-time stats on who is trying your app: The instant a new potential customer tries your app you'll have up-to-date information on where they are, when the started the trial, and when it expires.
Track conversions: In addition to the raw information about potential customers you'll also know which trial users converted to paying customers.
The downsides to verified trials: your app needs to contact the activation servers before the customer can use your app. Or, if you want to allow them to start the verified trial without internet access you can use the TA_UseTrialVerifiedRequest()
and TA_UseTrialVerifiedFromFile()
functions.
Unverified trials are just what they sound like — the trial is created completely on the client side (our activation servers are never contacted).
The benefits to unverified trials: the customer doesn't need internet access to start a trial. They can just download your app and start using it right away.
The downsides to unverified trials:
No fraud protection: Unverified trials can be reset easily just by deleting a few files.
Flying blind: You won't know who is using your app, or anything about your potential customers.
Starting with TurboActivate 4.0 we've dramatically simplified verified trials so that they don't require product keys. And we've merged the functionality with the existing unverified trials API, reducing your development time and support workload. In the examples below we show how to use verified trials by using the TA_VERIFIED_TRIAL
flag. But if you want to use unverified trials all you have to do is replace that flag with TA_UNVERIFIED_TRIAL
.
TA_UseTrial()
/ TurboActivate.UseTrial()
TA_TrialDaysRemaining()
/ TurboActivate.TrialDaysRemaining()
TA_SetTrialCallback()
/ TurboActivate.TrialChange
eventTA_ExtendTrial()
/ TurboActivate.ExtendTrial()
TA_UseTrialVerifiedRequest()
/ TurboActivate.UseTrialVerifiedRequest()
TA_UseTrialVerifiedFromFile()
/ TurboActivate.UseTrialVerifiedFromFile()
TA_UseTrial()
/ TurboActivate.UseTrial()
The UseTrial()
function begins the trial the first time it's called. Calling it again will simply validate the trial data hasn't been tampered with.
It's recommended that you call the TA_UseTrial()
/ TurboActivate.UseTrial()
function at the start of your application. Here's a simple example in C/C++:
// Set the trial flags you want to use. Here we've selected that the
// trial data should be stored system-wide (TA_SYSTEM) and that we should
// use un-resetable verified trials (TA_VERIFIED_TRIAL).
uint32_t trialFlags = TA_VERIFIED_TRIAL | TA_SYSTEM;
// Start or re-validate the trial if it has already started.
// This need to be called at least once before you can use
// any other trial functions.
HRESULT hr = TA_UseTrial(taHandle, trialFlags, NULL);
if (hr == TA_OK)
{
//TODO: Get the number of trial days remaining.
}
else
printf("TA_UseTrial failed: hr = 0x%x\n", hr);
And here's what this example would look like in C#:
// Set the trial flags you want to use. Here we've selected that the
// trial data should be stored system-wide (TA_SYSTEM) and that we should
// use un-resetable verified trials (TA_VERIFIED_TRIAL).
TA_Flags trialFlags = TA_Flags.TA_SYSTEM | TA_Flags.TA_VERIFIED_TRIAL;
try
{
ta.UseTrial(trialFlags);
//TODO: get the number of remaining trial days
}
catch (TurboActivateException ex)
{
MessageBox.Show("Failed to start the trial: " + ex.Message);
}
TA_TrialDaysRemaining()
/ TurboActivate.TrialDaysRemaining()
The TA_TrialDaysRemaining()
/ TurboActivate.TrialDaysRemaining()
function will give you the remaining days left in the trial. And if the trial has expired, then the days left will be "0". So, here would be the continuation of the above C/C++ example:
uint32_t trialDays = 0;
// Set the trial flags you want to use. Here we've selected that the
// trial data should be stored system-wide (TA_SYSTEM) and that we should
// use un-resetable verified trials (TA_VERIFIED_TRIAL).
uint32_t trialFlags = TA_VERIFIED_TRIAL | TA_SYSTEM;
// Start or re-validate the trial if it has already started.
// This need to be called at least once before you can use
// any other trial functions.
HRESULT hr = TA_UseTrial(taHandle, trialFlags, NULL);
if (hr == TA_OK)
{
// Get the number of trial days remaining.
hr = TA_TrialDaysRemaining(taHandle, trialFlags, &trialDays);
if (hr == TA_OK)
printf("Trial days remaining: %d\n", trialDays);
else
printf("Failed to get the trial days remaining: hr = 0x%x\n", hr);
}
else
printf("TA_UseTrial failed: hr = 0x%x\n", hr);
And here's the continuation of the above C# example:
uint trialDaysRemaining = 0;
// Set the trial flags you want to use. Here we've selected that the
// trial data should be stored system-wide (TA_SYSTEM) and that we should
// use un-resetable verified trials (TA_VERIFIED_TRIAL).
TA_Flags trialFlags = TA_Flags.TA_SYSTEM | TA_Flags.TA_VERIFIED_TRIAL;
try
{
ta.UseTrial(trialFlags);
// get the number of remaining trial days
trialDaysRemaining = ta.TrialDaysRemaining(trialFlags);
}
catch (TurboActivateException ex)
{
MessageBox.Show("Failed to start the trial: " + ex.Message);
}
// if no more trial days then disable all app features
if (trialDaysRemaining == 0)
DisableAppFeatures();
else
lblTrialMessage.Text = "Your trial expires in " + trialDaysRemaining + " days.";
TA_SetTrialCallback()
/ TurboActivate.TrialChange
eventIn addition to checking if a trial has expired at the start of your app, you can also tell TurboActivate to notify you when the trial has expired during the lifetime of your process running. You must first call TA_UseTrial()
at least once in the lifetime of the process the callback function (or event) is only called if the trial has expired since that TA_UseTrial()
call.
To do this either use the TA_SetTrialCallback()
function in C/C++ like so:
/*
This function will be called by a separate background thread to notify
your app of trial expiration (either naturally, or because of customer fraud).
That means if you're displaying UI to your users you must ensure
that any windows (or any resource sharing for that matter) are
created in the right thread context or bad things might happen.
Test this behavior well before releasing to your end-users.
*/
void TA_CC trialCallback(uint32_t status, void * userDefinedPtr)
{
switch (status)
{
case TA_CB_EXPIRED:
//TODO: disallow any features in your app.
printf("The app trial period has expired\n");
break;
case TA_CB_EXPIRED_FRAUD:
//TODO: disallow any features in your app.
printf("The app trial has expired due to date/time fraud\n");
break;
default:
printf("The app trial callback returned an unexpected status: %d\n", (int)status);
break;
}
}
int main()
{
// Start or re-validate the trial if it has already started.
// This need to be called at least once before you can use
// any other trial functions.
hr = TA_UseTrial(taHandle, trialFlags, NULL);
if (hr == TA_OK)
{
// Get the number of trial days remaining.
hr = TA_TrialDaysRemaining(taHandle, trialFlags, &trialDays);
if (hr == TA_OK)
{
printf("Trial days remaining: %d\n", trialDays);
if (trialDays > 0)
{
// Set the function that TurboActivate will call from another thread
// letting your app know of trial expiration (either naturally, or
// because of customer fraud).
hr = TA_SetTrialCallback(taHandle, trialCallback, NULL);
if (hr != TA_OK)
printf("Error setting trial callback: hr = 0x%x\n", hr);
}
}
else
printf("Failed to get the trial days remaining: hr = 0x%x\n", hr);
}
else
printf("TA_UseTrial failed: hr = 0x%x\n", hr);
}
Or, in C# and other languages, hook into the TrialChange
event:
public Form1()
{
InitializeComponent();
try
{
//TODO: goto the version page at LimeLM and paste this GUID here
ta = new TurboActivate("17738358944b7a7316ec5fe9.23132283");
// set the trial changed event handler
ta.TrialChange += trialChange;
// ...
}
}
void trialChange(object sender, StatusArgs e)
{
// disable the features of your app
DisableAppFeatures(e.Status == TA_TrialStatus.TA_CB_EXPIRED_FRAUD);
}
TA_ExtendTrial()
/ TurboActivate.ExtendTrial()
The TA_ExtendTrial()
accepts a trial extension string and, if it's valid, it extends the trial on the customer's computer. After a valid trial extension string has been entered, you can call the TA_TrialDaysRemaining()
/ TurboActivate.TrialDaysRemaining()
function to see the new number of trial days remaining.
Here's a very simple example of using TA_ExtendTrial()
in C/C++:
// The same flags you used in TA_UseTrial()
uint32_t trialFlags = TA_VERIFIED_TRIAL | TA_SYSTEM;
HRESULT hr = TA_ExtendTrial(taHandle, trialFlags, _T("INSERT TRIAL EXTENSION"));
if (hr == TA_OK)
printf("The trial extension was successful!");
else
printf("TA_ExtendTrial failed: hr = 0x%x\n", hr);
And here's the same example in C#:
// The same flags you used in ta.UseTrial()
TA_Flags trialFlags = TA_Flags.TA_SYSTEM | TA_Flags.TA_VERIFIED_TRIAL;
try
{
// try to extend the trial and close the form
ta.ExtendTrial("INSERT TRIAL EXTENSION", trialFlags);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Trial extension failed.", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
TA_UseTrialVerifiedRequest()
/ TurboActivate.UseTrialVerifiedRequest()
This function generates an offline verified trial request and saves it to an XML file. The customer sends that file to you and you use that request (either in the LimeLM interface or the web API) to generate the "verified trial response".
Here's a very simple example of using TA_UseTrialVerifiedRequest()
in C/C++:
HRESULT hr = TA_UseTrialVerifiedRequest(taHandle, filename, NULL);
if (hr == TA_OK)
printf("Generating the verified trial request was successful!");
else
printf("TA_UseTrialVerifiedRequest failed: hr = 0x%x\n", hr);
And here's the same example in C#:
try
{
ta.UseTrialVerifiedRequest(filename);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "UseTrialVerifiedRequest failed.", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
TA_UseTrialVerifiedFromFile()
/ TurboActivate.UseTrialVerifiedFromFile()
This function takes the "verified trial response" generated from LimeLM (either in the interface or the web API) and starts the verified trial on that customer's device.
Here's a very simple example of using TA_UseTrialVerifiedRequest()
in C/C++:
// Set the trial flags you want to use. Here we've selected that the
// trial data should be stored system-wide (TA_SYSTEM) and that we should
// use un-resetable verified trials (TA_VERIFIED_TRIAL).
uint32_t trialFlags = TA_VERIFIED_TRIAL | TA_SYSTEM;
HRESULT hr = TA_UseTrialVerifiedFromFile(taHandle, filename, trialFlags);
if (hr == TA_OK)
printf("The verified trial started successfully!");
else
printf("TA_UseTrialVerifiedFromFile failed: hr = 0x%x\n", hr);
And here's the same example in C#:
// Set the trial flags you want to use. Here we've selected that the
// trial data should be stored system-wide (TA_SYSTEM) and that we should
// use un-resetable verified trials (TA_VERIFIED_TRIAL).
TA_Flags trialFlags = TA_Flags.TA_SYSTEM | TA_Flags.TA_VERIFIED_TRIAL;
try
{
ta.UseTrialVerifiedFromFile(filename, trialFlags);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "UseTrialVerifiedFromFile failed.", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Trial extensions are codes you can give to prospective users so they can extend the trial to your application.
There are many uses for trial extensions. For instance, a user could tell you their trial expired and they haven't convinced upper management to make a purchase yet. Or perhaps they tried your application once, went on vacation, and have come back to discover the trial is expired.
In both cases (and many more instances) trial extensions are the solution.
To generate a trial extension, the first thing you need to do is click the "Trial extensions" clink on the side bar of one of your product versions:
After that, on the trial extensions page, click the "Create a new trial extension" link and you'll be presented with a few options. For starters you can choose from an "online" trial extension and an "offline" trial extension.
We recommend creating an "online" trial extension for all cases except when the user is on a restricted internet (government, banks, etc.). The advantages of the "online" trial extensions are as follows:
Much shorter extension string for the user to type (only 34 characters) as compared to the 380+ characters required for the "offline" trial extension.
You can limit how many times the trial extension can be used.
You can change the length of the trial extension and when it expires after you've created it.
In addition to generating trial extensions from within LimeLM, you can integrate this ability into your website or company processes. To do this use the limelm.trialExtension.generate web API function.