API Credentials

PaySimple assigns API credentials to each merchant account used to authenticate your requests. Your Production API Username and API Key will be delivered via encrypted email. Please ensure the API key is stored encrypted in a secured location on your server, and never sent in a request to any API endpoint or via unencrypted email.

Authorization Header

PaySimple requires an Authorization Header to be included in each request your backend service makes to API 4.0. The Authentication Header must contain an HMAC signature you generate using your API key and the current timestamp. The timestamp must be within a 5 minute window of the current time to account for clock skew. Therefore, the signature should be regenerated with each call to the API.

Building Authorization Header

  1. Generate an HMAC Signature
    a. Generate a string representation of the current date and time in ISO-8601 format. This string can be UTC (e.g. 2018-04-19T16:04:59.9148591Z) or local time with offset (e.g. 2018-04-19T10:04:50.6882019-06:00)
    b. Compute HMAC with date and API Key, both encoded UTF8, using a SHA256 hashing algorithm.
    c. Base-64 Encode the HMAC.
  2. Concatenate "accessid=" + your API Username + "; timestamp=" + the ISO-8601 timestamp defined in step a + "; signature=" + the HMAC result of step b.
  3. Create the Authorization Header value using the following format: "PSSERVER" + " " + the result of step two.

Example output:

Header Key: Authorization
Header Value: PSSERVER accessid=APIUser1000; timestamp=2017-07-20T20:45:44.0973928Z; signature=WqV47Dddgc6XqBKnQASzZbNU/UZd1tzSrFJJFVv76dw=

Code Samples

Examples of creating the authorization header in various languages:

using System;
using System.Net;
using System.Security.Cryptography;
using System.Text;

namespace PaySimpleTest
{
    internal class SignatureGenerator
    {
        public string GenerateAuthHeaderValue(string userName, string apiKey)
        {
            // Generate a string representation of the current date and time in ISO-8601 format.
            var timestamp = DateTime.Now.ToString("o");
            // Compute HMAC with date and API Key, both encoded UTF8, using a SHA256 hashing algorithm.
            var hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(apiKey));
            var hash = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(timestamp));
            // Base-64 Encode the HMAC.
            var signature = Convert.ToBase64String(hash);
            // Format the output
            return $"PSSERVER accessid={userName}; timestamp={timestamp}; signature={signature}";
        }
    }
}
<?php
// For example only, never hard code these values
$userName = "my_api_username";
$apiKey = "my_api_key";

// Generate a string representation of the current date and time in ISO-8601 format.
$timestamp = gmdate("c");

// Compute HMAC with date and API Key, both encoded UTF8, using a SHA256 hashing algorithm.
$hmac = hash_hmac("sha256", $timestamp, $apiKey, true); //note the raw output parameter

// Base-64 Encode the HMAC.
$hmac = base64_encode($hmac);

// Format the output
$authheaderValue = "Authorization: PSSERVER AccessId = $userName; Timestamp = $timestamp; Signature = $hmac";
?>
import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/base64"
    "fmt"
    "time"
)

func CreateAuthorization(username, apiKey string) string {
    return createAuthorization(username, apiKey, time.Now().UTC())
}

func createSignature(apiKey string, now time.Time) string {
    hash := hmac.New(sha256.New, []byte(apiKey))
    hash.Write([]byte(now.Format(time.RFC3339Nano)))
    return base64.StdEncoding.EncodeToString(hash.Sum(nil))
}

func createAuthorization(username, apiKey string, now time.Time) string {
    return fmt.Sprintf(
        `PSSERVER accessid=%s; timestamp=%s; signature=%s`,
        username,
        now.Format(time.RFC3339Nano),
        createSignature(apiKey, now),
    )
}
require 'time'
require 'digest'
require 'base64'

def authorization_header
    utc_timestamp = Time.now.getutc.iso8601.encode(Encoding::UTF_8)
    secret_key = @api_key.encode(Encoding::UTF_8)
    hash = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret_key, utc_timestamp)
    signature = Base64.encode64(hash)

    "PSSERVER accessid=#{@api_user}; timestamp=#{utc_timestamp}; signature=#{signature}"
end
import java.io.UnsupportedEncodingException;
import java.security.SignatureException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.joda.time.DateTime;
import org.springframework.security.crypto.codec.Base64;

public class SecurityUtil {   
    private static final String HMAC_ALGORITHM = "HmacSHA256";

  public static String generatePaySimpleAuthorization(String accessId,String secret) throws SignatureException, UnsupportedEncodingException {
        // get the current time
        String now = DateTime.now().toString();
        byte[] hexBytes;
        try {
            // get an hmac_sha1 key from the raw key bytes
            SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(),HMAC_ALGORITHM);
            // get an hmac_sha1 Mac instance and initialize with the signing key
            Mac mac = Mac.getInstance(HMAC_ALGORITHM);
            mac.init(signingKey);
            // compute the hmac on input data bytes
            byte[] rawHmac = mac.doFinal(now.getBytes());
            // base64-encode the hmac
            hexBytes = Base64.encode(rawHmac);
        } catch (Exception e) {
            throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
        }
        // build the result
        return new StringBuilder("PSSERVER accessid=")
            .append(accessId)
            .append("; timestamp=")
            .append(now)
            .append("; signature=")
            .append(new String(hexBytes,"UTF-8"))
            .toString();
    }
}
Imports System.Runtime.InteropServices
Imports System.Security.Cryptography
Imports System.Text
Imports System.Xml

Public Class HeaderBuilder
    Public Function GetPsServerParameter(userName As String, sharedSecret As String) As String
        Dim timestamp = DateTime.Now.ToUniversalTime()
        Dim formattedTimestamp = XmlConvert.ToString(timestamp, XmlDateTimeSerializationMode.RoundtripKind)
        Return String.Format("PSSERVER accessid={0}; timestamp={1}; signature={2}", userName, formattedTimestamp, CreateSignature(sharedSecret, formattedTimestamp))
    End Function

    Private Shared Function CreateSignature(sharedSecret As String, timestamp As String) As String
        Dim hasher = New HMACSHA256(Encoding.UTF8.GetBytes(sharedSecret))
        Dim hashBytes = hasher.ComputeHash(Encoding.UTF8.GetBytes(timestamp))
        Return Convert.ToBase64String(hashBytes)
    End Function
End Class