Authentication JavaScript

Introduction

The integration between Zinrelo and your website is essential for a smooth flow of information. The JavaScript integration will initialize the Zinrelo platform on your website and authenticate customers into your program. 

The integration snippet should go up on all the pages of your website. You can add it to the header or footer section of your website template.

The basic integration and authentication snippet serves two purposes:

  • Member Enrollment: It passes the information of the member logged-in on your website to Zinrelo so that Zinrelo can authenticate the member, initiate a session and log the user into the loyalty program.
  • Load the loyalty dashboard and other resources: This snippet also deploys different resources like the all.js javascript file and other scripts necessary to enable the loyalty dashboard and functions required for the loyalty program.

Why should I use new JavaScript snippet?

The new JavaScript accepts custom member attributes. You can now record browsing data such as the last website visit timestamp and visit duration and use these attributes in loyalty program rules. In addition to this, this snippet is email independent; you can pass a unique identifier for the member object such as "Customer ID", "GUID", "Email Address", "Phone Number."

How to include the snippet?

Add the snippet into the HEAD section of your website page template so that this snippet appears on ALL pages of your website. The JavaScript snippet looks like this:

<script type="text/javascript"> 
window._zrl = window._zrl || [];

/* Merchant needs to generate JWT token using API key from the backend. The sample code in Python and Java to generate the JWT is mentioned below in this article  */ 
let jwt_token = get_jwt_token() /* Fetch JWT token from backend */

let init_data = {
        'partner_id' : 'your_partner_id',         
        /*REQUIRED: Partner ID*/
        'jwt_token' : 'your-customer-jwt-token',          
        /*REQUIRED: jwt_token*/
        'version' : 'v2',          
        /*REQUIRED: version*/
        'server' : 'https://app.zinrelo.com',          
        /*REQUIRED: server */
}
 _zrl.push( [ 'init' , init_data ] ); 
</script> 
<script src="//cdn.zinrelo.com/js/all.js" type="text/javascript"></script>

For a guest/non-logged in user, you can simply pass the 'partner_id' and pass an empty string ('') for jwt_token.

The backend code will look like this:

import jwt

secret = 'your-api-key'
user_info = { 
     
     'member_id' : 'Unique-ID',         
     # REQUIRED: Pass members unique identifier in this field when user is Logged in. For Non-Logged in users, pass an empty string ('')
     'email_address' : '[email protected]',   
     # Optional: Please provide the email address of the member to whom you would like to send the loyalty email notifications.
     'first_name' : 'First Name',
     # Optional 
     'last_name' : 'Last Name',    
     # Optional 
     'member_status' : 'active',    
     # Optional 
     'member_tags' : ['Frequent buyer', 'Loyal'],    
     # Optional 
     'phone_number' : '+1-7203332525',    
     # Optional 
     'birthdate' : '12/06/2020',  
     # Optional (Format : <MM/DD/YYYY HH:MM:SS>)
     'anniversary_date' : '12/06/2020', 
     # Optional (Format : <MM/DD/YYYY HH:MM:SS>)
     'preferred_language': 'english', 
     # Optional: If you have a multi-language store, refer SUPPORTED_LANGUAGES_LIST = ['english', 'french', 'italian', 'german', 'spanish', 'custom language one', 'custom language two']
     'twitter_handle':'www.twitter.com/john',   
     # Optional 
     'instagram_handle':'www.instagram.com/john',   
     # Optional 
     'referrer_code':'JOH3TNLY',   
     # Optional 
     'current_tier_id':'zrl_silver', 
     # Optional: Pass valid tier_id.
     'custom_attributes': {
         "City_Name": "Paris", 
         # String field
         "Age_In_Years": 37, 
         # Integer field
         "last_visit_date": "03/16/2022 00:00:00", 
         # Date field (Format: < MM/DD/YYYY HH:MM:SS>)
         "visited_cities": ["Paris", "London"] 
         # List field
     } 
     # Optional: To create custom_attributes, contact your account manager at [email protected].   
     'address': {
        'line1': '530 Lytton Ave',  
        'line2': 'Suite #200', 
        'city': 'Palo Alto', 
        'state': 'CA', 
        'country': 'US', 
        'postal_code': '94301', 
    },
    # (optional)   
    'exp': '', 
   # Mandatory: Epoch timestamp (seconds), after which the token will expire
}

encoded_jwt = jwt.encode(user_info, secret, algorithm='HS256')
print(encoded_jwt)

package com.example.jwt;

import io.jsonwebtoken.*;
import java.util.*;
import org.json.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.*;


public class JWTApplication {

	public static void main(String[] args) throws IOException{
		String jwtToken="";
		String secret = "your_api_key";
		Claims claims = Jwts.claims();
		Duration duration = Duration.from(ChronoUnit.HOURS.getDuration());
		long epoch = System.currentTimeMillis()/1000;
		long validityInSeconds = 3600;
		long exp = epoch + validityInSeconds;
		String userInfo = "{\"member_id\" : \"Unique-ID\","
			+ "\"email_address\" : \"[email protected]\","
			+ "\"first_name\" : \"First Name\","
			+ "\"last_name\" : \"Last Name\","
      + "\"member_status\" : \"active\","
			+ "\"member_tags\" : [\"Frequent buyer\", \"Loyal\"],"
			+ "\"phone_number\" : \"+1-7203332525\","
			+ "\"birthdate\" : \"12/06/2020\","
			+ "\"anniversary_date\" : \"12/06/2020\","
			+ "\"preferred_language\": \"english\"," 
			+ "\"twitter_handle\":\"www.twitter.com/john\","
			+ "\"instagram_handle\":\"www.instagram.com/john\","
			+ "\"referrer_code\":\"JOH3TNLY\","
			+ "\"current_tier_id\":\"zrl_silver\","
			+ "\"custom_attributes\": {"
			+ "\"City_Name\": \"Paris\","
			+ "\"Marital_Status\": \"Married\","
			+ "\"Income_Source\": \"Service\","
			+ "\"Age_In_Years\": 37,"
			+ "\"Gender_Identity\": \"Male\","
			+ "\"Graduation_Date\": \"15/12/1989 00:00:00\","
			+ "\"last_visit_date\": \"03/16/2022 00:00:00\""
			+ "},"
			+ "\"address\": {"
			+ " \"line1\": \"Suite #200\","
			+ " \"line2\": \"530 Lytton Ave\","
			+ " \"city\": \"Palo Alto\","
			+ " \"state\": \"CA\"," 
			+ " \"country\": \"US\"," 
			+ " \"postal_code\": \"94301\"" 
			+ "}"
			+ "}";
		Map<String, Object> mapping = new ObjectMapper().readValue(userInfo, HashMap.class);
		for(String key:mapping.keySet()){
			claims.put(key, mapping.get(key));
		}
        claims.put("exp", exp);
    	jwtToken = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, Base64.getEncoder().encodeToString(secret.getBytes())).compact();
		System.out.println(jwtToken);
		
	}

}
require 'jwt'

secret = 'your-api-key'
user_info = {
  'member_id' => 'Unique-ID',
  'email_address' => '[email protected]',
  'first_name' => 'First Name',
  'last_name' => 'Last Name',
  'member_status' => 'active',
  'member_tags' => ['Frequent buyer', 'Loyal'],
  'phone_number' => '+1-7203332525',
  'birthdate' => '12/06/2020',
  'anniversary_date' => '12/06/2020',
  'preferred_language' => 'english',
  'twitter_handle' => 'www.twitter.com/john',
  'instagram_handle' => 'www.instagram.com/john',
  'referrer_code' => 'JOH3TNLY',
  'current_tier_id' => 'zrl_silver',
  'custom_attributes' => {
    "City_Name" => "Paris",
    "Age_In_Years" => 37,
    "last_visit_date" => "03/16/2022 00:00:00",
    "visited_cities" => ["Paris", "London"]
  },
  'address' => {
    'line1' => '530 Lytton Ave',
    'line2' => 'Suite #200',
    'city' => 'Palo Alto',
    'state' => 'CA',
    'country' => 'US',
    'postal_code' => '94301'
  },
  'exp' => '', # Mandatory: Epoch timestamp (seconds), after which the token will expire
}

encoded_jwt = JWT.encode(user_info, secret, 'HS256')
puts encoded_jwt

📘

Please Note:

Please ensure to provide only the member details that you wish to create or update. If there are certain attributes you do not wish to update, simply omit those fields from the payload entirely. To reset a specific field for a member, pass us the field with an empty string.

The member variables mentioned in the snippet can be passed through a JWT token. This can be done using the Python, Java and Ruby codes given above.

Shown below is the detailed description of the fields to be populated dynamically.

  • partner_id: This is an alpha-numeric value assigned that uniquely identifies the client account in Zinrelo. Each client is assigned a partner ID on signing up with Zinrelo. The client will update this partner ID in the admin configuration screen.
  • member_id: This is the unique identifier assigned to each member. For an eCommerce platform, the email address will be used as the unique identifier and should be mapped to the member_id field.
  • email_address: This is the email address of the user who is logged in to your website e.g - [email protected]. The email address should be sent separately even if this is the same value that is mapped to the member ID. The member_id is used for customer identification whereas the email_address field is used to send out the program emails.
  • first_name: This is the first name of the user who is logged in to your website. This information is used to address the user on the loyalty rewards dashboard and to include in the email templates sent to the user.
  • member_status: The status of a member can be categorized as either 'active', 'blocked', or 'opted_out'. However, if the JavaScript does not recognize any of these mentioned statuses, it assumes that the member is active by default.
  • last_name: This is the last name of the user who is logged in to your website. This information is used to address the user on the loyalty rewards dashboard and to include in the email templates sent to the user.
  • preferred_language: This is the multi-language option we provide to members. They can list the languages in which they want their dashboard to be.
  • phone_number: This is the phone number of the user who is logged in to your website. This information could be used to send out loyalty notifications to the member.
  • birthdate: This is the birthdate of the user who is logged in. This may be used to restrict access to certain parts of the program. It can also be used to give personalized rewards to the member.
  • member tags: Multiple comma separated tags can be assigned to the member. The tags passed through the script are appended to the existing tags the member may have. Tags are useful to apply business rules and filter the members to run campaigns.
  • anniversary_date: This is the wedding anniversary date of the user who is logged in to the website. Gifting websites usually capture this information for personalized promotions.
  • address: address_line1, address_line2, city, state, postal code are all fields to capture the address of the logged in user. This could be used to restrict some program content or to give personalized offers.
  • email_subscription_status: This is the email subscription status of the logged in user as captured in the eCommerce platform.
  • exp: This is the expiry time after which you want to expire the current token. For ex, if you want to create the token with 30 mins of expiry then you can set the exp as Exp: Current epoch time stamp + 1800
  • Jwt token: JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (in our case the API key will be the secret key).

Note: Since you would never want to expose your API Key on the frontend, you will need to generate the access_token at the backend and relay it over to the frontend so that it can be passed in the Zinrelo JavaScript snippet.

Common Mistakes

Here are some common mistakes in including the Basic Integration Snippet:

  • Partner ID is copied as-is from this document: The partner_id field is a unique key generated by Zinrelo to identify a Client. Please confirm that your partner_id is correct. If you are copying code from the Zinrelo Admin Console, the partner_id will be correct. If you are copying as-is from this document, the partner_id will be wrong.
  • Integration snippet is copied as-is: The fields must be filled dynamically from the information available on the website. Therefore, a developer with some technical skills is required to complete this task. It is not a mere copy and paste.
  • All.js code is not copied onto the website: Zinrelo uses a Javascript called all.js. This script must be included in the snippet.