Referral SaaSquatch Help Center

Signed Requests provide a layer of security for the squatch.js javascript library to validate that the data we receive originated from your servers.

We recommend that all programs use Signed Requests to secure their client-side code.

When to Use Signed Requests

Certain referral program functionality is limited based on they type of referral program you have and the state of the Signed Requests setting.

The follow charts outline the security requirements for different program types and Signed Request settings.

API Programs

For referral programs configured as "API-only":

Signed Requests ON Signed Requests OFF
payment_provider_id included Checksum/JWT Required No Checksum/JWT
payment_provider_id null Checksum/JWT Required No Checksum/JWT

Payment Provider Programs

For referral programs configured for one of our Payment Provider Integrations:

Signed Requests ON Signed Requests OFF
payment_provider_id included Checksum/JWT Required No Checksum/JWT
payment_provider_id null Checksum/JWT Required Checksum/JWT Required

Changing Signed Request Settings

How do I turn on Signed Requests?

  • Signed Requests are turned on by default for API integrations.

Signed Requests can't be turn on manually. Signed Requests are automatically turned back on when our system receives a correctly Signed Request as part of a squatch.js init call.

How do I turn off Signed Requests?

We highly recommend using Signed Requests to reduce your referral programs exposure to a man-in-the-middle security vulnerability. With Signed Requests turned off more attention should be paid to your incoming referrals. We recommend keeping a close watch on incoming referrals and familiarize yourself with how our referral Security Management System functions.

Signed Requests can be turned off on the install page of your Referral SaaSquatch Portal.

turn signed requests on and off

How do I use signed requests?

A signed request uses either a cryptographic signature (checksum) or a JSON Web Token (JWT).

To use signed requests, your server must generate a JWT or checksum using your tenant's API key, and pass that to the squatch.js init function.

JWT

The JWT will be used to sign the data that you plan to submit to Referral SaaSquatch.

Building the JWT

The JWT payload is built using the JSON object of the squatch.js init parameters:

Note: Make sure ignore client-only parameters like mode

{
  "tenant_alias": "test_aaaexampleaaa",
  "account_id": "a5678",
  "payment_provider_id": null,
  "user_id": "u1234",
  "email": "joe.tester@example.com",
  "first_name": "Joe",
  "last_name": "Tester",
}

The process for building the JWT is outlined on our JSON Web Tokens page.

Checksum

How do I generate a checksum?

The param checksum is computed using a HMAC-SHA2 algorithm. The signed value is a concatenated string assembled from the squatch.js init parameter map. As a simple convention, the values are concatenated based on an alphabetical ordering of the parameter names. This will become more clear in an example below. The final piece missing is the HMAC algorithm’s shared secret: your account’s API key.

Don't forget! You have a both a live API key and a test API key.

Example: Generating a Checksum

To start using secure requests, you simply need to add a checksum. For example, here is a JSON object of the parameters to be signed:

{
    "tenant_alias": "test_aaaexampleaaa",
    "account_id": "a5678",
    "payment_provider_id": null,
    "user_id": "u1234",
    "email": "joe.tester@example.com",
    "first_name": "Joe",
    "last_name": "Tester",
    "mode": "EMBED",
    "locale": "en_US"
}
  1. Ignore client-only parameters that don't need to be signed. The mode, locale parameters should be ignored.

    {
      "tenant_alias": "test_aaaexampleaaa",
      "account_id": "a5678",
      "payment_provider_id": null,
      "user_id": "u1234",
      "email": "joe.tester@example.com",
      "first_name": "Joe",
      "last_name": "Tester",
      //"mode": "EMBED",
      //"locale": "en_US"
    }
    
  2. Sort your parameters according to the alphabetical order of their keys. Notice how account_id is now first and user_id is now last.

    {
      "account_id": "a5678", // <-- "a" is sorted to first
      "email": "joe.tester@example.com",
      "first_name": "Joe",
      "last_name": "Tester",
      "payment_provider_id": null,
      "tenant_alias": "test_aaaexampleaaa",
      "user_id": "u1234" // <-- "u" is sorted to last
    }
    
  3. Concatenate the sorted values. Starting with an empty string, iterate through all the parameters that you sorted and append each parameter's value to the end of a string. Notice how "a5678", the value for account_id, is at the start, and "u1234", the value for user_id, is at the end. Also, any optional parameters or null parameters can be omitted. In this example payment_provider_id is set to null and isn't included in the concatenated string.

    a5678joe.tester@example.comJoeTestertest_aaaexampleaaau1234
    ^^^ the value for accountId is first
  4. Sign the string using your API key to compute a HMAC-SHA2 checksum. In the code below we use an example API key: TEST_HGO8125ANDFH152HSAS15

    using System.Security.Cryptography;
    
    private string CreateToken(string message, string secret)
        {
        var encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(secret);
        byte[] messageBytes = encoding.GetBytes(message);
        using (var hmacsha256 = new HMACSHA256(keyByte))
        {
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            return Convert.ToBase64String(hashmessage);
        }
    }
    require 'openssl'
    require base64'
    
    hash = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', 'TEST_HGO8125ANDFH152HSAS15', 'a5678joe.tester@example.comJoeTestertest_aaaexampleaaau1234'))
    import java.security.SignatureException;
    
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    
    public static String calculateHMACSHA256(String data, String secretKey) throws java.security.SignatureException {
        String result;
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec key = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
            mac.init(key);
            byte[] authentication = mac.doFinal(data.getBytes());
            result = new String(org.apache.commons.codec.binary.Base64.encodeBase64(authentication));
    
        } catch (Exception e) {
            throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
        }
        return result;
    }
    base64_encode(hash_hmac('sha256','a5678joe.tester@example.comJoeTestertest_aaaexampleaaau1234', 'TEST_HGO8125ANDFH152HSAS15', true))
    import hashlib
    import hmac
    import base64
    
    message = bytes('a5678joe.tester@example.comJoeTestertest_aaaexampleaaau1234').encode('utf-8')
    secret = bytes('TEST_HGO8125ANDFH152HSAS15').encode('utf-8')
    base64.standard_b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest())

  5. Include the checksum in your javascript initialization call. Secure mode is enabled for an account as soon as we receive your first valid signed request. Once enabled, non-signed requests will no longer be accepted for that account.

    
    _sqh.push(['init', {
      tenant_alias: 'test_aaaexampleaaa',
      account_id: 'a5678',
      payment_provider_id: null,
      user_id: 'u1234',
      email: 'joe.tester@example.com',
      first_name: 'Joe',
      last_name: 'Tester'
      checksum: 'TFs5pf1zQUgaerOVvLSIiCfrty/GXHdXU5AK5rCmbYU=' // <-- Add the checksum to your init call
    }]);

Looking for something special?

Still couldn't find it?