License Management Add-on for Larapen
Latest: v1.0.32 6 November 2026 22 releases
Back to product
  1. 1.0.32

    Latest
    • Security: buying a service plan (installation, management...) bound to a product no longer issues a license key for that product
    • Security: the license keys of a Cash on Delivery order are issued once its payment is recorded
    • Fixed: a malformed API call (a list instead of a key) is logged instead of causing an error
    • Fixed: with the Envato add-on 1.0.10, "Test connection" in the Envato settings of the Licenses add-on reads its token, now stored encrypted
    • Fixed: with the Gumroad add-on 1.1.13, "Test connection" in the Gumroad settings of the Licenses add-on reads its token, now stored encrypted
    • Security: the API key, the HMAC key, the webhook secret, the rate limit bypass token and the Envato and Gumroad tokens of the Licenses settings are now stored encrypted, also the ones already saved. Their values do not change, so API clients, webhook senders and issued keys keep working
    • Changed: the HMAC key and the Envato and Gumroad tokens are no longer sent back to the settings form. Leave their field blank to keep them. The API key, the webhook secret and the bypass token stay readable there, since they have to be copied to other systems or tools
    • Fixed: an empty HMAC key now falls back to APP_KEY for new HMAC-signed keys, as documented. It used to sign with an empty key
    • Improvements & Bugs fixed.
    • Fixed: the key button of a Shop product (Shop > Products) no longer refuses with "SKU already used" when the license product carrying the same SKU is listed on no Shop product (for example, one imported from Gumroad before the Shop product existed): it links that license product to the Shop product instead of creating another one. A license product already listed on another Shop product is still refused
    • Added: a licenses:link-shop-products command that restores these missing links in one go, with a --dry-run option listing them first. Until a Shop product is linked, the Licenses products list could show its image (found by the SKU) while the Shop products list showed it as linked to no license product
    • Updated: the Shop marketplace no longer issues a license key for an order whose buyer already received one from another add-on. With the Gumroad add-on, this is the case of an order paid on Gumroad when license keys are enabled on its Gumroad link and Gumroad generated the key of the sale: the buyer keeps that single key
    • Added: a 'Legacy Endpoint' settings tab holding the legacy endpoint configuration (moved from the API Endpoints tab), and banning rules of its own on the 'Banning Rules' tab: the two auto-ban switches, rate-limit thresholds counted on separate limiters so a client hammering the legacy endpoint does not consume the API budget, and the oracle-safe rejection response; every value follows the API one until it is set. The card is hidden while the legacy endpoint is off
    • Added: the oracle-safe rejection response carries an editable message per endpoint family; the legacy default tells the outdated client to update ('License verification could not be completed with this version of the software. For security reasons, please update your installation to the latest release.') while the non-legacy API keeps its neutral 'Request rejected.'
    • Added: the 'Never ban callers of the non-legacy API' option (Settings → Banning Rules), off by default: a call to 'verify', 'activate' or 'deactivate' is then never auto-banned, never rejected by a ban, and lifts any ban already recorded on the key, the domain or the IP it carries; the generated .htaccess ban rules are limited to the legacy endpoint path and the precheck gatekeeper skips the ban checks for the non-legacy endpoints
    • Added: the 'version' request parameter is accepted by the verify, activate and deactivate endpoints (and the legacy one) and recorded on the activation: the version of the app, add-on or theme the client runs, refreshed on every later call. It is shown on the activations pages and in the API log, and the activations search matches it, so an audit can tell which installs still run an outdated release (client apps that include the matching change send it; older clients leave it empty)
    • Added: a 'Generate' button in front of the 'Key' field of the license key create form: it fills the field right away with a unique key built in the 'Key Format' selected just below, so the key can be read, copied or regenerated before saving. Clicking it again replaces the current value, and leaving the field empty still generates the key on save as before
    • Updated: the '.htaccess Blocklist' settings tab is renamed 'Banning Rules' and moved right after 'API Configuration'. It gathers the rate-limit thresholds, auto-ban switches and rejection response of both endpoint families: an 'API Banning Rules' card (moved off the 'API Configuration' tab, which now keeps the API switch, the API key, the bypass token and the maintenance exemption) and a 'Legacy Endpoint Banning Rules' card, followed by IP banning, the non-legacy API ban exemption, the required request parameters and the .htaccess blocklist
    • Updated: searching the banned domains accepts a full URL pasted from a browser and finds the ban recorded on its domain
    • Updated: the 'Key Prefix' setting (Settings → Key Generation) is only shown while the 'Default Key Format' is 'Prefixed': the only format that uses it. The field keeps its slot in the row, so 'Default Max Activations' does not move, and the saved prefix is preserved while it is hidden
    • Fixed: the sample key shown beside each format name on the key forms had one group too few for the 'Alphanumeric' and 'Prefixed' formats, and the 'Prefixed' sample always showed 'LIC' instead of the prefix actually configured
    • Fixed: the customer detail page still labelled the marketplace badge 'Linked Provider', and the add-on described itself as 'provider-based': leftovers of the 1.0.13 rename of provider / store / channel to 'marketplace'
    • Added: a 'Group calls' switch on the API logs page folds the calls of one client action into a single entry per product: activating a paid add-on verifies the purchase code against the product's SKU, then its marketplace IDs, then its slug, which used to fill the log with up to four near-identical rows per attempt
    • Added: a grouped entry expands to the calls it folds, each naming what the client asked the product by ('SKU', 'Gumroad ID', 'Shop SKU', 'Slug'), with its own status, error and actions
    • Added: the verify endpoint returns a machine-readable 'error' code next to its message ('key_not_found', 'product_mismatch', 'license_inactive', 'license_expired')
    • Added: a key is only looked up on the external marketplaces whose key format it could have been issued by: an Envato purchase code is a UUID, a Gumroad-issued key is four groups of eight hex characters. Verifying an unknown key no longer sweeps the Gumroad API once per tracked product for a certain 'not found', which is where most of the wait came from (config 'marketplace_key_format_gate' restores the old behavior)
    • Fixed: a key an external marketplace knows for another product was answered as 'License key not found.', indistinguishable from a key that exists nowhere; it is now reported as a product mismatch, so a client knows an unknown key is final and stops asking about the same code once instead of once per identifier
    • Updated: the slug of a license product listed on Envato is no longer read-only in the product edit form: it can be renamed like any other product's
    • Added: renaming a product's slug keeps the former slug as a slug alias (and drops the new slug from the aliases), so client apps and marketplace purchases still matching the old slug keep resolving the product
    • ACTION REQUIRED: update the envato and gumroad add-ons to their matching releases (their purchase flows now match a product by its slug aliases too)
    • Fixed: the 'Create / Update license product' button of a shop product showed 'Create' and 'not linked' even when the product was already listed on a license product (it still read the 'shop_products.license_product_id' column dropped in 1.0.13)
    • Fixed: a license product created automatically from a key verified by Envato or Gumroad no longer takes the item ID as its SKU: the ID is recorded as the product's listing on that marketplace, linked to the imported catalog row when there is one
    • Updated: the user and developer guides describe marketplaces, listings, the SKU, shared slug aliases, the 1.0.13 update order, and what the API accepts in the 'product' parameter (SKU, alias, marketplace ID or slug, and what happens when it is missing)
    • Added: the legacy verification endpoint has a master switch on the 'API Endpoints' tab, off by default; while it is off the route is not registered, its dedicated domain is not restricted and its path is left out of the generated .htaccess / precheck rules (an install already answering on a legacy path keeps it enabled across this update)
    • Added: the legacy verification endpoint is configurable from the admin: its path, its dedicated API domain and the three query parameter names old clients send are now settings on the 'API Endpoints' tab instead of LICENSES_LEGACY_* env variables
    • Updated: the 'API Endpoints' reference lists every endpoint with its HTTP method, its full copyable URL, whether it expects the X-Api-Key header and a per-parameter required/optional table; the legacy entry follows the fields being edited live
    • Added: the 'licenses_marketplaces' table: the marketplaces license keys come from (the in-site Shop, Envato Market and Gumroad as stores; Manual and Webhook as internal sources), seeded on update
    • Added: the 'licenses_product_marketplace' table, where each license product is sold, one row per marketplace listing with the identifiers the marketplace knows the product by (Envato item ID, Gumroad product ID and permalinks, shop product SKU) and the local catalog row. It replaces the 'shop_products.license_product_id' column (dropped), the license-product rows of 'envato_item_links' / 'gumroad_product_links' and the store identifiers kept in the product metadata; every existing link is copied into it during this update
    • Updated: 'marketplace' is the one word for what used to be called provider, store or sales channel: the settings are now 'licenses_manual_marketplace_enabled', 'licenses_shop_marketplace_enabled', 'licenses_envato_marketplace_enabled' and 'licenses_gumroad_marketplace_enabled' (renamed in place); the 'provider', 'provider_reference' and 'provider_data' columns of the keys, webhook logs and doctor acknowledgements are renamed 'marketplace', 'marketplace_reference' and 'marketplace_data'; the webhook endpoint is 'POST /api/licenses/callback/{marketplace}' (same URLs); the admin filters and the registration form send 'marketplace' instead of 'provider'
    • Updated: the SKU is the product's own identifier: what its shop product and the add-on / theme manifests carry, and what client apps now send first. A SKU still holding an Envato item ID or a Gumroad product ID is cleared, and every product without a SKU receives its slug during this update
    • Updated: a slug alias may be shared by several license products: two product lines shipping an add-on under the same directory name ('paypal' for Larapen and for LaraClassifier) can both carry that name, so client apps that only send the name verify a key of either product instead of failing with 'License key does not belong to this product'
    • Updated: the product check of the verify endpoint matches the SKU first, then the aliases, the marketplace identifiers, and the primary slug last
    • Updated: the product form's marketplace sections write the listings table and gain a Shop section (pick the shop product, or type its SKU); the Envato and Gumroad importers record listings there and never write the store ID into the SKU
    • Added: the SKU of a license product and of the shop product it is listed as are kept identical: an empty side is filled from the other one on save, and the 'Create / Update license product' button of the shop refuses to run while the two SKUs differ, or when the shop SKU is already held by another license product
    • Added: a shop button before the SKU field of the product create / edit forms, shown while the Shop add-on is active, opens a searchable list of the shop products and copies the picked product's SKU into the field
    • Fixed: the shop product search of the product form failed on databases using a table prefix
    • Added: 'licenses:doctor' reports a shop product whose SKU differs from its license product's ('sku_mismatch'), a sold product without a SKU ('sku_missing') and a listing whose catalog row no longer exists
    • ACTION REQUIRED: update the envato and gumroad add-ons to their matching releases (their link pages now read and write the listings table)