Influencemart
Become an Affiliate

Getting started

HMAC signing guide

Sign each request so the platform can verify it came from you and wasn’t tampered with.

The recipe

  • Signing string: `${X-Timestamp}.${rawRequestBody}`
  • Algorithm: HMAC-SHA256, output as lowercase hex
  • Secret: your signing secret (shown once at key creation)
  • Body: sign the exact bytes you send — serialize once, sign that string, send that string
  • Bodyless requests: sign `${timestamp}.` (empty body)

Signing code

Set AFF_BASE_URL to your host https://shop.influencemart.com — the examples append the explicit /api/v1/conversions path, matching the conversions guide.

const crypto = require('crypto');

function sign(secret, timestamp, rawBody) {
  // signing string = "${timestamp}.${rawBody}"
  return crypto.createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');
}

const body = JSON.stringify({ externalOrderId: 'ORD-1001', orderAmount: '2999.00' });
const ts = Math.floor(Date.now() / 1000).toString();
const signature = sign(process.env.AFF_API_SECRET, ts, body);

await fetch(process.env.AFF_BASE_URL + '/api/v1/conversions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.AFF_API_KEY,
    'X-Timestamp': ts,
    'X-Signature': signature,
  },
  body, // sign over the EXACT bytes you send
});
Full runnable SDK samples (with product, conversion, order-status and webhook calls) are on the overview page downloads.

Optional: signature v2 (bind method + path)

Everything above is the default scheme (v1). For extra defence-in-depth you can opt into v2, which also binds the HTTP method and request path into the signature so a captured signature can never be replayed against a different route. It is fully backward-compatible — send it only when you want it, per request.

  • Signing string: `${X-Timestamp}.${METHOD}.${path}.${rawRequestBody}`
  • Header: add X-Signature-Version: v2 (omit it, or send v1, for the default)
  • METHOD: the uppercase HTTP method, e.g. POST
  • path: the request path including the /api prefix, with no query string, e.g. /api/v1/conversions
v2 signing (Node.js)
function signV2(secret, ts, method, path, rawBody) {
  // signing string = "${ts}.${METHOD}.${path}.${rawBody}"
  const data = `${ts}.${method.toUpperCase()}.${path}.${rawBody}`;
  return require('crypto').createHmac('sha256', secret).update(data).digest('hex');
}

const ts = Math.floor(Date.now() / 1000).toString();
const sig = signV2(process.env.AFF_API_SECRET, ts, 'POST', '/api/v1/conversions', body);

await fetch(process.env.AFF_BASE_URL + '/api/v1/conversions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.AFF_API_KEY,
    'X-Timestamp': ts,
    'X-Signature': sig,
    'X-Signature-Version': 'v2',
  },
  body,
});

Common mistakes

  • Re-serializing the body after signing (e.g. a framework re-encodes JSON) — the bytes change and the signature fails. Sign the final string.
  • Uppercase hex — the platform compares case-insensitively, but emit lowercase to be safe.
  • Wrong separator — it’s a literal dot between timestamp and body: timestamp + "." + body.
  • Clock drift — a timestamp outside ±300s is rejected as stale. Sync via NTP.
  • Reusing a signature — each is single-use within the window; generate a new timestamp + signature per request.
  • Signing a pretty-printed body but sending minified (or vice-versa).

Troubleshooting

A signature failure returns 401 and logs an error code in your API logs: SIG_BAD_SIGNATURE (mismatch), SIG_STALE_TIMESTAMP (clock), SIG_REPLAY (reused), SIG_UNSUPPORTED_VERSION (unknown X-Signature-Version). Reproduce locally by signing a known timestamp + body and comparing against the expected hex.

Verify locally (Node.js)
const sig = require('crypto').createHmac('sha256', secret).update('1718000000.{"a":1}').digest('hex');
console.log(sig); // compare with what you sent in X-Signature

Start earning from your audience

Join Nepal's affiliate network. Weekly payouts, real tracking, honest commissions.

Join as Affiliate →List Your Store