Back to Guides
Pulse2Pay TeamJanuary 3, 20254 min read

API Authentication Guide

Learn how to authenticate API requests using API keys and HMAC signatures with Pulse2Pay.

Pulse2Pay uses API Key + HMAC signature authentication for all API requests. This guide explains how to authenticate your requests correctly.

Authentication Overview

Every API request requires three headers:

HeaderDescription

|--------|-------------|

X-Pulse2Pay-KeyYour public API key (starts with pk_live_ or pk_test_) X-Pulse2Pay-SignatureHMAC-SHA256 signature of the request X-Pulse2Pay-TimestampCurrent Unix timestamp in milliseconds

Getting Your Credentials

  • Log into your merchant dashboard
  • Navigate to Settings > API Keys
  • Click Generate New Keys
  • Store your API Key and Secret securely
  • Important: The API Secret is shown only once. Store it in a secure location (environment variables, secrets manager).

    Generating Signatures

    The signature is computed over a canonical request string:

    signature = HMAC-SHA256(api_secret, canonical_request)
    

    canonical_request = timestamp + "." + method + "." + path + "." + body

    Components

    ComponentDescriptionExample

    |-----------|-------------|---------|

    timestampUnix timestamp (milliseconds)1705320000000 methodHTTP method (uppercase)POST pathRequest path (no host)/api/merchant/v1/payments bodyRequest body (empty string for GET){"amount":"100.00","currency":"USDT","network":"TRON"}

    Example: Creating a Payment

    const crypto = require('crypto');

    function signRequest(method, path, body, apiSecret) {

    const timestamp = Date.now().toString(); // milliseconds

    const bodyString = body ? JSON.stringify(body) : '';

    const canonical = ${timestamp}.${method}.${path}.${bodyString};

    const signature = crypto

    .createHmac('sha256', apiSecret)

    .update(canonical)

    .digest('hex');

    return { timestamp, signature };

    }

    // Usage

    const body = {

    amount: '100.00',

    currency: 'USDT',

    network: 'TRON'

    };

    const { timestamp, signature } = signRequest(

    'POST',

    '/api/merchant/v1/payments',

    body,

    process.env.PULSE2PAY_API_SECRET // sk_live_...

    );

    Code Examples

    Node.js

    const axios = require('axios');
    

    const crypto = require('crypto');

    const API_KEY = process.env.PULSE2PAY_API_KEY; // pk_live_...

    const API_SECRET = process.env.PULSE2PAY_API_SECRET; // sk_live_...

    const BASE_URL = 'https://api.pulse2pay.com';

    async function createPayment(amount, currency, network) {

    const path = '/api/merchant/v1/payments';

    const body = { amount, currency, network };

    const bodyString = JSON.stringify(body);

    const timestamp = Date.now().toString(); // milliseconds

    const canonical = ${timestamp}.POST.${path}.${bodyString};

    const signature = crypto

    .createHmac('sha256', API_SECRET)

    .update(canonical)

    .digest('hex');

    const response = await axios.post(${BASE_URL}${path}, body, {

    headers: {

    'Content-Type': 'application/json',

    'X-Pulse2Pay-Key': API_KEY,

    'X-Pulse2Pay-Signature': signature,

    'X-Pulse2Pay-Timestamp': timestamp

    }

    });

    return response.data;

    }

    Python

    import hmac
    

    import hashlib

    import time

    import json

    import os

    import requests

    API_KEY = os.environ['PULSE2PAY_API_KEY'] # pk_live_...

    API_SECRET = os.environ['PULSE2PAY_API_SECRET'] # sk_live_...

    BASE_URL = 'https://api.pulse2pay.com'

    def create_payment(amount, currency, network):

    path = '/api/merchant/v1/payments'

    body = {'amount': amount, 'currency': currency, 'network': network}

    body_string = json.dumps(body, separators=(',', ':'))

    timestamp = str(int(time.time() * 1000)) # milliseconds

    canonical = f"{timestamp}.POST.{path}.{body_string}"

    signature = hmac.new(

    API_SECRET.encode(),

    canonical.encode(),

    hashlib.sha256

    ).hexdigest()

    response = requests.post(

    f"{BASE_URL}{path}",

    json=body,

    headers={

    'Content-Type': 'application/json',

    'X-Pulse2Pay-Key': API_KEY,

    'X-Pulse2Pay-Signature': signature,

    'X-Pulse2Pay-Timestamp': timestamp

    }

    )

    return response.json()

    PHP

    $apiKey = getenv('PULSE2PAY_API_KEY');      // pk_live_...

    $apiSecret = getenv('PULSE2PAY_API_SECRET'); // sk_live_...

    $baseUrl = 'https://api.pulse2pay.com';

    function createPayment($amount, $currency, $network) {

    global $apiKey, $apiSecret, $baseUrl;

    $path = '/api/merchant/v1/payments';

    $body = ['amount' => $amount, 'currency' => $currency, 'network' => $network];

    $bodyString = json_encode($body);

    $timestamp = (string) round(microtime(true) * 1000); // milliseconds

    $canonical = "{$timestamp}.POST.{$path}.{$bodyString}";

    $signature = hash_hmac('sha256', $canonical, $apiSecret);

    $ch = curl_init($baseUrl . $path);

    curl_setopt_array($ch, [

    CURLOPT_POST => true,

    CURLOPT_POSTFIELDS => $bodyString,

    CURLOPT_RETURNTRANSFER => true,

    CURLOPT_HTTPHEADER => [

    'Content-Type: application/json',

    "X-Pulse2Pay-Key: {$apiKey}",

    "X-Pulse2Pay-Signature: {$signature}",

    "X-Pulse2Pay-Timestamp: {$timestamp}"

    ]

    ]);

    $response = curl_exec($ch);

    curl_close($ch);

    return json_decode($response, true);

    }

    Common Errors

    ErrorCauseSolution

    |-------|-------|----------|

    INVALID_SIGNATURESignature mismatchCheck canonical string format TIMESTAMP_EXPIREDTimestamp > 5 min oldUse current Unix timestamp INVALID_API_KEYKey not foundVerify API key is correct

    Security Best Practices

  • Never expose secrets: Keep API Secret server-side only
  • Use environment variables: Don't hardcode credentials
  • Rotate keys periodically: Generate new keys monthly
  • Monitor usage: Check dashboard for unusual activity
  • Related Resources

  • Webhook Security
  • API Reference
  • Accept USDT Payments
  • #api#authentication#hmac#security

    Ready to get started?

    Create your merchant account and start accepting crypto payments today.