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:
| Header | Description |
|---|---|
x-response-timestamp | Unix epoch milliseconds when the server signed the response. |
x-response-signature | HMAC-SHA256 hex signature over the canonical response string. |
Canonical response format
STATUS | PATH | RESPONSE_TIMESTAMP | RESPONSE_BODY
STATUSis the numeric HTTP status code (e.g.200).PATHis the original request path.RESPONSE_BODYis 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.