SaaS Code Examples

Introduction

This guide is here to help you implement key events in your SaaS platform using Kissmetrics. From user sign ups to tracking revenue, you’ll find step-by-step examples to streamline your tracking setup.

Events flow

Before revenue comes into play, events like user sign ups, demo requests, and trial starts we recommend tracking using our Javascript APIs on the client side. This ensures seamless integration with our base snippet and identity handling.

However, when it comes to revenue events like subscriptions, upgrades, and cancellations, server side tracking is recommended. Server side tracking ensures that your data is accurate and not affected by browser issues or network interruptions.

Getting started - environment setup

The first step before implementing custom events is to load our Javascript snippet in the <head> section on all of the pages of your website or application. You can easily locate your API KEY and snippet under the Product Settings in your account.

<script type="text/javascript">var _kmq = _kmq || [];
var _kmk = _kmk || 'YOUR_API_KEY';
function _kms(u){
  setTimeout(function(){
    var d = document, f = d.getElementsByTagName('script')[0],
    s = d.createElement('script');
    s.type = 'text/javascript'; s.async = true; s.src = u;
    f.parentNode.insertBefore(s, f);
  }, 1);
}
_kms('//i.kissmetrics.io/i.js');
_kms('//scripts.kissmetrics.io/' + _kmk + '.2.js');
</script>

With the snippet installed we will be tracking all of our out of the box events and properties like Visited site, Ad campaign hit, Page View. We talk more about those in our SaaS Essentials guide.

Tracking Custom Info

With the snippet installed, business questions defined, and data schema structured, you can proceed to implementing custom events.

🚧

Please note that the code snippets for custom event tracking are examples meant to show case the logic behind trigger definition, dynamic property handling, identification, and sending the event to us. Depending on the business, you may have more properties, less properties, different triggers, error, or dynamic property value handling.

Requested demo

This event is triggered when a user requests a demo via a button click

// Event listener for demo request button
document.getElementById('requestDemoButton').addEventListener('click', function() {
  try {
    var userEmail = getUserEmail() || 'Unknown'; // string
    var requestPage = window.location.pathname; // string

    _kmq.push(['record', 'Requested demo', {
      'Email': userEmail, // string
      'Requested at': requestPage // string
    }]);
  } catch (error) {
    console.error('Error tracking Requested demo event:', error);
  }
});

Signed up

This event is triggered on signup form submission. In addition to firing the event, this is a place to call identify to get the user identified (known at this stage) and connect their anonymous activity with the following server side events.

// Utility function to validate email address
function isValidEmail(email) {
  const emailRegex = /^[^@\s]+@[^@\s]+\.[^@\s]+$/; // General email pattern
  const disallowedDomains = ['example.com', 'test.com'];
  const domain = email.split('@')[1];
  return emailRegex.test(email) && !disallowedDomains.includes(domain);
}

// Event listener for signup form submission
document.getElementById('signupForm').addEventListener('submit', function(event) {
  event.preventDefault();

  try {
    var firstName = document.getElementById('firstName').value || 'N/A'; // string
    var lastName = document.getElementById('lastName').value || 'N/A'; // string
    var userEmail = document.getElementById('email').value; // string

    if (!userEmail || !isValidEmail(userEmail)) {
      alert('Please provide a valid email address.');
      return;
    }
      // Identify the user with their email
    _kmq.push(['identify', userEmail]);
    
    // Sending Signed up event to Kissmetrics
    _kmq.push(['record', 'Signed up', {
      'First name': firstName, // string
      'Last name': lastName, // string
      'Email': userEmail // string
    }]);
  } catch (error) {
    console.error('Error tracking Signed up event:', error);
  }
});

Logged in

This event is triggered on the login form submission.

// Event listener for login form submission
document.getElementById('loginForm').addEventListener('submit', function(event) {
  event.preventDefault();

  try {
    var userEmail = getUserEmail(); // string
    var companyName = getCompanyName() || 'Unknown'; // string

    if (!userEmail || !isValidEmail(userEmail)) {
      alert('Please provide a valid email address.');
      return;
    }

    // Identify the user with their email
    _kmq.push(['identify', userEmail]);
    
    // Sending Logged in event to Kissmetrics
    _kmq.push(['record', 'Logged in', {
      'Email': userEmail, // string
      'Company name': companyName // string
    }]);
  } catch (error) {
    console.error('Error tracking Logged in event:', error);
  }
});

Trial started

This event is triggered when user initiates a trial.

// Event listener for trial start button
document.getElementById('startTrialButton').addEventListener('click', function() {
  try {
    var companyName = getCompanyName() || 'Unknown'; // string

    _kmq.push(['record', 'Trial started', {
      'Company name': companyName // string
    }]);
  } catch (error) {
    console.error('Error tracking Trial started event:', error);
  }
});

Subscription started

This event is triggered when a user starts a subscription. Server side tracking is recommend, but we are also listing the Javascript tracking example if you don't have a way to use any of the server side libraries.

// Event listener for subscription form submission
document.getElementById('subscriptionForm').addEventListener('submit', function(event) {
  event.preventDefault(); // Prevent form submission

  try {
    // Dynamic data retrieval or defaults
    const billingAmount = calculateBillingAmount() || 0; // numeric
    const subscriptionType = getSubscriptionType() || 'Unknown'; // string
    const paymentFrequency = getPaymentFrequency() || 'Unknown'; // string
    const newRevenue = billingAmount; // numeric
    const companyName = getCompanyName() || 'Unknown'; // string

    // Record the subscription started event with properties
    _kmq.push(['record', 'Subscription started', {
      'Subscription billing amount': billingAmount, // numeric
      'Subscription new revenue': newRevenue, // numeric
      'Subscription type': subscriptionType, // string
      'Subscription paid frequency': paymentFrequency, // string
      'Company name': companyName // string
    }]);
  } catch (error) {
    console.error('Error tracking Subscription started event:', error);
  }
});
<?php
$api_url = "https://trk.kissmetrics.io/e"; // API endpoint
$api_key = "YOUR_API_KEY"; // Replace with your Kissmetrics API key

function track_subscription_started($email, $billing_amount, $new_revenue, $type, $frequency, $company_name) {
    // Validate the email address
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        throw new Exception("Invalid email address.");
    }

    // Prepare event data
    $data = [
        '_k' => $api_key,
        '_p' => $email, // string: User's email
        '_n' => 'Subscription started', // string: Event name
        'Subscription billing amount' => $billing_amount, // numeric: Billing amount
        'Subscription new revenue' => $new_revenue, // numeric: Revenue generated
        'Subscription type' => $type, // string: Subscription type
        'Subscription paid frequency' => $frequency, // string: Payment frequency
        'Company name' => $company_name // string: Associated company
    ];

    // Set up the HTTP request
    $options = [
        'http' => [
            'header' => "Content-type: application/x-www-form-urlencoded\r\n",
            'method' => 'POST',
            'content' => http_build_query($data),
        ],
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($api_url, false, $context);

    if ($result === FALSE) {
        throw new Exception("Error tracking Subscription started.");
    }

    echo "Subscription started tracked successfully.";
}
?>

require 'net/http'
require 'uri'

API_URL = 'https://trk.kissmetrics.io/e'
API_KEY = 'YOUR_API_KEY' # Replace with your Kissmetrics API key

def track_subscription_started(email, billing_amount, new_revenue, type, frequency, company_name)
  # Validate email address
  raise 'Invalid email address.' if email.nil? || email.match(/test@/)

  # Prepare event data
  params = {
    '_k' => API_KEY,
    '_p' => email, # string: User's email
    '_n' => 'Subscription started', # string: Event name
    'Subscription billing amount' => billing_amount, # numeric: Billing amount
    'Subscription new revenue' => new_revenue, # numeric: Revenue generated
    'Subscription type' => type, # string: Subscription type
    'Subscription paid frequency' => frequency, # string: Payment frequency
    'Company name' => company_name # string: Associated company
  }

  # Send the HTTP request
  uri = URI.parse(API_URL)
  response = Net::HTTP.post_form(uri, params)

  # Check response
  raise "Error tracking event: #{response.body}" unless response.is_a?(Net::HTTPSuccess)

  puts 'Subscription started tracked successfully.'
end

You can repeat the same approach for other revenue related events like Subscription billed, Subscription cancelled, Subscription upgraded etc.

Sending user specific properties

You would want to send such properties to update the user subscription health and have an accurate canvas of your top populations that can be used as filters in reports.

// Function to update user-specific subscription properties
function updateUserSubscriptionProperties(subscriptionStatus, planType, payingFrequency) {
  try {
    // Ensure valid inputs with fallback defaults
    const status = subscriptionStatus || 'unknown'; // string: active, trial, canceled
    const plan = planType || 'unknown'; // string: silver, gold, enterprise
    const frequency = payingFrequency || 'unknown'; // string: monthly, annually, quarterly

    // Push properties to Kissmetrics
    _kmq.push(['set', {
      'Subscription Status': status, // string
      'Plan Type': plan, // string
      'Paying Frequency': frequency // string
    }]);

    console.log('Subscription properties updated successfully.');
  } catch (error) {
    console.error('Error updating subscription properties:', error);
  }
}

// Example usage
updateUserSubscriptionProperties('active', 'silver', 'monthly');

Troubleshooting

To further troubleshoot, you will need to use our Live Tool or your browser's developers tools to make sure the events and properties are coming in correctly.

Integrations

With your core implementation set, be sure to look at our Integrations section to see how you can advance your tracking by integrating with other tools like Mailchimp , Optimizely or VWO.

Contact us

We hope you found this guide helpful. Contact us with any questions at [email protected].