Docs
Documentation
Documentation Signature Generation

Signature Generation

Learn how to generate signatures for secure API authentication

At a Glance

We'll walk through generating your signature with your secret key, and making your first payment initiation API call.

Generate your signature

To authenticate a request using a secret key, you need to generate a signature.

  • 1. Navigate to the Security > API Credential section of your merchant dashboard and copy your secret key.
  • 2. Use the secret key to generate a signature for your request.
  • 3. Organize all request parameters in alphabetical order by their parameter names.
  • 4. Build a query string in the format: key1=value1&key2=value2&... using RFC 1738 URL encoding (spaces as +)
  • 5. Generate a HMAC-SHA256 signature using the secret key and the query string.
  • 6. Include the signature in the request header as X-Signature.

Let's see an example:

Code Example
<?php
function generateSignature($params, $secretKey) {
  // Sort parameters alphabetically
  ksort($params);
  
  // Build query string with URL encoding
  $queryString = implode('&', array_map(function($key, $value) {
    return $key . '=' . urlencode($value);
  }, array_keys($params), array_values($params)));
  
  // Generate HMAC-SHA256
  $signature = hash_hmac('sha256', $queryString, $secretKey);
  
  return $signature;
}

// Example usage
$params = [
  'biller_code' => '202500039',
  'order_id' => 'ORDER123456',
  'amount' => '150.50',
  'timestamp' => '2025-01-15T10:30:00Z'
];

$signature = generateSignature($params, 'your_secret_key');
?>
const crypto = require('crypto');

function generateSignature(params, secretKey) {
  // Sort parameters alphabetically
  const sortedKeys = Object.keys(params).sort();
  
  // Build query string with URL encoding
  const queryString = sortedKeys
    .map(key => `${key}=${encodeURIComponent(params[key]).replace(/%20/g, '+')}`)
    .join('&');
  
  // Generate HMAC-SHA256
  const signature = crypto
    .createHmac('sha256', secretKey)
    .update(queryString)
    .digest('hex');
  
  return signature;
}

// Example usage
const params = {
  biller_code: "202500039",
  order_id: "ORDER123456",
  amount: "150.50",
  timestamp: "2025-01-15T10:30:00Z"
};

const signature = generateSignature(params, "your_secret_key");
import hashlib
import hmac
from urllib.parse import quote_plus

def generate_signature(params, secret_key):
    # Sort parameters alphabetically
    sorted_params = sorted(params.items())
    
    # Build query string with URL encoding
    query_string = '&'.join([f'{key}={quote_plus(str(value))}' for key, value in sorted_params])
    
    # Generate HMAC-SHA256
    signature = hmac.new(
        secret_key.encode('utf-8'),
        query_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    return signature

# Example usage
params = {
    'biller_code': '202500039',
    'order_id': 'ORDER123456',
    'amount': '150.50',
    'timestamp': '2025-01-15T10:30:00Z'
}

signature = generate_signature(params, 'your_secret_key')
package utils

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"net/url"
	"sort"
	"strings"
)

func CalculateSignature(params map[string]string, hashKey string) string {
	keys := make([]string, 0, len(params))
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	var builder strings.Builder
	for i, k := range keys {
		if i > 0 {
			builder.WriteString("&")
		}
		builder.WriteString(k)
		builder.WriteString("=")
		builder.WriteString(url.QueryEscape(params[k]))
	}
	stringToSign := builder.String()
	h := hmac.New(sha256.New, []byte(hashKey))
	h.Write([]byte(stringToSign))

	return hex.EncodeToString(h.Sum(nil))
}

// Example usage
params := map[string]string{
	"biller_code": "202500039",
	"order_id":    "ORDER123456",
	"amount":      "150.50",
	"timestamp":   "2025-01-15T10:30:00Z",
}

signature := CalculateSignature(params, "your_secret_key")

Mismatched Signature

If the provided signature is invalid, the API returns a 401 Unauthorized response:

{
    "success": false,
    "message": "Authentication failed",
    "errors": [
        {
            "field": "signature",
            "message": "Invalid signature"
        }
    ]
}
            
Was this helpful?
Docs

API

Copyright © Zenpay. All rights reserved.