Changelog

Welcome to the changelog section of Freemius, here you'll find our weekly technical update notes. You can subscribe to all posts via Newsletter or follow us on Twitter to stay updated.

API-related enhancements for Licenses and SaaS

We are pushing more enhancements in our system to cater to SaaS. Recently we looked deeply at our API and how SaaS makers can consume our API. In the process, we delivered the following enhancements.

Using product scope in API endpoint paths

We’ve been using and documenting our API endpoints as plugin scopes. The endpoint path usually looks like this:

  • v1/plugins/{plugin_id}/users.json
  • v1/stores/{store_id}/plugins/{plugin_id}/carts.json

While it makes sense for WP products, for general software, term product is more appropriate.

Therefore all our product-scoped endpoints can now be accessed with products instead of plugins. For examples:

  • v1/products/{product_id}/users.json
  • v1/stores/{store_id}/products/{product_id}/carts.json

For backward compatibility purposes, the plugins will keep on working. This is just a small change to make the terminology easier for SaaS makers.

Correcting public license activation endpoint

We realized we mistakenly published the license activation and deactivation endpoints under

  • v1/products/{product_id}/activate.json
  • /v1/products/{product_id}/deactivate.json

We fixed it by instead publishing under

  • v1/products/{product_id}/licenses/activate.json
  • v1/products/{product_id}/licenses/deactivate.json

The old endpoints are now deprecated and will be removed in the near future. We will also update our LiteSDK.

New public endpoint for license validation

To ease license validation for software makers, we have introduced a new endpoint.

/v1/products/{product_id}/installs/{install_id}/license.json (public)

It requires the following parameters:

  • uid – The UID of the install which was used during the license activation.
  • license_key – The license key that was used to activate the install.

On a GET request, the endpoint will give back an license entity with details like expiration date, whether it is canceled etc.

You can read the previous changelog to under more about the license activation system. A proper documentation will be published soon.

Consistent parameter naming

We realized the endpoints responsible for creating licenses were using a request parameter named is_blocking although the license entity itself has the property is_block_features. This property determines whether all “premium” features of a product should be blocked when the license expires.

To make it consistent we have introduced a backward-compatible change in the API endpoints to accept is_block_features. The following endpoints are affected

  • /v1/products/{product_id}/installs/{install_id}/plans/{plan_id}/pricing/{pricing_id}/licenses.json
  • /v1/products/{product_id}/plans/{plan_id}/pricing/{pricing_id}/licenses.json

The endpoints are particularly useful when creating licenses for migrated products or from SaaS.

EU Finland VAT updates

Being a Merchant of Record (MoR), we at Freemius handle VAT and Sales tax for you. This includes the complexities of handling the collection and submission of taxes and tracking and updating tax rate changes.

Finland has increased the VAT rate from 24% to 25.5% starting September 2024. In response, we have also updated our system. All existing subscriptions will also be updated accordingly.

The buyers can of course enter their VAT number to get an exemption.

You can read our blog to learn how Freemius handles taxes.

New Checkout Feature for SaaS – Readonly user mode + Bug fix

This week’s deployment brings enhancements to the Freemius Checkout.

Read-only user mode – aimed for SaaS integrations

This is yet another push to make our Freemius platform more friendly for SaaS integrations. For SaaS, we understand most solutions would have their own user system. When loading the Checkout you can already populate the fields with the following parameters.

  • user_firstname – The first name of the user.
  • user_lastname – The last name of the user.
  • user_email – The email address of the user.
Freemius Checkout with prefilled user data

However, the user could still change their information if they wanted to from the checkout. This could make it difficult for SaaS products to consume webhook events and find the right user.

To solve this, we have introduced a new parameter readonly_user.

Freemius checkout with readonly user data

When set to true the fields will not let the user edit the information anymore. It works for both JS integration as well as standalone mode (when the checkout is opened directly).

Bug fix in success dialog

We discovered that the ‘support’ email address was mistakenly shown as the sender in the thank you dialog after a purchase. Emails should be sent from the ‘system’ email you’ve configured. This bug has now been fixed.

You can configure the email addresses on the ‘Emails’ page of your product or store.

Miscellaneous Developer Dashboard enhancements and bug fixes

This week’s deployment comes with the following misc enhancements and bug fixes.

  • We resolved an issue where the payment refund form sometimes failed to honor the ‘Cancel subscription’ checkbox.
  • We enhanced overall responsiveness and optimized cross-platform font stacks across various UIs and pages.
  • For the affiliate system, we are now blocking the rejection of referrals already included in the payout calculation. We realized rejecting them after payout calculation is mostly a mistake. But if you have any reason to do it, please get in touch with our support.

New feature: Added authentication support for custom webhook events

We understand that custom webhook events are the cornerstone for integrating Freemius with any SaaS product. To make it even easier to consume webhooks sent from Freemius, we have introduced support for direct authentication using an HTTP signature.

From now on every webhook request that Freemius sends, will carry a HTTP_X_SIGNATURE header, which you can use to validate the request. Previously we’ve been asking to use the event_id and re-retrieve the event from Freemius API to consume it. But with this update, you can skip the extra step and after authentication, you can directly consume the webhook request.

Example usage

The HTTP_X_SIGNATURE header will have the sha256 of the request payload encrypted with the secret key of your product.

Go to the Settings page of the product from the Developer Dashboard to get the secret key. Once you have it, you have to calculate the hmac hash with the sha256 algorithm of the RAW HTTP payload using the secret key as the encryption key.

<?php
    // Retrieve the request's body payload.
    $input     = @file_get_contents("php://input");
    $hash      = hash_hmac('sha256', $input, '<PRODUCT_SECRET_KEY>');
    $signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';

    if ( ! hash_equals($hash, $signature))
    {
        // Invalid signature, don't expose any data to attackers.
        http_response_code(200);
        exit;
    }

    $event_json = json_decode($input);
    // Handle the event JSON as needed

The above shows how the hash_hmac can be used to calculate the sha256 of the request payload with your product’s secret key with PHP.

Please note that getting the raw body is important here, instead of decoding the JSON and then encoding again, to avoid issues with JSON stringification. Here’s another example of a nodejs server using express.

const crypto = require('crypto');
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

app.post('/webhook', bodyParser.raw({ type: '*/*' }), (req, res) => {
    const input = req.body.toString('utf8');
    const secret = '<PRODUCT_SECRET_KEY>';
    const hash = crypto.createHmac('sha256', secret).update(input).digest('hex');
    const signature = req.headers['x-signature'] || '';

    if (hash !== signature) {
        // Invalid signature, don't expose any data to attackers.
        res.status(200).send();
        return;
    }

    const eventJson = JSON.parse(input);
    // Handle the event JSON as needed
});

app.listen(3000, () => {
    console.log('Server is listening on port 3000');
});

We hope you find this feature useful when integrating your product with Freemius. You can read here about all the events we have available. For any queries please feel free to head to our support.

Checkout phase2 final rollout with some bug fixes

Following our rollout schedule, we’ve made the new Checkout design the default in production. From today onwards the new checkout design will show up, regardless of the status of the CSS migration.

If you aren’t using custom CSS or have already migrated your custom CSS, then you are all set. Otherwise, we request you to do that as soon as possible. Please read our changelog and documentation for help with the CSS migration.

If for some reason you still want to use the legacy checkout, you can use the JavaScript parameter checkout_style: 'legacy'. But please note, you have until September 29th, 2024, after which the legacy Checkout will be completely removed.

Enabling the monthly switch by default

While introducing the upsell concept, we made the annual/monthly upsell switch hidden when the Checkout already loads in the “annual” billing cycle.

Following our maker’s feedback and discussing some cases, we understand it can be a bit confusing for some specific cases. Especially when:

  1. The checkout is loaded from the WordPress SDK – Since users can miss the billing cycle when clicking some promotional notice coming from the plugin/theme itself.
  2. The checkout is in license renewal/upgrade mode – A user may want to change the billing cycle from annual to monthly or vice-versa.

Hence for the two cases, we are now showing the switch by default. Additionally, you can always use the show_monthly_switch parameter and choose to show it all the time.

You can find more about all the new configuration options here.

Other bug fixes

  • Fixed the positioning of the exit intent modal.
  • Fixed refund policy UI showing up incorrectly in some edge cases.

Introducing new feature to export Payments

Following up on our data liberation project, we are glad to announce the immediate availability of payment exports from the Developer Dashboard.

Go to the “Payments” page and you will see the “Download” button. You can choose to download all payments or just the ones showing up in the UI.

While Freemius offers intensive reports and analytics tools, the export feature is beneficial for understanding the data and doing your custom reporting. Please stay tuned while we introduce such export options for more assets.

Developer Dashboard bug fixes

This week brings a few minor bug fixes to our Developer Dashboard:

  • We noticed a bug on the product’s settings page where the ‘Paid version slug‘ field was not showing in some cases. This bug has now been fixed.
  • We fixed a bug in the relative date/time UI that was showing incorrect values in the Payments and Subscription tables.

The new phase2 Checkout is officially live

We are glad to announce the new phase2 Checkout is officially in production starting today.

We’ve been doing a gradual rollout for quite some time and the time has finally come for the first production rollout.

Freemius Checkout Phase2 - Release Candidate

If you do not use custom CSS to modify the Checkout, then the new Checkout will start showing up for you without any changes.

However, if you are using custom CSS, then you have until August 18th to migrate your CSS. You can read about the features, migration tips, and full rollout schedule here.

Frequently Asked Questions (FAQ)

I have migrated CSS and put a new URL under Customization, but the new Checkout is still not showing up, why?

Freemius Developer Dashboard Checkout Customization for disabling the legacy Checkout

Please note that after you’ve migrated your CSS, you will need to clear the field of the “(Legacy) Custom Checkout CSS file” under the “Customization” section of the “Plans” page. Only then will the new checkout start showing up everywhere (on the Customer Portal and inside the WP SDK).

Can I have more time to migrate my CSS?

From August 18th, we will set the new Checkout as default. However, you can force-load the old checkout with checkout_style: 'legacy' in the JS configuration. Please note that you will have until September 29th, after which we will completely remove the legacy Checkout. Also, you cannot force the legacy Checkout on the Customer Portal and inside the WP SDK.

How can I have the option in the Checkout to switch to a monthly billing cycle?

We removed the billing cycle UI from the Checkout and have introduced the “Upsells” concept. Therefore, when the Checkout is loaded with an Annual billing cycle, we do not show the UI to downgrade to a Monthly billing cycle.

However, you can use the configuration option show_monthly_switch and set it to true to show it anyway.

What are the new configurations available to tweak the Checkout UI

You can find them here inside our JavaScript SDK documentation.

Freemius for SaaS – Ability to expose license keys to buyers

In yet another improvement for “Freemius for SaaS”, we are pushing the ability to expose license keys to the buyers. During our previous update, we removed the license keys for SaaS products. We thought license keys were not relevant for SaaS. However, after having some discussions with our makers, we understood, that for some SaaS it is preferred to expose license keys. It becomes handy when a subscription is canceled mid-term and you want to keep the features active until the license itself expires.

So in this iteration, we are giving the option to show license keys to customers for SaaS products.

Go to the “Settings” page from your Developer Dashboard. You will find a new section labeled “License Keys”. From there you can enable or disable the visibility of license keys for your customers.

If this is disabled, then none of the payments or subscription emails will have the license key-related information. By default, this setting is disabled for SaaS products. If you want your customers to see the license keys, then please enable this configuration explicitly.

Checkout Spanish translation out of beta

We are glad to announce that the Spanish translation of our Checkout is out of beta.

Long ago we introduced translation capability to our Checkout. Displaying the checkout in the buyer’s local language significantly boosts the conversion rate. At that time we used AI to generate the following translations for the Checkout:

  • Spanish
  • German
  • French
  • Italian
  • Dutch

But we marked the translations as “beta” as those were not proof-read or approved by professionals.

Now we have started to hire professional translators to finalize the translation and the first language to go through the process is Spanish.

Passing the language parameter with an auto value to the Checkout ensures that if your buyers are from Spanish-speaking regions, the Checkout will automatically load in Spanish. You can also pass static values like es to the language parameter. See here for an example. When the Checkout is loaded in a different language or when the language parameter is present, we show a dropdown in the footer of the Checkout to change the language.

More information about it can be found in our documentation (search for “language”). Very soon we will finalize more languages. Please note that only the languages for the new phase2 Checkout are being worked upon. Just a reminder on August 4th, we will switch the phase2 Checkout as default. You can read more about it here.

Misc enhancements and various bug fixes

This week we are also deploying some enhancements and bug fixes for the Developer Dashboard.

Improved “Custom localhost URLs” UI from store

When viewing a user from a Store, we have improved the Custom localhost URLs section to include instructions on how to change it from the relevant product.

Freemius stores page "Custom localhost URLs" section

Previously we allowed changing it directly for the product associated with the latest license of the user. Since a user can have licenses for multiple products from a store, it created some confusion. To avoid such confusion, we have improved the UI to tell explicitly what action needs to be taken and for what product.

Bug fix for the new product form

We noticed a bug in the “New Product Form” when it was loaded directly due to some race condition. We have deployed a fix for the same.

Analytics bug fix

We noticed that for some makers, the store-level analytics were generating some API errors. We identified the root cause and have deployed a fix.

Minor Checkout enhancement

We noticed some redundant API requests being made from our Checkout when calculating taxes. We have pushed a fix to make the system more efficient while making network requests.

New action to copy license renewal link with UI/UX refresh

We made some noticeable UI/UX overhauls to the Licenses page in your Developer Dashboard. We wanted to add a new action item in the table and while doing so, we noticed that over the time, the table UI has gotten bloated with many actions.

So we took the opportunity to make some refreshing changes.

Refreshed Licenses table with consolidated actions

We replaced some old designs and components inside the licenses table.

Freemius Developer Dashboard Licenses table page

For example, we removed some space between the columns and used a new component to display the license key with the copy and reveal button.

Grouped actions button inside Freemius Developer Dashboard's License page

We grouped all available actions, which are non-frequent, at the end of the column inside a dropdown menu.

We hope this change will help you make the most use of the table, by showing the most important things at first.

New action to copy renewal link

Sometimes customers ask our makers to share some links from where they can renew expired licenses or update billing methods. We do provide a Customer Portal from where your customers can self-serve. But sometimes sharing a direct link helps in quicker conversion.

Copy renewal link action inside Licenses page of Freemius Developer Dashboard

To help you quickly generate such links, we have added a new action item beside every license row. Simply click on the “Copy Renewal Link” button and share the link with your customer. This will open the checkout with the license key prefilled from where they can update the renewal mechanism.

Load more