OMPAYOMPAY
Reference

Signature Verification

How to generate and verify HMAC signatures for OMPAY API requests and responses

Signature Verification

OMPAY uses HMAC SHA256 signatures to ensure the integrity and authenticity of API requests and responses.

Request Signature (Merchant Hosted)

For merchant-hosted APIs, each request must include an X-Signature header.

Signature Generation

The signature is an HMAC SHA256 hash of apiPath + payload, using your clientSecret as the key.

Node.js Example

const crypto = require('crypto');

function generateHMAC(clientSecret, apiPath, payload = '') {
  const dataToSign = apiPath + payload;
  const signature = crypto
    .createHmac('sha256', clientSecret)
    .update(dataToSign)
    .digest('hex');
  return signature;
}

Parameters

ParameterMandatoryDescriptionExample
clientSecretYesYour client secret<your-client-secret>
apiPathYesAPI endpoint path/order
payloadNo (GET) / Yes (POST)Request body as JSON string{"amount":100,"currency":"OMR"}

POST Request Example

const apiPath = '/order';
const payload = {
  amount: 100,
  currency: 'OMR',
  description: 'Test Purchase',
  customerFields: {
    name: 'John Doe',
    email: 'johndoe@example.com',
    phone: '1234567890',
  },
  uiMode: 'checkout',
};

const signature = generateHMAC(clientSecret, apiPath, JSON.stringify(payload));

GET Request Example

const apiPath = '/transaction/status/paycbaff3b9dc5443f0ba0997970ebeddfa';
const signature = generateHMAC(clientSecret, apiPath);

Response Signature Verification

For both bank-hosted and merchant-hosted flows, verify payment responses using HMAC SHA256 over orderId|paymentId.

Verification Process

  1. Gather inputs: orderId, paymentId, clientSecret
  2. Generate HMAC: SHA256(orderId + "|" + paymentId)
  3. Compare with response signature

JavaScript Verification

const crypto = require('crypto');

function generateHMAC(key, data) {
  const hmac = crypto.createHmac('sha256', key);
  hmac.update(data);
  return hmac.digest('hex');
}

const secretKey = '<clientSecret>';
const message = `${orderId}|${paymentId}`;
const generatedSignature = generateHMAC(secretKey, message);

if (generatedSignature === responseSignature) {
  // Payment signature is validated
  // Proceed with updating transaction status
}

Java Verification

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class HMACGenerator {
  public static String generateHMAC(String key, String data) {
    try {
      Mac hmac = Mac.getInstance("HmacSHA256");
      SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "HmacSHA256");
      hmac.init(secretKeySpec);
      byte[] hmacBytes = hmac.doFinal(data.getBytes());
      return bytesToHex(hmacBytes);
    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
      e.printStackTrace();
      return null;
    }
  }

  public static String bytesToHex(byte[] bytes) {
    StringBuilder hexString = new StringBuilder();
    for (byte b : bytes) {
      String hex = Integer.toHexString(0xff & b);
      if (hex.length() == 1) hexString.append('0');
      hexString.append(hex);
    }
    return hexString.toString();
  }

  public static void main(String[] args) {
    String secretKey = "<clientSecret>";
    String message = orderId + "|" + paymentId;
    String generatedSignature = generateHMAC(secretKey, message);

    if (generatedSignature.equals(signature)) {
      // Payment signature is validated
    }
  }
}

Failure Responses

ResCodeStatusDescription
401failureSignature missing in request header
401failureInvalid signature

Next Steps

On this page