Skip to main content

Hash calculation

Every Omniware request carries a hash field that signs the rest of the body. Responses that include sensitive state (payment outcome, refund status) also carry a hash you should verify before acting on the result.

The algorithm

  1. Start with the salt

    Begin a string with your salt as the first segment.

  2. Sort parameters by key

    Take all request parameters except hash and sort by key, alphabetically.

  3. Append non-empty values, pipe-delimited

    For each parameter whose value is non-empty (strlen(value) > 0), append | followed by the value. Empty parameters are skipped entirely.

  4. SHA-512 and uppercase

    Hash the resulting string with SHA-512, take the hex digest, and convert to uppercase. That string is your hash.

tip

The salt prefix is appended unconditionally — there is no leading | before it. The first | separator appears between the salt and the first parameter value.

Reference implementation

function generateHashKey(array $parameters, string $salt): ?string
{
$hashing_method = 'sha512';
$secure_hash = null;
ksort($parameters);
$hash_data = $salt;
foreach ($parameters as $key => $value) {
if (strlen($value) > 0) {
$hash_data .= '|' . $value;
}
}
if (strlen($hash_data) > 0) {
$secure_hash = strtoupper(hash($hashing_method, $hash_data));
}
return $secure_hash;
}

Verifying a response hash

When Omniware sends you a response (server-to-server callback, return URL redirect, or API response body) that includes a hash, recompute it using the same algorithm and compare.

function responseHashCheck(string $salt, array $response_array): bool
{
if (is_null($response_array['hash'] ?? null)) {
return true; // no hash to verify
}
$response_hash = $response_array['hash'];
unset($response_array['hash']);
$response_json = json_encode($response_array);

$calculated = strtoupper(hash('sha512', $salt . $response_json));
return hash_equals($response_hash, $calculated);
}
note

Two response-hash conventions exist in the Omniware platform:

  1. Body-as-JSON (Payment Status, Refund Status, S2S webhooks) — hash = SHA512(salt + json_without_hash_field).
  2. Sorted-pipe (form-post redirects) — same algorithm as the request: sort fields, pipe-delimit non-empty values, prefix salt.

The endpoint reference for each API tells you which convention to use.

warning

Use a constant-time comparison (hash_equals / crypto.timingSafeEqual / hmac.compare_digest) when comparing hashes to avoid leaking information through timing differences.