HMAC Signature Authentication

To ensure data integrity and prevent tampering, every request with a body must include both your API key and an HMAC signature. This provides an additional layer of security by verifying that the request payload hasn't been modified in transit.


1. Obtaining Your HMAC Secret Key

Important: Your HMAC secret key is provided by ALPPAY support through a secure communication channel.

  • How to get it: Contact [email protected] after registration
  • Delivery method: Encrypted email or secure messaging platform
  • Security: Never share this key publicly or store it in your code repository
  • Format: followed by alphanumeric characters (e.g., sk_live_abcdef1234567890)

2. X-HMAC Header Configuration

  • Header Name: X-HMAC
  • Algorithm: HMAC-SHA256
  • Data Source: Raw request body (JSON without extra spaces or formatting)
  • Secret Key: Your HMAC secret key from support
  • Signature Format: Lowercase hexadecimal string

3. Generating the HMAC Signature

Follow these steps to generate a valid signature:

  1. Prepare the payload: Serialize your request body to a JSON string maintaining field order
  2. Create HMAC: Compute the HMAC-SHA256 digest using your secret key
  3. Encode result: Convert the hash to a lowercase hexadecimal string

Command Line Example

BODY='{"amount":"250.00","asset":{"short":"USDT","network":"tron"}}'
SECRET_KEY='abcdef1234567890'
SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET_KEY" | cut -d" " -f2)
echo "X-HMAC: $SIGNATURE"

Node.js Implementation

import crypto from 'crypto';

function generateHMACSignature(body, secretKey) {
  // Ensure body is a string
  const bodyString = typeof body === 'string' 
    ? body 
    : JSON.stringify(body);
  
  // Generate HMAC-SHA256 signature
  return crypto
    .createHmac('sha256', secretKey)
    .update(bodyString, 'utf8')
    .digest('hex');
}

// Example usage
const requestBody = {
  amount: '250.00',
  asset: { short: 'USDT', network: 'tron' }
};

const secretKey = process.env.ALPPAY_HMAC_SECRET; // Store in environment variable
const bodyString = JSON.stringify(requestBody);
const signature = generateHMACSignature(bodyString, secretKey);

// Make the request
const response = await fetch('https://api.alppay.io/v2/payment', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'API-KEY': process.env.ALPPAY_API_KEY,
    'X-HMAC': signature
  },
  body: bodyString
});

Python Implementation

import hmac
import hashlib
import json
import os
import requests

def generate_hmac_signature(body, secret_key):
    """Generate HMAC-SHA256 signature for request body"""
    if isinstance(body, dict):
        body = json.dumps(body, separators=(',', ':'))
    
    signature = hmac.new(
        secret_key.encode('utf-8'),
        body.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    return signature

# Example usage
payload = {
    'amount': '250.00',
    'asset': {'short': 'USDT', 'network': 'tron'}
}

secret_key = os.environ.get('ALPPAY_HMAC_SECRET')  # Store in environment variable
api_key = os.environ.get('ALPPAY_API_KEY')

body_string = json.dumps(payload, separators=(',', ':'))
signature = generate_hmac_signature(body_string, secret_key)

# Make the request
response = requests.post(
    'https://api.alppay.io/v2/payment',
    headers={
        'Content-Type': 'application/json',
        'API-KEY': api_key,
        'X-HMAC': signature
    },
    data=body_string
)

4. Complete cURL Request Example

curl https://api.alppay.io/v2/payment \
  -X POST \
  -H "Content-Type: application/json" \
  -H "API-KEY: ak_live_1234567890abcdef" \
  -H "X-HMAC: 3f8fa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0" \
  -d '{"amount":"250.00","asset":{"short":"USDT","network":"tron"}}'

5. Common Errors and Troubleshooting

Error Responses

  • 400 Bad Request: Malformed JSON or incorrect field formatting
  • 401 Unauthorized: Missing, invalid, or incorrectly calculated signature
  • 403 Forbidden: Valid signature but API key lacks permission
  • 422 Unprocessable Entity: Valid signature but payload failed business validation

Debugging Tips

  1. Verify JSON formatting: Ensure no extra spaces or line breaks in the JSON string
  2. Check field order: Maintain consistent field ordering when serializing JSON
  3. Log for comparison: Log both the exact body string and generated signature
  4. Validate secret key: Ensure you're using the correct HMAC secret key from support
  5. Time synchronization: Ensure your server clock is synchronized (if using timestamps)

Best Practices

  • Environment Variables: Never hardcode secret keys; use environment variables
  • Key Rotation: Regularly rotate your HMAC secret key for enhanced security
  • Secure Storage: Use key management services (AWS KMS, HashiCorp Vault, etc.)
  • HTTPS Only: Always use HTTPS to prevent man-in-the-middle attacks
  • Request Logging: Log request signatures for audit trails (but never log the secret key)

6. Security Considerations

  • Never expose your HMAC secret key in client-side code or public repositories
  • Generate a new signature for every request; never reuse signatures
  • Validate signatures server-side before processing any request
  • Use secure channels when receiving your HMAC key from support
  • Implement rate limiting to prevent brute force attempts

Need Help? Contact [email protected] for assistance with HMAC implementation or to request your secret key through a secure channel.