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.

Checkout licensing UI bug fixes

A maker provided us with some bug reports for the Checkout’s licensing UI.

We noticed we did not show the short label in the “License label” (where it says “Single Site”) when there was only one unit available. It was wrongly showing “Single Site License” causing inconsistency in the UI. We have fixed that.

We also noticed a broken UI in case the error message when entering a license key was long. Previously the “Try again?” button would try to appear in the same line, breaking the flow of the UI. We have improved that as well.

General SaaS improvements

We have various small and medium tweaks to our system to make it more useful for SaaS makers. The changes were made across the Developer Dashboard, the backend, and the User Dashboard. Please find the details below.

Decluttering the Developer Dashboard

We have removed or enhanced many things that do not pertain to SaaS products.

We improved the Plans configuration.

The Customization section was also simplified.

The Settings page also got a revamp.

The setup page also updated some inline documentation.

Removed License related information from the User Dashboard

Recently we pushed a change to allow SaaS products to decide whether to expose licenses to the users.

Following up, we’ve updated the User Dashboard to show or hide any license-related information depending on the configuration.

CCing payment emails to user billing address

Freemius sends various payment-related emails to the users. For example

  • When a new subscription is made.
  • When a renewal of a subscription happens.
  • When a refund is issued.

We have been sending the emails to the primary address of the user.

The users can also have a different “Billing Address” defined through the User Dashboard.

To make the user experience better, we are now CCing such emails to the billing email too. For example, if the address of the user is [email protected] and the billing email is set as [email protected], Freemius will now send payment-related emails to both addresses.

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.