Refgrow

Identity Verification (HMAC)

Secure the pre-authenticated widget by verifying affiliate identity with a server-side HMAC-SHA256 signature.

Why Use Identity Verification?

When you embed the Refgrow widget with data-project-email pre-set, the email is visible in the page source. A tech-savvy user could change this attribute via browser DevTools and access another affiliate's dashboard (earnings, referral code, payment method).

Identity Verification prevents this by requiring a server-generated HMAC hash alongside the email. The hash is computed using your project secret, which only your server knows. If the hash doesn't match, the widget refuses to load affiliate data.

How It Works

  1. Your server computes HMAC-SHA256(email, project_secret)
  2. You pass the hash as data-user-hash in the widget embed
  3. Refgrow's API verifies the hash before returning any affiliate data
  4. If verification fails, the API returns 403 Forbidden

Setup

Step 1: Enable in Settings

Go to your project Settings → General → Identity Verification (HMAC) and toggle it on.

Important: Make sure your widget embed code includes data-user-hash before enabling this setting. Otherwise, all affiliate widgets will stop loading data until the hash is added.

Step 2: Generate the Hash on Your Server

Use your HMAC Secret Key (shown in Settings → General → Identity Verification when enabled) and the affiliate's email to compute the hash. Always lowercase the email before hashing. Store the secret key as an environment variable on your server — never expose it in frontend code.

Node.js

const crypto = require('crypto');

const userHash = crypto
  .createHmac('sha256', process.env.REFGROW_HMAC_SECRET)
  .update(userEmail.toLowerCase())
  .digest('hex');

Python

import hmac
import hashlib

user_hash = hmac.new(
    HMAC_SECRET.encode(),
    user_email.lower().encode(),
    hashlib.sha256
).hexdigest()

PHP

$userHash = hash_hmac(
    'sha256',
    strtolower($userEmail),
    $hmacSecret
);

Ruby

require 'openssl'

user_hash = OpenSSL::HMAC.hexdigest(
  'sha256',
  hmac_secret,
  user_email.downcase
)

Go

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "strings"
)

func userHash(email, secret string) string {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write([]byte(strings.ToLower(email)))
    return hex.EncodeToString(mac.Sum(nil))
}

Step 3: Add the Hash to Your Widget

Standard & Compact Widget

Pass the generated hash as the data-user-hash attribute:

<div id="refgrow"
  data-project-id="YOUR_PROJECT_ID"
  data-project-email="user@example.com"
  data-user-hash="a1b2c3d4e5f6...">
</div>
<script src="https://scripts.refgrowcdn.com/latest.js" async defer></script>

Modal Widget

Pass the hash as the 5th parameter to openModal. The 4th parameter (legacy) should be null:

RefgrowCompact.openModal(
  'YOUR_PROJECT_ID',
  'user@example.com',
  'en',        // language
  null,        // legacy param, pass null
  'a1b2c3...'  // HMAC hash
)

How Verification Works

When the widget loads, it sends the email and hash to the Refgrow API. The API computes the expected hash using the stored HMAC secret key and compares it:

  • Hash matches: Affiliate data is returned normally
  • Hash doesn't match: API returns 403 — "Invalid identity verification hash"
  • No hash provided (when required): API returns 403 — "Identity verification required"

Backward Compatibility

Identity verification is opt-in. When disabled (default), the widget works exactly as before — no hash is needed. This means you can:

  1. First update your embed code to include data-user-hash
  2. Deploy the change to production
  3. Then enable the setting in Refgrow

This ensures zero downtime during the transition.

Security Notes

  • Never expose your Project Secret in client-side code. The hash must be computed on your server.
  • The hash is specific to each email address. Changing the email without updating the hash will fail verification.
  • If you rotate your Project Secret, all existing hashes become invalid. Update your server code with the new secret and redeploy before rotating.

Troubleshooting

Widget shows "Identity verification required"

Your project has identity verification enabled but the widget embed is missing the data-user-hash attribute. Add the hash to your embed code.

Widget shows "Invalid identity verification hash"

  • Check that you're using the correct Project Secret
  • Make sure you lowercase the email before hashing: email.toLowerCase()
  • Verify the hash is the full hex string (64 characters for SHA-256)
  • Ensure the email in data-project-email matches exactly what you hashed
Start Free Trial
Identity Verification (HMAC) — Refgrow Docs