General overview of KEYZY C++ Client Library
The main idea behind the KEYZY C++ Client Library is to offer simple methods for activating and validating your product's license management. Additionally, it provides functionality for registering trial licenses.
To activate and validate licenses, you need to utilize the following classes:
- KeyzyLicenseActivator
- KeyzyLicenseValidator
These classes provide the necessary functionality for license activation and validation within the KEYZY C++ Client Library.
To register licenses on the KEYZY service from the client side, use the LicenseDepositHandler class: registerTrial() creates a trial license and returns its serial number, and registerOfflineDistributedLicense() sets the licensee's name and email for an offline-distributed (dealer) license. Neither stores anything on the device; activate the serial number afterwards with one of the activation methods.
The KeyzyLicenseActivator class utilizes the ProductData structure as an input argument in its constructor. This allows the system to identify the specific product on the server side for license activation and validation purposes. By providing the relevant product information through the ProductData structure, the system can accurately handle the licensing operations associated with that product.
struct ProductData
{
ProductData() : _useHostIdInOffilneActivation(true), _hostIdScheme(HostIdScheme::V2) {}
ProductData(std::string appId, std::string apiKey, std::string productCode,
std::string cryptionKey, bool useHostIdInOfflineActivation = true,
HostIdScheme hostIdScheme = HostIdScheme::V2)
: _appId(appId)
, _apiKey(apiKey)
, _productCode(productCode)
, _cryptionKey(cryptionKey)
, _useHostIdInOffilneActivation(useHostIdInOfflineActivation)
, _hostIdScheme(hostIdScheme) {}
std::string _appId;
std::string _apiKey;
std::string _productCode;
std::string _cryptionKey;
bool _useHostIdInOffilneActivation;
};
HostIdScheme
Definition KeyzyTypes.h:27
- Warning
- Upgrading a product released on an SDK before 1.10.0: do not just rebuild. The default host id scheme is HostIdScheme::V2, so every device's host id changes and all existing activations would have to re-activate. Since 1.10.2, keep the default and call migrateHostIdV1toV2() on every start: users with a working license move to V2 without noticing (Host ID schemes → Moving a released product to V2). A product sold with offline licenses stays on HostIdScheme::V1.
Keyzy::ProductData productData(
"YOUR_APP_ID",
"YOUR_API_KEY",
"YOUR_PRODUCT_CODE",
"YOUR_CRYPTION_KEY");
auto pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
@ SemiOnline
The product uses activateSemiOnline() or registerTrial().
Definition KeyzyTypes.h:38
Definition KeyzyTypes.h:256
Your product's identity and credentials; construct one and pass it to KeyzyLicenseActivator to authen...
Definition KeyzyTypes.h:93
- You can obtain an appId and apiKey pair from the "App Keys" section of the KEYZY dashboard at App Keys.
- The product code can be obtained from the "Products" section of the KEYZY dashboard at Products.
- The cryption key (_cryptionKey) is in the "Products" section of the KEYZY dashboard at Products as well. Semi-online and offline activation need it to verify the license file on the device. Set it even if you start with online activation, so a later switch to semi-online works without changes.
Product activation process
Run the activation on every launch of your application: the first time with the serial the user enters (activateSemiOnline(serialNumber)), afterwards without it (activateSemiOnline()). Each run refreshes the license file on the device, so its Offline License Life starts again.
KeyzyLicenseActivator class provides the following methods that should be used to activate or deactivate a license:
- LicenseStatus activateOnline(const std::string& serialNumber);
- LicenseStatus deactivateOnline();
- LicenseStatus activateSemiOnline(const std::string& serialNumber);
- LicenseStatus activateSemiOnline();
- LicenseStatus deactivateSemiOnline();
- LicenseStatus activateOffline(const std::string& licenseFilePath);
- bool deactivateOffline();
- LicenseStatus upgradeLicense(const std::string& targetSerial);
- LicenseStatus upgradeLicense(const std::string& sourceSerial, const std::string& targetSerial);
- HostIdMigrationResult migrateHostIdV1toV2(HostIdMigrationMode mode); (see Host ID schemes → Moving a released product to V2)
License validation process
Online license validation
Online validation checks the serial number stored on the device with the KEYZY service each time it is called, so it needs an internet connection. The serial number comes from the user, or from registerTrial() for a trial, and activateOnline() stores it on the device.
You need to call the LicenseStatus validateOnline() function from the KeyzyLicenseValidator class. If the serial number is valid, this function will return the value LicenseStatus::VALID.
Offline license validation
The offline validation process uses a license file provided by the KeyzyLicenseActivator class and does not require an internet connection.
You need to call the LicenseStatus validateOffline() function from KeyzyLicenseValidator class. If the license file is valid, this function will return the value LicenseStatus::VALID.
Semi-Online activation schema uses the offline validation process as well.
Dealer information
After a successful validateOnline() or validateOffline(), the dealer name is available from KeyzyLicenseValidator for offline-distributed (dealer) licenses: getDealerName() returns the dealer's display name (empty string when the license has no dealer). It is populated by the online and offline flows alike.
Host ID schemes
The SDK identifies each device with a host id. Two generation schemes are available, selected per product with ProductData::_hostIdScheme or the last ProductData constructor parameter (default V2 since SDK 1.10.0):
- HostIdScheme::V2: the default. Uses more stable hardware information, so the host id survives network changes and OS reinstalls. On Linux, V2 is identical to V1.
- HostIdScheme::V1: the scheme used by SDK versions before 1.10.0.
- Warning
- Upgrading a product released on an SDK before 1.10.0: do not just rebuild. The default host id scheme is HostIdScheme::V2, so every device's host id changes and all existing activations would have to re-activate. Since 1.10.2, keep the default and call migrateHostIdV1toV2() on every start: users with a working license move to V2 without noticing (Host ID schemes → Moving a released product to V2). A product sold with offline licenses stays on HostIdScheme::V1.
Moving an already-released product from V1 to V2 changes its device host ids. Without migrateHostIdV1toV2(), existing activations need to re-activate once, and previous activations keep consuming license slots until they are reset. With it (since SDK 1.10.2), the move happens on the end user's device without user input (below).
If the device identifier cannot be read (extremely rare), methods that use the host id can return LicenseStatus::CANNOT_READ_HOST_ID.
Moving a released product to V2
For a product released with HostIdScheme::V1 (every product released on an SDK before 1.10.0). Construct the activator with HostIdScheme::V2 (the default) and call migrateHostIdV1toV2() on every start, in place of the first step of your start-up flow (validateOffline() for semi-online, validateOnline() for online). On the next start, every user with a working V1 license moves to V2 without noticing anything. A user whose V1 license has run out on the device (not started for a while) moves too, as long as the serial is still stored. A user whose device ID has already changed under V1 moves to V2 with the serial stored on the device; if their device limit is full, an old activation has to be removed first, as today.
The parameter says how your product activates its licenses: HostIdMigrationMode::SemiOnline (activateSemiOnline(), also server-side trials from registerTrial()) or HostIdMigrationMode::Online (activateOnline() and validateOnline()).
Offline activation (activateOffline()) is not supported. Keep a product sold with offline licenses on HostIdScheme::V1, or send each user a new license file made for their V2 host id.
The call returns two values:
- status (LicenseStatus): can the user use the product now. Handle it as in your start-up flow. VALID does not mean the move has finished.
- state (HostIdMigrationState): what happened to the move.
| state | Meaning | What to do |
| AlreadyV2 | No V1 license to move and the V2 license is valid. | Follow status. |
| Moved | The license moved from V1 to V2 on this call. | Follow status. |
| NothingToMove | No working license to move. The result of the normal start-up step, or the reason it could not run, is in status. | Follow status (for example, show the serial form on CLIENT_SERIAL_DOES_NOT_EXIST). |
| NotNeededOnPlatform | No move is needed on this platform (Linux: V2 is identical to V1); the normal start-up step ran. | Follow status. |
| StayedOnV1 | The move did not finish this time; the license stays on V1 for this start. Whether it can be used is in status. | For the rest of this run, use an activator constructed with HostIdScheme::V1 (example below). The next start tries again. |
| Interrupted | The move started but did not finish, and there is no license on the device for now. | Follow status: it says why. Once the cause is gone (for example the connection is back, or the subscription is renewed), the next start finishes the move with the stored serial; the user enters nothing. |
| WrongHostIdScheme | The activator was constructed with HostIdScheme::V1; nothing was done and status is INVALID. | An integration error: construct it with HostIdScheme::V2. |
Semi-online start-up flow with the move:
auto pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
auto pValidator = pActivator->getLicenseValidator();
{
pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
pValidator = pActivator->getLicenseValidator();
status = pValidator->validateOffline();
}
{
pActivator->activateSemiOnline();
}
else
{
{
std::string serial = getSerialFromUser();
status = pActivator->activateSemiOnline(serial);
}
{
}
}
@ V1
The host_id scheme used by SDK versions before 1.10.0. Keeps existing activations valid for products ...
Definition KeyzyTypes.h:28
@ StayedOnV1
The license stays on V1 for this start; whether it can be used is in the status. For the rest of this...
Definition KeyzyTypes.h:49
LicenseStatus
Definition KeyzyTypes.h:200
@ SERIAL_INVALID
The serial number is invalid or not registered. (Server-side).
Definition KeyzyTypes.h:205
@ ACTIVATION_DEACTIVATED
This device's activation was deactivated (revoked) on the server. (Server-side).
Definition KeyzyTypes.h:213
@ CLIENT_SERIAL_DOES_NOT_EXIST
No serial number is stored on the device. (Client-side).
Definition KeyzyTypes.h:221
@ VALID
The license is valid and active. The only success status for validation/activation calls (with ACTIVA...
Definition KeyzyTypes.h:201
LicenseStatus status
Whether the user can use the product now; handle it as in your start-up flow.
Definition KeyzyTypes.h:257
HostIdMigrationState state
What happened to the move.
Definition KeyzyTypes.h:258
Call it once per process, before any other license call.
Online start-up flow with the move:
auto pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
auto pValidator = pActivator->getLicenseValidator();
{
pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
pValidator = pActivator->getLicenseValidator();
status = pValidator->validateOnline();
}
{
{
std::string serial = getSerialFromUser();
status = pActivator->activateOnline(serial);
}
{
}
}
@ INVALID
The license is invalid or could not be verified; generic failure when no more specific status applies...
Definition KeyzyTypes.h:203
@ Online
The product uses activateOnline() and validateOnline().
Definition KeyzyTypes.h:39
If your product was released with HostIdScheme::V1, keep the call in every release until a KEYZY SDK release marks it deprecated: a user who has not started your product since still needs it on their next start.
All error statuses
Network-layer statuses. CONNECTION_ERROR and the NETWORK_* statuses below are returned by any method that performs a network request when the call fails at the network layer (no HTTP response received): validateOnline(), activateOnline(), activateSemiOnline(), upgradeLicense(), deactivateOnline(), deactivateSemiOnline(), registerTrial(), registerOfflineDistributedLicense() and migrateHostIdV1toV2() (in the status of its result). They let your application show the end user a specific, actionable message instead of a generic "connection problem."
| Status | Explanation |
| LicenseStatus::VALID | The license is valid and active. The success status of validation and activation calls; deactivation succeeds with ACTIVATION_DELETED. |
| LicenseStatus::EXPIRED | A locally-stored (client-only) trial has expired. Returned by validateTrialLicense() from KeyzyLicenseValidator, deprecated since 1.10.0 with client-only trials. Use server-side trials (registerTrial()) instead; their expiry is reported as TRIAL_LICENSE_EXPIRED. (Client-side) |
| LicenseStatus::NOT_AUTHORIZED | The appId / apiKey pair is wrong or not authorized. Returned by any call that contacts the KEYZY server. (Server-side) |
| LicenseStatus::SERIAL_INVALID | The serial number is invalid or not registered. Returned by validateOnline() (KeyzyLicenseValidator), activateOnline() and activateSemiOnline() (KeyzyLicenseActivator). (Server-side) |
| LicenseStatus::PRODUCT_NOT_EXIST | The product code does not exist. Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::PRODUCT_NOT_EXIST_FOR_USER | The product code does not exist. Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::PRODUCT_NOT_ACTIVE | The product exists but is not active. Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::SKU_NOT_EXIST | The SKU does not exist. Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::SKU_NOT_ACTIVE | The SKU exists but is not active. Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::REACHED_MAX_NUMBER_OF_HOST | The license has reached its maximum number of activated devices (hosts). Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::PRODUCT_NOT_EXIST_FOR_SKU | The product exists but is not part of the SKU linked to this license. Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::ACTIVATION_DEACTIVATED | This device's activation was deactivated (revoked) on the server. Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::SUBSCRIPTION_LICENSE_EXPIRED | The subscription license has expired (its end date has passed). Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::SUBSCRIPTION_LICENSE_NOT_STARTED | The subscription license has not started yet (future start date). Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::TRIAL_LICENSE_EXPIRED | The server-side trial license has expired. (Distinct from EXPIRED, which is a local trial check.) Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::TRIAL_LICENSE_NOT_STARTED | The server-side trial license has not started yet (future start date). Returned by validateOnline(), activateOnline() and activateSemiOnline(). (Server-side) |
| LicenseStatus::CANNOT_KEEP_SERIAL | The SDK could not save the serial number to the device (write failed). Happens locally, before any server contact. (Client-side) |
| LicenseStatus::CANNOT_KEEP_LICENSE_FILE | The SDK could not save the license file to the device (write failed, often a wrong or unwritable target path). Happens locally. (Client-side) |
| LicenseStatus::ACTIVATION_DELETED | The activation was successfully removed from the KEYZY servers. A success status, returned by the deactivation flow. (Server-side) |
| LicenseStatus::CLIENT_SERIAL_DOES_NOT_EXIST | No serial number is stored on the device. Returned by activateSemiOnline() (without a serial number), upgradeLicense(targetSerial), deactivateOnline() and deactivateSemiOnline(). (Client-side) |
| LicenseStatus::CANNOT_READ_HOST_ID | The SDK could not read the device identifier. Happens locally, before any server contact. Returned by validateOnline(), validateOffline(), activateOnline(), activateSemiOnline(), activateOffline(), deactivateOnline() and registerTrial(). (Client-side) |
| LicenseStatus::CONNECTION_ERROR | Network or firewall error (umbrella). Returned when the connection fails at the network layer and no more specific NETWORK_* status applies. |
| LicenseStatus::NETWORK_DNS_FAILED | The address of the KEYZY server could not be resolved. Likely no internet connection, or DNS is blocked on that network. Ask the user to check their internet connection. |
| LicenseStatus::NETWORK_REFUSED | TCP connection refused, typically a firewall blocking outbound HTTPS. Ask the user to check their firewall settings. |
| LicenseStatus::NETWORK_TIMEOUT | Connection timed out. With no HTTP 407, this is usually a firewall blocking outbound HTTPS or a proxy silently dropping the connection. Ask the user to check firewall/proxy settings. |
| LicenseStatus::NETWORK_TLS_FAILED | TLS handshake failed: corporate SSL inspection, MITM or a wrong system clock. Ask the user to check the system date/time and any security software. |
| LicenseStatus::NETWORK_PROXY_REQUIRED | HTTP 407: the network requires an authenticated proxy. Ask the user to contact their IT department to whitelist api.keyzy.io, or to configure proxy credentials at the OS level. |
| LicenseStatus::NETWORK_HOSTS_TAMPERED | The address of the KEYZY server on this device points somewhere else, a strong sign of hosts-file or DNS manipulation. Advise the user to check their hosts file. |
| LicenseStatus::TOO_MANY_REQUESTS | The client sent too many requests in a short time and was rate-limited (HTTP 429). (Server-side) |
| LicenseStatus::NO_ACTIVE_SUBSCRIPTION | The account holder has a subscription problem on the KEYZY side (i.e. your own KEYZY plan is inactive, not the end user's license). (Server-side) |
| LicenseStatus::CURRENT_LICENSE_DOES_NOT_EXIST | During an upgrade, the source (current) license serial does not exist on the KEYZY servers. (Server-side) |
| LicenseStatus::UPGRADE_LICENSE_DOES_NOT_EXIST | During an upgrade, the target (upgrade) license serial does not exist on the KEYZY servers. (Server-side) |
| LicenseStatus::UPGRADE_LICENSE_DOES_NOT_MATCH | The target license is not a valid upgrade path for the current license. (Server-side) |
| LicenseStatus::ANOTHER_TRIAL_LICENSE_ALREADY_ACTIVATED | A trial has already been activated on this device; a second trial is blocked. (Server-side) |
| LicenseStatus::SKU_NUMBER_VALIDATION | The sku_number parameter failed validation (HTTP 422). (Server-side) |
| LicenseStatus::PRODUCT_CODE_VALIDATION | The product_code parameter failed validation (HTTP 422). (Server-side) |
| LicenseStatus::NAME_VALIDATION | The name parameter failed validation (HTTP 422). (Server-side) |
| LicenseStatus::EMAIL_VALIDATION | The email parameter failed validation. Rejected server-side (HTTP 422) or client-side (empty email in register* calls). (Server-side & Client-side) |
| LicenseStatus::SERIAL_VALIDATION | The serial parameter failed validation (HTTP 422 on register). (Server-side) |
| LicenseStatus::CODE_VALIDATION | Deprecated. Kept for ABI compatibility. |
| LicenseStatus::NO_FREE_LICENSES | No unassigned (free) licenses remain in this SKU's pool to register. Returned by registration flows (including trial registration) when the pool is exhausted; generate more licenses for the SKU. (Server-side) |
| LicenseStatus::NAME_OR_EMAIL_VALIDATION | Deprecated. Replaced by LicenseStatus::EMAIL_VALIDATION. Kept for ABI compatibility. |
| LicenseStatus::LICENSE_NOT_EXIST_NOT_ASSIGNED_DEALER_ALREADY_DEPOSITED | Register-offline-distributed-license flow: the license does not exist, is not assigned to a dealer, or has already been deposited. (Server-side) |
| LicenseStatus::INVALID | The license is invalid or could not be verified; generic failure when no more specific status applies. |
Example of offline-distributed license registration
Demonstrates registering an offline-distributed (dealer) license from the client side: it sets the licensee's name and email address.
#include <iostream>
using namespace Keyzy;
int main()
{
data._appId = "xxxxxxxx";
data._apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._productCode = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
data._cryptionKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._useHostIdInOffilneActivation = true;
const std::string serialNumber = "XXXX-XXXX-XXXX-XXXX-XXXX";
std::unique_ptr<KeyzyLicenseActivator> pLicenseActivator = std::make_unique<KeyzyLicenseActivator>(data);
std::shared_ptr<LicenseDepositHandler> pLicenseDepositHandler = pLicenseActivator->getLicenseDepositHandler();
registerDistributedLicenseStatus = pLicenseDepositHandler->registerOfflineDistributedLicense(serialNumber, "John Doe", "john@doe.com");
std::cout << errorStatuses(registerDistributedLicenseStatus) << std::endl;
} else {
std::cout << "The license was registered successfully." << std::endl;
}
return 0;
}
License activation and deactivation (online, semi-online, and offline flows).
@ V2
Default. Host_id from a stable firmware hardware identifier.
Definition KeyzyTypes.h:29
Example of server-side trial license process
Demonstrates registering a trial license and activating it on the device. registerTrial() sends a trial license request with the provided SKU number to the KEYZY service. If a free trial license is available for the given SKU number, KEYZY registers the license and responds with its information. registerTrial() does not store anything on the device; activate the returned serial number afterwards. The trial serial works with any activation method, like any other serial; this example uses activateSemiOnline().
#include <iostream>
using namespace Keyzy;
int main()
{
data._appId = "xxxxxxxx";
data._apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._productCode = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
data._cryptionKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._useHostIdInOffilneActivation = true;
std::unique_ptr<KeyzyLicenseActivator> pLicenseActivator = std::make_unique<KeyzyLicenseActivator>(data);
std::shared_ptr<LicenseDepositHandler> pLicenseDepositHandler = pLicenseActivator->getLicenseDepositHandler();
LicenseStatus registerTrialStatus = pLicenseDepositHandler->registerTrial(licenseInfo,
"your-sku-number",
"optional-licensee-name",
"licensee@example.com");
std::cout << errorStatuses(registerTrialStatus) << std::endl;
return 0;
}
std::cout <<
"Start Time : " << licenseInfo.
_startTime << std::endl;
std::cout <<
"End Time : " << licenseInfo.
_endTime << std::endl;
std::cout <<
"Serial Number : " << licenseInfo.
_serialNumber << std::endl;
std::cout << errorStatuses(activationStatus) << std::endl;
} else {
std::cout << "Trial activated" << std::endl;
}
return 0;
}
License details filled in by the SDK: SKU, product code, licensee name/email, type,...
Definition KeyzyTypes.h:182
std::int64_t _endTime
Definition KeyzyTypes.h:190
std::string _serialNumber
Definition KeyzyTypes.h:192
std::int64_t _startTime
Definition KeyzyTypes.h:189
Example of upgrade license process
The upgradeLicense() method only performs the upgrade on the KEYZY server. It does not activate or validate the new license, and does not store the target serial on the device. To activate the target serial afterward, use one of the activation methods (e.g. activateOnline, activateSemiOnline).
Upgrade using stored serial (recommended)
If the source serial is already stored on the device (from a previous activation), you only need to provide the target serial:
#include <iostream>
using namespace Keyzy;
int main()
{
data._appId = "xxxxxxxx";
data._apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._productCode = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
data._cryptionKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._useHostIdInOffilneActivation = true;
std::unique_ptr<KeyzyLicenseActivator> pLicenseActivator = std::make_unique<KeyzyLicenseActivator>(data);
LicenseStatus status = pLicenseActivator->upgradeLicense(
"TARG-ETSE-RIAL-XXXX-XXXX");
std::cout << "Upgrade License Status: " << errorStatuses(status) << std::endl;
status = pLicenseActivator->activateOnline("TARG-ETSE-RIAL-XXXX-XXXX");
std::cout << "Activation Status: " << errorStatuses(status) << std::endl;
}
}
Upgrade with explicit source and target serials
You can also provide both serials explicitly:
#include <iostream>
using namespace Keyzy;
int main()
{
data._appId = "xxxxxxxx";
data._apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._productCode = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
data._cryptionKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._useHostIdInOffilneActivation = true;
std::unique_ptr<KeyzyLicenseActivator> pLicenseActivator = std::make_unique<KeyzyLicenseActivator>(data);
LicenseStatus status = pLicenseActivator->upgradeLicense(
"SOUR-CESE-RIAL-XXXX-XXXX",
"TARG-ETSE-RIAL-XXXX-XXXX");
std::cout << "Upgrade License Status: " << errorStatuses(status) << std::endl;
status = pLicenseActivator->activateOnline("TARG-ETSE-RIAL-XXXX-XXXX");
std::cout << "Activation Status: " << errorStatuses(status) << std::endl;
}
}
Example of online license validation and activation process
#include <iostream>
using namespace Keyzy;
int main()
{
data._appId = "xxxxxxxx";
data._apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._productCode = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
data._cryptionKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._useHostIdInOffilneActivation = true;
std::unique_ptr<KeyzyLicenseActivator> pLicenseActivator =
std::make_unique<KeyzyLicenseActivator>(data);
std::shared_ptr<KeyzyLicenseValidator> pLicenseValidator =
pLicenseActivator->getLicenseValidator();
const std::string serialNumber = "XXXX-XXXX-XXXX-XXXX-XXXX";
status = pLicenseActivator->activateOnline(serialNumber);
std::cout << std::endl;
std::cout << "Online Activation Status: " << errorStatuses(status) << std::endl << std::endl;
std::cout << "Licensee's Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee's Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
} else {
std::cout << "Licensee's Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee's Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
std::cout << "Online Validation Status: " << errorStatuses(status) << std::endl << std::endl;
}
status = pLicenseActivator->deactivateOnline();
std::cout << "Online Deactivation Status: " << errorStatuses(status) << std::endl << std::endl;
}
Example of offline license validation and activation process
Offline activation takes three steps: show the user the host id from getHostIdHash() (an empty string if the device identifier cannot be read); the user generates the license file for that host id outside the application; the user selects the file and activateOffline() stores it on the device.
#include <iostream>
using namespace Keyzy;
int main()
{
data._appId = "xxxxxxxx";
data._apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._productCode = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
data._cryptionKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._useHostIdInOffilneActivation = true;
std::unique_ptr<KeyzyLicenseActivator> pLicenseActivator =
std::make_unique<KeyzyLicenseActivator>(data);
std::shared_ptr<KeyzyLicenseValidator> pLicenseValidator =
pLicenseActivator->getLicenseValidator();
const std::string hostId = pLicenseValidator->getHostIdHash();
if (hostId.empty()) {
return 0;
}
std::cout << "Host ID: " << hostId << std::endl;
status = pLicenseActivator->activateOffline("/Users/user111/Downloads/license_file.lic");
std::cout << "Offline Activation Status: " << errorStatuses(status) << std::endl << std::endl;
std::cout << "Licensee Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
} else {
std::cout << "Licensee Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
}
bool res = pLicenseActivator->deactivateOffline();
if (!res)
else
std::cout << "Offline Deactivation Status: " << errorStatuses(status) << std::endl << std::endl;
}
License validation (online and offline) and access to license fields (info, SKU, dealer,...
@ CANNOT_READ_HOST_ID
The SDK could not read the device identifier. Happens locally, before any server contact....
Definition KeyzyTypes.h:249
@ ACTIVATION_DELETED
The activation was successfully removed from the KEYZY servers. A success status, returned by the dea...
Definition KeyzyTypes.h:220
Full example (Online, Semi-Online and Offline Activation)
#include <iostream>
using namespace Keyzy;
int main()
{
data._appId = "xxxxxxxx";
data._apiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._productCode = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
data._cryptionKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
data._useHostIdInOffilneActivation = true;
std::unique_ptr<KeyzyLicenseActivator> pLicenseActivator = std::make_unique<KeyzyLicenseActivator>(data);
std::shared_ptr<KeyzyLicenseValidator> pLicenseValidator = pLicenseActivator->getLicenseValidator();
std::string serialNumber = "";
status = pLicenseValidator->validateOnline();
status = pLicenseActivator->activateOnline(serialNumber);
std::cout << std::endl;
std::cout << "Online Activation Status: " << errorStatuses(status) << std::endl << std::endl;
std::cout << "Licensee's Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee's Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
} else {
std::cout << "Licensee's Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee's Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
std::cout << "Online Validation Status: " << errorStatuses(status) << std::endl << std::endl;
}
status = pLicenseActivator->deactivateOnline();
std::cout << "Online Deactivation Status: " << errorStatuses(status) << std::endl << std::endl;
status = pLicenseValidator->validateOffline();
status = pLicenseActivator->activateSemiOnline();
status = pLicenseActivator->activateSemiOnline(serialNumber);
}
std::cout << "Semi Online Activation Status: " << errorStatuses(status) << std::endl << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
} else {
LicenseStatus renewStatus = pLicenseActivator->activateSemiOnline();
std::cout << "Semi Online Renew Activation Status: " << errorStatuses(renewStatus) << std::endl << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Licensee's Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee's Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
}
status = pLicenseActivator->deactivateSemiOnline();
std::cout << "Semi Online Deactivation Status: " << errorStatuses(status) << std::endl << std::endl;
status = pLicenseActivator->activateSemiOnline();
std::cout << "Semi Online Renew Activation Status 2 (Error expected): " << errorStatuses(status) << std::endl << std::endl;
}
const std::string hostId = pLicenseValidator->getHostIdHash();
if (hostId.empty()) {
} else {
std::cout << "Host ID: " << hostId << std::endl;
status = pLicenseActivator->activateOffline("/Users/user111/Downloads/license_file.lic");
}
std::cout << "Offline Activation Status: " << errorStatuses(status) << std::endl << std::endl;
std::cout << "Licensee Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
} else {
std::cout << "Licensee Name: " << pLicenseValidator->getLicenseeName() << std::endl;
std::cout << "Licensee Email: " << pLicenseValidator->getLicenseeEmail() << std::endl;
std::cout << "Version: " << pLicenseValidator->getVersion() << std::endl;
std::cout << "Sku: " << pLicenseValidator->getSku() << std::endl;
std::cout << "License Type: " << pLicenseValidator->getLicenseType() << std::endl;
std::cout << "Start Time: " << pLicenseValidator->getStartTime() << std::endl;
std::cout << "End Time: " << pLicenseValidator->getEndTime() << std::endl;
std::cout << "Info: " << pLicenseValidator->getInfo() << std::endl;
std::cout << "Dealer Name: " << pLicenseValidator->getDealerName() << std::endl;
}
bool res = pLicenseActivator->deactivateOffline();
if (!res)
else
std::cout << "Offline Deactivation Status: " << errorStatuses(status) << std::endl << std::endl;
}
Error function
Find the error function for all examples following.
{
switch(status) {
return "Expired";
return "Invalid";
return "Not authorized";
return "Serial invalid";
return "Product does not exist";
return "Product does not exist";
return "Product is not active";
return "SKU does not exist";
return "SKU is not active";
return "Reached maximum number of hosts";
return "Product does not exist for this SKU";
return "Activation is deactivated";
return "Subscription license expired!";
return "Subscription license not started!";
return "Trial license expired!";
return "Trial license not started!";
return "Cannot keep serial!";
return "Cannot keep license file!";
return "Activation deleted!";
return "Client serial does not exist!";
return "Connection Error!";
return "Cannot reach the server. Please check your internet connection.";
return "Connection refused. Please check your firewall settings.";
return "Connection timed out. Please check your firewall or proxy settings.";
return "Secure connection failed. Please check your system date/time and security software.";
return "A proxy is required. Please ask your IT to whitelist api.keyzy.io or configure proxy credentials.";
return "Cannot verify the server address. Please check your hosts file.";
return "Too Many Requests!";
return "Cannot read the device identifier!";
return "No Active Subscription!";
return "Current license does not exist!";
return "Upgrade license does not exist!";
return "The upgrade license is not a valid upgrade for the current license!";
return "Another trial license has already been activated on this device!";
return "sku_number parameter cannot be validated!";
return "product_code parameter cannot be validated!";
return "name parameter cannot be validated!";
return "email parameter cannot be validated!";
return "serial parameter cannot be validated!";
return "code parameter cannot be validated!";
return "You do not have any free licenses for this sku. Please generate new licenses for this sku!";
return "Either the name or email field must be filled!";
return "The license does not exist or is not assigned to a dealer or is already deposited!";
return "Valid";
default:
return "Unknown";
}
}
@ REACHED_MAX_NUMBER_OF_HOST
The license has reached its maximum number of activated devices (hosts). (Server-side).
Definition KeyzyTypes.h:211
@ SUBSCRIPTION_LICENSE_NOT_STARTED
The subscription license has not started yet (it has a future start date). (Server-side).
Definition KeyzyTypes.h:215
@ ANOTHER_TRIAL_LICENSE_ALREADY_ACTIVATED
A trial has already been activated on this device; a second trial is blocked. (Server-side).
Definition KeyzyTypes.h:228
@ SKU_NUMBER_VALIDATION
The sku_number parameter failed validation (HTTP 422). (Server-side).
Definition KeyzyTypes.h:229
@ UPGRADE_LICENSE_DOES_NOT_EXIST
During an upgrade, the target (upgrade) license serial does not exist on the KEYZY servers....
Definition KeyzyTypes.h:226
@ NO_ACTIVE_SUBSCRIPTION
The account holder has a subscription problem on the KEYZY side (i.e. your own KEYZY plan is inactive...
Definition KeyzyTypes.h:224
@ NETWORK_HOSTS_TAMPERED
The address of the KEYZY server on this device points somewhere else, a strong sign of hosts-file or ...
Definition KeyzyTypes.h:247
@ EXPIRED
A locally-stored (client-only) trial has expired. Returned by validateTrialLicense() in KeyzyLicenseV...
Definition KeyzyTypes.h:202
@ PRODUCT_NOT_EXIST_FOR_SKU
The product exists but is not part of the SKU linked to this license. (Server-side).
Definition KeyzyTypes.h:212
@ SERIAL_VALIDATION
The serial parameter failed validation (HTTP 422 on register). (Server-side).
Definition KeyzyTypes.h:236
@ TOO_MANY_REQUESTS
The client sent too many requests in a short time and was rate-limited (HTTP 429)....
Definition KeyzyTypes.h:223
@ NETWORK_REFUSED
TCP connection refused, typically a firewall blocking outbound HTTPS. Ask the user to check their fir...
Definition KeyzyTypes.h:243
@ CANNOT_KEEP_LICENSE_FILE
The SDK could not save the license file to the device (write failed, often a wrong or unwritable targ...
Definition KeyzyTypes.h:219
@ CODE_VALIDATION
Definition KeyzyTypes.h:237
@ TRIAL_LICENSE_NOT_STARTED
The server-side trial license has not started yet (future start date). (Server-side).
Definition KeyzyTypes.h:217
@ NETWORK_TIMEOUT
Connection timed out. With no HTTP 407, this is usually a firewall blocking outbound HTTPS or a proxy...
Definition KeyzyTypes.h:244
@ NO_FREE_LICENSES
No unassigned (free) licenses remain in this SKU's pool to register. Returned by registration flows (...
Definition KeyzyTypes.h:233
@ PRODUCT_NOT_ACTIVE
The product exists but is not active. (Server-side).
Definition KeyzyTypes.h:208
@ NAME_VALIDATION
The name parameter failed validation (HTTP 422). (Server-side).
Definition KeyzyTypes.h:231
@ SKU_NOT_ACTIVE
The SKU exists but is not active. (Server-side).
Definition KeyzyTypes.h:210
@ CANNOT_KEEP_SERIAL
The SDK could not save the serial number to the device (write failed). Happens locally,...
Definition KeyzyTypes.h:218
@ PRODUCT_NOT_EXIST
The product code does not exist. (Server-side).
Definition KeyzyTypes.h:206
@ NETWORK_PROXY_REQUIRED
HTTP 407: the network requires an authenticated proxy. Ask the user to contact their IT department to...
Definition KeyzyTypes.h:246
@ SKU_NOT_EXIST
The SKU does not exist. (Server-side).
Definition KeyzyTypes.h:209
@ NAME_OR_EMAIL_VALIDATION
Definition KeyzyTypes.h:234
@ NETWORK_DNS_FAILED
The address of the KEYZY server could not be resolved. Likely no internet connection,...
Definition KeyzyTypes.h:242
@ EMAIL_VALIDATION
The email parameter failed validation. Rejected server-side (HTTP 422) or client-side (empty email in...
Definition KeyzyTypes.h:232
@ UPGRADE_LICENSE_DOES_NOT_MATCH
The target license is not a valid upgrade path for the current license. (Server-side).
Definition KeyzyTypes.h:227
@ PRODUCT_CODE_VALIDATION
The product_code parameter failed validation (HTTP 422). (Server-side).
Definition KeyzyTypes.h:230
@ CURRENT_LICENSE_DOES_NOT_EXIST
During an upgrade, the source (current) license serial does not exist on the KEYZY servers....
Definition KeyzyTypes.h:225
@ TRIAL_LICENSE_EXPIRED
The server-side trial license has expired. (Distinct from EXPIRED, which is a local trial check....
Definition KeyzyTypes.h:216
@ CONNECTION_ERROR
Network or firewall error (umbrella). Returned when the connection fails at the network layer and no ...
Definition KeyzyTypes.h:222
@ LICENSE_NOT_EXIST_NOT_ASSIGNED_DEALER_ALREADY_DEPOSITED
Register-offline-distributed-license flow: the license does not exist, is not assigned to a dealer,...
Definition KeyzyTypes.h:235
@ PRODUCT_NOT_EXIST_FOR_USER
The product code does not exist. (Server-side).
Definition KeyzyTypes.h:207
@ NOT_AUTHORIZED
The appId / apiKey pair is wrong or not authorized. (Server-side).
Definition KeyzyTypes.h:204
@ NETWORK_TLS_FAILED
TLS handshake failed: corporate SSL inspection, MITM or a wrong system clock. Ask the user to check t...
Definition KeyzyTypes.h:245
@ SUBSCRIPTION_LICENSE_EXPIRED
The subscription license has expired (its end date has passed). (Server-side).
Definition KeyzyTypes.h:214