Praxis Wiki logo

Overview Authentication


Algorithm

The signature is built as a sha-384 hash of the JSON string being sent in request body.

Signature generation The following steps are required in order to generate or validate the signature

  1. Values for the specified parameters are concatenated into a string (1) - in a sequence as described for each API method (see Signature section for each API method documentation)
  2. String variable (1) is concatenated with the merchant secret into a new temporary variable (2).
  3. Resulting temporary variable (2) is hashed with sha-384 algorithm into a hash variable (3).
  4. The hash variable (3) value is sent as GT-Authentication: YOUR_HASH_STRING_HERE HTTP header.
  5. Additionally Content-Type: application/json; charset=utf-8 HTTP header is sent.
  6. JSON string is sent as a body of your outgoing request, or your response to the incoming request.

Signature validation When you receive an incoming request or a response to your outgoing request, it will be also preceded by the GT-Authentication: ... and Content-Type: application/json; charset=utf-8 HTTP headers. In order to validate the signature the following steps should be done:

  1. JSON string from incoming request body or from response body to your outgoing request is read and parsed into the data object.
  2. Values for the specified parameters are concatenated into a string (1) - in a sequence as described for each API method (see Signature section for each API method documentation)
  3. String variable (1) is concatenated with the merchant secret into a new temporary variable (2).
  4. Resulting temporary variable (2) is hashed with sha-384 algorithm into a hash variable (3).
  5. Temporary hash variable (3) is compared to GT-Authentication HTTP header of an incoming request or a response to your outgoing request - by using the string comparison function.
  6. If the temporary hash variable (3) is equal to GT-Authentication HTTP header then the signature is valid, otherwise your application behavior should recognize the invalid signature as the authentication failure with corresponding further logic.

Example

<?php

class HowToBuildSignature
{
    //Action to be taken within the cashier
    const INTENT_PAYMENT = 'payment';
    // Your Merchant Account ID
    const MERCHANT_ID = 'Test-Integration-Merchant';
    // Your Merchant Secret
    const MERCHANT_SECRET = 'MerchantSecretKey';
    // Your Application Key
    const APPLICATION_KEY = 'Sandbox';
    // Your API Version
    const API_VERSION = '1.3';
​
    public static function _GET_SAMPLE_DATA_TO_SEND_REQUEST_(): array
    {
        $request = [
            'cid'                 => '1',
            'application_key'     => self::APPLICATION_KEY,
            'merchant_id'         => self::MERCHANT_ID,
            'intent'              => self::INTENT_PAYMENT,
            'order_id'            => self::getOrderID(),
            'your_variable_key_1' => 'some_string_value',
            'your_variable_key_2' => 12345,
            'your_variable_key_3' => null,
            'your_variable_key_4' => true,
            'timestamp'           => self::getCurrentTimestamp(),
            'version'             => self::API_VERSION
        ];
​
        return $request;
    }
​
    //Cashier API 1.3
    private static function getRequestSignatureList()
    {
        return [
            'merchant_id',
            'application_key',
            'timestamp',
            'intent',
            'cid',
            'order_id'
        ];
    }
​
    private static function getConcatenatedString(array $data): string
    {
        $concatenated_string = "";
        foreach (HowToBuildSignature::getRequestSignatureList() as $key) {
            if (array_key_exists($key, $data) && !is_null($data[$key])) {
                $concatenated_string .= $data[$key];
            }
        }
​
        return $concatenated_string;
    }
​
    private static function getGtAuthenticationHeader(array $request): string
    {
        // Sort request array by keys ASC
        $concatenated_string = self::getConcatenatedString($request);
​
        // Concatenate Merchant Secret Key with response params
        $concatenated_string .= self::MERCHANT_SECRET;
​
        // Generate HASH of concatenated string
        $signature = self::generateSignature($concatenated_string);
        return $signature;
    }
​
    private static function generateSignature(string $input): string
    {
        $hashtext = hash('sha384', $input);
​
        return $hashtext;
    }
​
    private static function exportArrayToJSON(array $input): string
    {
        $json_string = json_encode($input);
​
        return $json_string;
    }
​
    private static function getOrderID(): string
    {
        return 'order_' . rand(100, 100000);
    }
​
    private static function getCurrentTimestamp(): int
    {
        return time();
    }
​
    public static function _TEST_()
    {
        echo "=== TESTING REQUEST TO BE SENT ====";
        echo "\n";
        $request_to_send             = self::_GET_SAMPLE_DATA_TO_SEND_REQUEST_();
        $gt_authentication_header    = self::getGtAuthenticationHeader($request_to_send);
        $request_to_send_json_string = self::exportArrayToJSON($request_to_send);
        echo "== GT-Authentication header in the request:";
        echo "\n";
        echo $gt_authentication_header;
        echo "\n";
        echo "== data to send:";
        echo "\n";
        echo $request_to_send_json_string;
        echo "\n";
        echo "\n";
    }
}
​
HowToBuildSignature::_TEST_();