Jindal India — Mobile App API Handover

1. Project Overview

This backend service powers the Jindal India mobile app (Retailer & Dealer modules). It exposes APIs for:

  • Dealer/Retailer registration

  • Login & authentication

  • Password management (encrypt/decrypt, reset)

  • Notifications & mail triggers

  • Utility functions (random password generation, global variables)

The APIs integrate with Zoho CRM (for user data storage, auth validation, and mail workflows). Notifications are triggered on key state changes (e.g., activation of a Retailer).


2. Architecture

  • Backend: Zoho Deluge


4. API Endpoints

Retailer APIs

  • POST /retailer/register → Register a retailer in CRM

curl --location 'https://www.zohoapis.in/crm/v7/functions/registeruserapi/actions/execute?auth_type=apikey&zapikey=1003.bf06a30b1844b21cc47b37e0587bffe8.ae7fb8c43e6cc0eebcc3f0bd787cab99' \
--data-raw '{
    "data": {
        "Last_Name": "Hashib Raja",
        "Email": "hashib@extensioncrm.com",
        "Company": "Marrier Pvt Ltd",
        "Retailer_Type": "Strong",
        "Date_of_Onboarding": "2023-05-10",
        "Date_of_Birth": "1990-08-15",
        "Date_of_Marriaage": "2018-02-20",
        "Account_Name": "1019885000000426373",
        "Phone": "555-555-5555",
        "Alternate_Phone_Number": "555-111-2222",
        "City": "Delhi",
        "State": "Delhi",
        "Pin_code": "1019885000000590143",
        "Zone": "North"
    },
    "send_email": true
}'

Dealer APIs

  • POST /dealer/register → Register dealer

curl --location 'https://www.zohoapis.in/crm/v7/functions/registeruserapi/actions/execute?auth_type=apikey&zapikey=1003.bf06a30b1844b21cc47b37e0587bffe8.ae7fb8c43e6cc0eebcc3f0bd787cab99' \
--data-raw '{
    "data": {
        "Account_Name": "Hashib Account",
        "Organization": "King Enterprises Pvt Ltd",
        "Date_of_Onboarding": "2023-04-12",
        "Email": "hashib@extensioncrm.com",
        "Phone": "555-555-5555",
        "Aadhaar_Number": "1234-5678-9012",
        "Alternate_Phone_Number": "555-111-9999",
        "PAN_Number": "ABCDE1234F",
        "GST_Number": "22ABCDE1234F1Z5",
        "City": "Mumbai",
        "State": "Maharashtra",
        "Pincode": "1019885000000590143"
    },
    "module": "Accounts",
    "send_email": true
}'

Auth APIs

  • POST /auth/login → Login with encrypted password

curl --location --request POST 'https://www.zohoapis.in/crm/v7/functions/loginretailerdealer/actions/execute?auth_type=apikey&zapikey=1003.bf06a30b1844b21cc47b37e0587bffe8.ae7fb8c43e6cc0eebcc3f0bd787cab99&identifier=hashib%40extensioncrm.com&password=DGSZJ5'
  • POST /auth/reset-password → Reset password (uses random generator)

curl --location --request POST 'https://www.zohoapis.in/crm/v7/functions/resetprofilepasswordapi/actions/execute?auth_type=apikey&zapikey=1003.bf06a30b1844b21cc47b37e0587bffe8.ae7fb8c43e6cc0eebcc3f0bd787cab99&moduleName=Contacts&recordId=1019885000000958001&newPassword=Hashib%20Raja&sendEmail=true'


Utility APIs

string standalone.generateRandomPassword(Int length)
{
if(length == null)
{
    length = 6;
}
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#%$";
password = "";
i = 0;
iterations = "".leftpad(length).toList("");
for each  iteration in iterations
{
    r = randomnumber(1,chars.length());
    password = password + chars.substring(r,r + 1);
    i = i + 1;
}
return password;
}
string standalone.sendWelcomeEmail(String recordId,String moduleName,String plainPassword,String encryptedPassword,Map opts)
{
resp = Map();
resp.put("status","error");
resp.put("message","unhandled path");
if(opts == null)
{
    opts = Map();
}
emailField = ifnull(opts.get("email_field"),"Email");
login_url = ifnull(opts.get("login_url"),"https://your-app-login.example.com");
logo_url = ifnull(opts.get("logo_url"),"https://www.jindalindia.com/images/demo/choose-jindal-log.png");
from_user = ifnull(opts.get("from_user"),zoho.adminuserid);
// validate inputs
if(recordId == null || recordId == "" || moduleName == null || moduleName == "")
{
    resp.put("message","recordId or moduleName missing");
    return resp.toString();
}
// fetch record by id (string)
rec = zoho.crm.getRecordById(moduleName,recordId);
if(rec == null)
{
    resp.put("message","record fetch failed");
    resp.put("module",moduleName);
    resp.put("id",recordId);
    return resp.toString();
}
toEmail = ifnull(rec.get(emailField),"");
if(toEmail == "" || toEmail == null)
{
    resp.put("message","recipient email not found");
    resp.put("email_field",emailField);
    return resp.toString();
}
// determine plain temporary password
temp_pass = "";
if(encryptedPassword != null && encryptedPassword != "")
{
    try 
    {
        decRes = standalone.decryptPassword(encryptedPassword);
        if(decRes != null && decRes != "")
        {
            // If decrypt helper returned a map-like string, try to parse and get the password key
            try 
            {
                decMap = decRes.toMap();
                // common shapes: {"status":"success","password":"plain"} or {"status":"success","data":"plain"}
                if(decMap.containsKey("password") && decMap.get("password") != null)
                {
                    temp_pass = decMap.get("password");
                }
                else if(decMap.containsKey("data") && decMap.get("data") != null)
                {
                    temp_pass = decMap.get("data");
                }
                else if(decMap.containsKey("result") && decMap.get("result") != null)
                {
                    temp_pass = decMap.get("result");
                }
                else if(decMap.containsKey("status") && decMap.get("status") == "success" && decMap.containsKey("plain"))
                {
                    temp_pass = decMap.get("plain");
                }
                else
                {
                    // If parse succeeded but no expected key, assume decRes itself is the plain string
                    temp_pass = decRes;
                }
            }
            catch (pe)
            {
                // not a map-string; assume decRes is plain password
                temp_pass = decRes;
            }
        }
    }
    catch (e)
    {
        // decrypt call failed; fallback later to plainPassword
        temp_pass = "";
    }
}
// fallback to plainPassword when decrypt not available/failed
if((temp_pass == null || temp_pass == "") && plainPassword != null && plainPassword != "")
{
    temp_pass = plainPassword;
}
// prepare user details
user_email = toEmail;
user_name = "";
if(rec.containsKey("Full_Name"))
{
    user_name = ifnull(rec.get("Full_Name"),"");
}
else if(rec.containsKey("First_Name") || rec.containsKey("Last_Name"))
{
    user_name = ifnull(rec.get("First_Name"),"") + " " + ifnull(rec.get("Last_Name"),"");
    user_name = user_name.trim();
}
if(user_name == "")
{
    user_name = user_email;
}
user_role = moduleName;
// role-based subject/heading
if(user_role == "Accounts")
{
    subject_text = "Welcome DealerYour Jindal account and temporary password";
    role_heading = "Dealer Account Created";
    user_role = "Dealer";
}
else if(user_role == "Contacts")
{
    subject_text = "Welcome RetailerYour Jindal account and temporary password";
    role_heading = "Retailer Account Created";
    user_role = "Retailer";
}
else
{
    subject_text = "Welcome to JindalYour account and temporary password";
    role_heading = "Account Created";
}
// === THE HTML TEMPLATE YOU PROVIDED (kept intact) ===
msg_html = "<!doctype html><html><head><meta charset='utf-8'/><meta name='viewport' content='width=device-width'/><title>Welcome to Jindal</title></head><body style='margin:0;padding:0;background:#ffffff;font-family:Helvetica, Arial, sans-serif;'><table width='100%' cellpadding='0' cellspacing='0' border='0' style='padding:20px 0;'><tr><td align='center'><table width='600' cellpadding='0' cellspacing='0' border='0' style='max-width:600px;border:1px solid #eee;border-radius:8px;overflow:hidden;'><tr><td style='padding:20px 24px;text-align:center;background:#fff;'><img src='" + logo_url + "' alt='Jindal' width='180' style='display:block;margin:0 auto;max-width:80%;height:auto;'/></td></tr><tr><td style='padding:16px 24px;background:#fff;'><h1 style='font-size:20px;margin:0 0 8px 0;color:#cc0000;text-align:left;'>" + role_heading + "</h1><p style='margin:0 0 12px 0;color:#444;line-height:1.45;'>Hi <strong>" + user_name + "</strong>,<br/>Your account has been created successfully. Use the temporary password below to sign in, then update your password in your profile.</p><table cellpadding='10' cellspacing='0' border='0' width='100%' style='margin:12px 0 18px 0;background:#f8f8f8;border-radius:6px;'><tr><td style='font-size:14px;color:#333;'><div style='margin-bottom:6px;'><strong>Role:</strong> " + user_role + "</div><div style='margin-bottom:6px;'><strong>Email / Username:</strong> " + user_email + "</div><div style='margin-bottom:6px;'><strong>Temporary Password:</strong></div><div style='font-size:18px;font-weight:700;color:#cc0000;padding:8px 10px;border-radius:4px;background:#fff;display:inline-block;'>" + temp_pass + "</div></td></tr></table><p style='margin:0 0 18px 0;'><a href='" + login_url + "' style='display:inline-block;padding:10px 16px;border-radius:6px;text-decoration:none;font-weight:600;border:1px solid #cc0000;color:#fff;background:#cc0000;'>Sign in to Jindal</a></p><p style='margin:0;color:#666;font-size:13px;line-height:1.4;'>Note: This password is temporaryplease change it inside your profile after first login. If you did not request this account, please contact support.</p></td></tr><tr><td style='padding:14px 24px;background:#fafafa;color:#777;font-size:12px;text-align:center;'>© " + zoho.currentdate.toString("yyyy") + " Jindal. All rights reserved.</td></tr></table></td></tr></table></body></html>";
// sendmail
try 
{
    sendmail
    [
        from :from_user
        to :user_email
        subject :subject_text
        message :msg_html
    ]
   resp.put("status","success");
   resp.put("message","email sent");
   resp.put("to",user_email);
   resp.put("module",moduleName);
   resp.put("record_id",recordId);
    if(encryptedPassword != null && encryptedPassword != "")
    {
        if(temp_pass != null && temp_pass != "")
        {
           resp.put("password_source","decrypted");
        }
     else if(plainPassword != null && plainPassword != "")
        {
           resp.put("password_source","plain_fallback");
        }
     else
        {
           resp.put("password_source","none");
        }
    }
 else if(plainPassword != null && plainPassword != "")
    {
       resp.put("password_source","plain");
    }
}
catch (e)
{
   resp.put("message","sendmail failed");
   resp.put("details",e.toString());
   resp.put("to",user_email);
}
return resp.toString();
}
string standalone.customEncryptPassword(String plainText)
{
encrypted = zoho.encryption.base64Encode(plainText);
return encrypted;
}

6. Sample cURL (from Postman)

Retailer Registration

curl --location 'https://www.zohoapis.in/crm/v7/functions/registeruserapi/actions/execute?auth_type=apikey&zapikey=1003.bf06a30b1844b21cc47b37e0587bffe8.ae7fb8c43e6cc0eebcc3f0bd787cab99' \
--header 'Content-Type: application/json' \
--data '{
  "name": "ABC Retailer",
  "phone": "9876543210",
  "email": "retailer@test.com"
}'

Login

curl --location 'https://www.zohoapis.in/crm/v7/functions/loginretailerdealer/actions/execute?auth_type=apikey&zapikey=1003.bf06a30b1844b21cc47b37e0587bffe8.ae7fb8c43e6cc0eebcc3f0bd787cab99&identifier=hashib%40extensioncrm.com&password=DGSZJ5' \
--header 'Content-Type: application/json' \
--data '{
  "email": "retailer@test.com",
  "password": "encrypted_value_here"
}'

Reset Password

curl --location 'https://www.zohoapis.in/crm/v7/functions/resetprofilepasswordapi/actions/execute?auth_type=apikey&zapikey=1003.bf06a30b1844b21cc47b37e0587bffe8.ae7fb8c43e6cc0eebcc3f0bd787cab99&moduleName=Contacts&recordId=1019885000000958001&newPassword=Hashib%20Raja&sendEmail=true' \
--header 'Content-Type: application/json' \
--data '{
  "userId": "12345"
}'


7. Blueprint Actions & Notifications

  • Retailer Activate → Mail Trigger (sends activation mail to retailer)


  • Dealer Register → Mail Trigger (sends welcome mail)

  • Password Reset → Mail Trigger (sends random password)



On this page