BridgPay Docs

Verify Response Signature

Server response bodies carry x-response-timestamp + x-response-signature. Verify them before trusting payload.

Every response from BridgPay's signed API is itself signed, so you can detect tampering in flight (e.g. a proxy injecting a success flag). The two response headers:

HeaderDescription
x-response-timestampUnix epoch milliseconds when the server signed the response.
x-response-signatureHMAC-SHA256 hex signature over the canonical response string.

Canonical response format

STATUS | PATH | RESPONSE_TIMESTAMP | RESPONSE_BODY
  • STATUS is the numeric HTTP status code (e.g. 200).
  • PATH is the original request path.
  • RESPONSE_BODY is the exact bytes you received — do not re-stringify the parsed JSON. Whitespace and key ordering matter.

TypeScript

import crypto from 'crypto';
 
export function verifyResponseSignature({
  status,
  path,
  timestamp,
  rawBody,
  signature,
  apiSecret,
}: {
  status: number;
  path: string;
  timestamp: string;
  rawBody: string; // MUST be the raw response string, not JSON.stringify(parsed)
  signature: string;
  apiSecret: string;
}): boolean {
  const canonical = [String(status), path, timestamp, rawBody].join('|');
 
  const expected = crypto
    .createHmac('sha256', apiSecret)
    .update(canonical)
    .digest('hex');
 
  const sigBuf = Buffer.from(signature, 'hex');
  const expBuf = Buffer.from(expected, 'hex');
  if (sigBuf.length !== expBuf.length) return false;
 
  return crypto.timingSafeEqual(sigBuf, expBuf);
}

Use timingSafeEqual (constant-time comparison) — a regular === leaks timing information that lets an attacker brute-force the signature byte by byte.

On this page