Signature generation and verification

Overview

The data communication between the merchant's web service and the Benker payment platform is protected by using the TLS (Transport Layer Security) protocol version 1.2 or later. This ensures the confidentiality of the data being transmitted, although the protocol cannot guarantee the message integrity and ensure that the message author possesses the secret key. Therefore, every message must be digitally signed using the secret key issued by Benker for the merchant and known only to the merchant and the Benker payment platform.

Regardless of the interface that is used for working with the payment platform, digital signatures must be included in all requests, callbacks, and certain responses exchanged between the merchant's web service and the payment platform. Thus, before sending any request to the platform, generate and include a signature in the request to be sent; and when receiving responses and callbacks from the platform, verify the received data by comparing the signatures to the ones generated on the merchant side. To implement the digital signature generation and verification, you can use either your own solutions or the SDKs available from Benker (details).

This section describes the algorithms for the digital signature generation and the data integrity verification, including examples with the use of these algorithms and interactive forms for testing the workflows using signatures.

Signature generation

Signing algorithm

The algorithm input includes the following:

  1. Data to sign.

    As a rule, it is a request body: all request parameters without the signature or the configObj JavaScript object with parameters that do not include the signature parameter.

  2. A signing key.
    Note: For working with the Data API, it is necessary to use keys generated via the Dashboard interface together with tokens (for more information, see the Data access model section.)

    For the purposes of debugging and testing your signing algorithm implementation, you are free to use any signing key. For signing requests in production environment, you are required to use your production secret key.

Depending on the algorithm implementation, its output may be either a signature or signed data. Generally, the algorithm output consists of an object or a request body in the JSON format with the signature parameter.

The algorithm description, the examples, and test forms below include the most common algorithm implementation relevant for use when working with the Payment Page API, the Gate API, and the Data API.

The algorithm includes the following steps:

  1. Validating input. Make sure the following requirements are met:

    1. The structure of data to be signed must correspond to the JSON format. In case of using Payment Page, JavaScript objects are also allowed.
    2. Data to sign does not contain any signature parameter even if it is empty.
    3. The signing key is readily available.
  2. Transforming data to meet the nesting depth requirements.

    Depending on which interface of the payment platform you need to send the request to, this step requires different actions:

    • When working via Payment Page, encode those parameters that contain nested objects using Base64 or URL encoding, as per the requirements that can be found in the list of parameters for opening the payment form.
    • When working via the Gate API, you do not have to transform data because there are no nesting depth restrictions.
    • When working via the Data API, replace values of all parameters nested at level four or deeper with empty strings.
  3. Converting all strings to UTF-8 with parameters sorted in natural order. Complete the following steps:

    1. Encode any Boolean values as follows: replace false with 0, replace true with 1. Mind that this rule applies only to Boolean values. If any string parameter contains "false" or "true" string value, the value is not replaced with 0 or 1 but is treated as any other string value.
    2. Convert each parameter into a string that contains the full path to the parameter (with all its parents), parameter name, and parameter value:

      <parent_1>:...:<parent_n>:<parameter_name>:<parameter_value>

      where parents are the object(s) and/or arrays in which the parameter is contained. Parents are ordered by the embedding level starting with the topmost one. The parent names, parameter name, and parameter value are delimited by colon (:); delete any commas between key-value pairs and any quotation marks that delimit string values.

    3. Leave any empty parameter values empty. In other words, do not replace any empty values with blank space or null. For instance, "payment_description":"" is replaced with payment_description:.
    4. Add index numbers to array elements starting with zero, for example, ["alpha", "beta", "gamma"] is replaced with three strings: 0:alpha, 1:beta, and 2:gamma.
    5. Empty arrays are ignored and are not included in the string set used to generate the signature.
    6. Convert all strings to UTF-8.
    7. Sort the strings in natural sort order and join them into a single string by using semicolon (;) as a delimiter.
  4. Calculating the HMAC code by using the key and the SHA-512 hash function. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key. The HMAC code must be calculated as raw binary data.
  5. Encoding the HMAC code by using the Base64 scheme. Encode the HMAC code using Base64 to obtain the signature for the initial data.
  6. Adding signature. Add the signature parameter to the request body using the signature from the previous step as its value.

Example of a purchase request via Payment Page

Suppose that you need to generate a signature for a Payment Page request in the following scenario:

  • The secret key obtained from the Benker technical support: secret.
  • The configObj object that does not yet contain the signature parameter is the following:
    {
       "project_id": 120,
       "payment_id": "580",
       "payment_amount": 1000,
       "payment_currency": "EUR",
       "customer_id": "customer1",
       "customer_first_name": "John",
       "customer_last_name": "Doe",
       "merchant_return_url": "http://example.com/return",
       "signature": "<signature that needs to be generated>" 
    }

The task is to generate the signature; in other words, you need to compute the value for the signature parameter. The signature is generated as follows:

  1. Make sure there is no signature parameter in your request even it is empty:
    {
       "project_id": 120,
       "payment_id": "580",
       "payment_amount": 1000,
       "payment_currency": "EUR",
       "customer_id": "customer1",
       "customer_first_name": "John",
       "customer_last_name": "Doe",
       "merchant_return_url": "http://example.com/return",
       "signature": "<signature that needs to be generated>" 
    }
  2. Convert all strings to UTF-8 as per algorithm description:
    project_id:120
    payment_id:580
    payment_amount:1000
    payment_currency:EUR
    customer_id:customer1
    customer_first_name:John
    customer_last_name:Doe
    merchant_return_url:http://example.com/return
  3. Sort the strings in natural sort order:
    customer_first_name:John
    customer_id:customer1
    customer_last_name:Doe
    merchant_return_url:http://example.com/return
    payment_amount:1000
    payment_currency:EUR
    payment_id:580
    project_id:120
  4. Join all strings into a single string by using semicolon (;) as a delimiter:
    customer_first_name:John;customer_id:customer1;customer_last_name:Doe;merchant_return_url:http://example.com/return;payment_amount:1000;payment_currency:EUR;payment_id:580;project_id:120
  5. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key, and then encode the HMAC code by using the Base64 scheme:
    rgA1gh7M3LQBSJn1UiCkjIRWkO39c5xMyI5gwCdI/AgLJ1wYkw0clL8Zm89CGHZo6dp9E6YOLa870GH4GkMmZA==
  6. Add the resulting signature to the configObj object:
    {
       "project_id": 120,
       "payment_id": "580",
       "payment_amount": 1000,
       "payment_currency": "EUR",
       "customer_id": "customer1",
       "customer_first_name": "John",
       "customer_last_name": "Doe",
       "merchant_return_url": "http://example.com/return",
       "signature": "rgA1gh7M3LQBSJn1UiCkjIRWkO39c5xMyI5gwCdI/AgLJ1wYkw0clL8Zm89CGHZo6dp9E6YOLa870GH4GkMmZA==" 
    }

Signature verification form for Payment Page

Below you can find an interactive form that allows you to test signature generation when sending requests for opening Payment Page.

Note: To ensure correct processing of parameters specified in real requests for opening Payment Page, familiarise yourself with the requirements for encoding nested objects listed in Parameters for opening the payment form and the articles describing the capabilities of the payment form. When you specify nested objects that do not conform to these requirements, the signature in the interactive testing form will still be generated according to the algorithm, but this signature cannot be used for real requests because it is generated with the use of incorrect input data.

Example of a purchase request via Gate

Suppose that you need to generate the signature for the Gate API request in the following scenario:

  • Signing key : secret.
  • Preliminary request body version where the value for the signature is not yet added:
    {
        "general": {
          "project_id": 2990,
          "payment_id": "payment_id",
          "signature": "<signature that needs to be generated>" 
        },
        "payment": {
          "amount": 1000,
          "currency": "EUR"
          },
        "customer": {
          "id": "customer1",
          "ip_address": "66.249.64.45",
          "first_name": "John",
          "last_name": "Doe"
        },
        "account":{
          "bank_id": 22731
        },
        "return_url":{
          "return": "http://example.com/return"
     }
    }

The task is to generate the signature; in other words, you need to compute the value for the signature parameter and add it to the request. Complete the following steps:

  1. Make sure there is no signature parameter in your request even if it is empty:
    {
        "general": {
          "project_id": 2990,
          "payment_id": "payment_id",
          "signature": "<signature that needs to be generated>"
        },
        "payment": {
          "amount": 1000,
          "currency": "EUR"
          },
        "customer": {
          "id": "customer1",
          "ip_address": "66.249.64.45",
          "first_name": "John",
          "last_name": "Doe"
        },
        "account":{
          "bank_id": 22731
        },
        "return_url":{
          "return": "http://example.com/return"
     }
    }
  2. Convert all strings to UTF-8 as per algorithm description:
    general:project_id:2990
    general:payment_id:payment_id
    payment:amount:1000
    payment:currency:EUR
    customer:id:customer1
    customer:ip_address:66.249.64.45
    customer:first_name:John
    customer:last_name:Doe
    account:bank_id:22731
    return_url:return:http://example.com/return
  3. Sort the strings in natural sort order:
    account:bank_id:22731
    customer:first_name:John
    customer:id:customer1
    customer:ip_address:66.249.64.45
    customer:last_name:Doe
    general:payment_id:payment_id
    general:project_id:2990
    payment:amount:1000
    payment:currency:EUR
    return_url:return:http://example.com/return
  4. Join all strings into a single string by using semicolon (;) as a delimiter:
    account:bank_id:22731;customer:first_name:John;customer:id:customer1;customer:ip_address:66.249.64.45;customer:last_name:Doe;general:payment_id:payment_id;general:project_id:2990;payment:amount:1000;payment:currency:EUR;return_url:return:http://example.com/return
  5. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key, and then encode the HMAC code by using the Base64 scheme:
    bywiqOm5qhxOdslsXGgH1pJIkxzkJfeDsLYn2wzaDK4ZjHjgCRXN1M1fz3jrhI5CYUFwzSUqf8QLQ3xJ6wKEfw==
  6. Add the resulting signature to the request body:
    {
        "general": {
          "project_id": 2990,
          "payment_id": "payment_id",
         "signature": "bywiqOm5qhxOdslsXGgH1pJIkxzkJfeDsLYn2wzaDK4ZjHjgCRXN1M1fz3jrhI5CYUFwzSUqf8QLQ3xJ6wKEfw=="
        },
        "payment": {
          "amount": 1000,
          "currency": "EUR"
          },
        "customer": {
          "id": "customer1",
          "ip_address": "66.249.64.45",
          "first_name": "John",
          "last_name": "Doe"
        },
        "account":{
          "bank_id": 22731
        },
        "return_url":{
          "return": "http://example.com/return"
     }
    }

Signature verification form for the Gate API

Below you can find an interactive form that allows you to test signature generation when sending the Gate API requests.

Example of a data request via the Data API

Suppose that you need to generate a signature for a Dashboard request in the following scenario:

  • Signing key : secret.
  • Preliminary request body version where the value for the signature is not yet added:
    {
      "token": "WKiarERJ5pcceNerpM9R5TNnyPTQMl",
      "interval": {
        "from": "2025-01-01 14:53:55",
        "to": "2025-01-30 13:53:59"
      },
      "project_id": [
        183
      ],
      "limit": 3,
      "offset": 0,
      "tz": "Europe/Athens",
     "signature": "<signature that needs to be generated>"
    }

The task is to generate the signature; in other words, you need to compute the value for the signature parameter and add it to the request. Complete the following steps:

  1. Make sure there is no signature parameter in your request even it is empty:
    {
      "token": "WKiarERJ5pcceNerpM9R5TNnyPTQMl",
      "interval": {
        "from": "2025-01-01 14:53:55",
        "to": "2025-01-30 13:53:59"
      },
      "project_id": [
        183
      ],
      "limit": 3,
      "offset": 0,
      "tz": "Europe/Athens",
     "signature": "<signature that needs to be generated>"
    }
  2. Convert all strings to UTF-8 as per algorithm description:
    token:WKiarERJ5pcceNerpM9R5TNnyPTQMl
    interval:from:2025-01-01 14:53:55
    interval:to:2025-01-30 13:53:59
    project_id:0:183
    limit:3
    offset:0
    tz:Europe/Athens
  3. Sort the strings in natural sort order:
    interval:from:2025-01-01 14:53:55
    interval:to:2025-01-30 13:53:59
    limit:3
    offset:0
    project_id:0:183
    token:WKiarERJ5pcceNerpM9R5TNnyPTQMl
    tz:Europe/Athens
  4. Join all strings into a single string by using semicolon (;) as a delimiter:
    interval:from:2025-01-01 14:53:55;interval:to:2025-01-30 13:53:59;limit:3;offset:0;project_id:0:183;token:WKiarERJ5pcceNerpM9R5TNnyPTQMl;tz:Europe/Athens
  5. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key, and then encode the HMAC code by using the Base64 scheme:
    OR3xug58e9lpzT30E9Hc8/nBRCaXYH//pGcFP66bOlI7QZ8oiRuKlMR0aYIugo2GGxjVzmULzHqwjgcg9iM6iQ==
  6. Add the resulting signature to the request body:
    {
      "token": "WKiarERJ5pcceNerpM9R5TNnyPTQMl",
      "interval": {
        "from": "2025-01-01 14:53:55",
        "to": "2025-01-30 13:53:59"
      },
      "project_id": [
        183
      ],
      "limit": 3,
      "offset": 0,
      "tz": "Europe/Athens",
     "signature": "OR3xug58e9lpzT30E9Hc8/nBRCaXYH//pGcFP66bOlI7QZ8oiRuKlMR0aYIugo2GGxjVzmULzHqwjgcg9iM6iQ=="
    }

Signature verification form for Data API

Below you can find an interactive form that allows you to test signature generation when sending the Data API requests.

Note: When working with the requests sent to the platform via the Data API and the responses to such requests, mind the restriction for signing multi-level nested data included in the payload. The signature is generated for data with three levels of nesting, and the data nested at deeper levels is ignored.

Signature verification

Verification algorithm

The algorithm input includes the following:

  1. Signed data to verify.

    As a rule, it is a callback or response body in the JSON format with the signature parameter.

  2. Verification key. It must be the same key that was previously used for signing the data to verify.

Depending on the algorithm implementation, its output may be either a generated signature or the information whether the generated signature matches the one included in the response or callback.

The algorithm description, the examples, and test forms below use the most common algorithm implementation that includes a callback or response body in the JSON format as input (without the signature parameter) and the result of signature verification as output (with the signature parameter).

Thus, the algorithm includes the following steps:

  1. Validating input. Make sure the following requirements are met:

    1. Data conforms to the JSON format.
    2. Data to verify contains a signature parameter with the signature value.
    3. The signing key is readily available.
  2. Extracting the signature from the data to verify. Store the value of the signature parameter value for further reference and remove the parameter from the input data.
  3. When working with the responses received from the platform via the Data API, at this step you need to replace values of all parameters nested at level four and deeper with empty strings. For example, in the response with operation information for a specified time period you need to remove key-value pairs of the following object: "sum_initial": {"amount": 2000, "currency": "EUR"}. Next, you need to replace the value of the parameter with an empty string "sum_initial": "" and then generate the signature. As for responses and callbacks received from other interfaces of the platform, there are no nesting depth restrictions, and, therefore, no actions to remove data are required.

  4. Generating a signature for the data to verify.
    1. Converting all strings to UTF-8 with parameters sorted in natural order. Complete the following steps:
      1. Encode any Boolean values as follows: replace false with 0, replace true with 1. Mind that this rule applies only to Boolean values. If any string parameter contains "false" or "true" string value, the value is not replaced with 0 or 1 but is treated as any other string value.
      2. Convert each parameter into a string that contains the full path to the parameter (with all its parents), parameter name, and parameter value:

        <parent_1>:...:<parent_n>:<parameter_name>:<parameter_value>

        where parents are the object(s) and/or arrays in which the parameter is contained. Parents are ordered by the embedding level starting with the topmost one. The parent names, parameter name, and parameter value are delimited by colon (:); delete any commas between key-value pairs and any quotation marks that delimit string values.

      3. Leave any empty parameter values empty. In other words, do not replace any empty values with blank space or null. For instance, "payment_description":"" is replaced with payment_description:.
      4. Add index numbers to array elements starting with zero, for example, ["alpha", "beta", "gamma"] is replaced with three strings: 0:alpha, 1:beta, and 2:gamma.
      5. Empty arrays are ignored and not included in the string set used to generate the signature.
      6. Convert all strings to UTF-8.
      7. Sort the strings in natural sort order and join them into a single string by using semicolon (;) as a delimiter.
    2. Calculating the HMAC code by using the key and the SHA-512 hash function. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key. The HMAC code must be calculated as raw binary data.
    3. Encoding the HMAC code by using the Base64 scheme. Encode the HMAC code using Base64 to obtain the signature for the initial data.
  5. Signature matching. Compare the generated signature with the signature you have previously stored. If the signatures match, the data is authentic and its integrity is considered confirmed; otherwise, the data is considered compromised and cannot be used for production purposes.

Example of callback verification

Suppose that you need to verify the signature of a callback in the following scenario:

  • Signing key : secret.
  • The callback body contains the following information:
    Figure 1. Callback body
    {
      "project_id": 200,
      "payment": {
        "id": "abc12345",
        "type": "purchase",
        "status": "success",
        "date": "2025-03-20T14:22:06+0000",
        "method": "Greek Banks",
        "sum": {
          "amount": 1000,
          "currency": "EUR"
        },
        "description": "Success"
      },
      "customer": {
        "id": "123"
      },
      "operation": {
        "id": 9529253065607,
        "type": "sale",
        "status": "success",
        "date": "2025-03-20T14:22:06+0000",
        "created_date": "2025-03-20T14:22:00+0000",
        "request_id": "f1de353331a01fd14163fe4226-00009530",
        "sum_initial": {
          "amount": 1000,
          "currency": "EUR"
        },
        "sum_converted": {
          "amount": 1000,
          "currency": "EUR"
        },
        "code": "0",
        "message": "Success",
        "provider": {
          "id": 1914,
          "payment_id": "",
          "auth_code": ""
        }
      },
      "signature": "OBjT3RaJnOWsDXOclvWoC6+CFSCtLprTo8VFbN6BYVQD2tVK/3d9k+RRA/7N9TV6OQqk+0uPUnx4/c8uaUurw=="
    }

The signature is verified as follows:

  1. Remove the signature parameter and its value from the callback:
    {
      "project_id": 200,
      "payment": {
        "id": "abc12345",
        "type": "purchase",
        "status": "success",
        "date": "2025-03-20T14:22:06+0000",
        "method": "Greek Banks",
        "sum": {
          "amount": 1000,
          "currency": "EUR"
        },
        "description": "Success"
      },
      "customer": {
        "id": "123"
      },
      "operation": {
        "id": 9529253065607,
        "type": "sale",
        "status": "success",
        "date": "2025-03-20T14:22:06+0000",
        "created_date": "2025-03-20T14:22:00+0000",
        "request_id": "f1de353331a01fd14163fe4226-00009530",
        "sum_initial": {
          "amount": 1000,
          "currency": "EUR"
        },
        "sum_converted": {
          "amount": 1000,
          "currency": "EUR"
        },
        "code": "0",
        "message": "Success",
        "provider": {
          "id": 1914,
          "payment_id": "",
          "auth_code": ""
        }
      },
      "signature": "OBjT3RaJnOWsDXOclvWoC6+CFSCtLprTo8VFbN6BYVQD2tVK/3d9k+RRA/7N9TV6OQqk+0uPUnx4/c8uaUurw=="
    }
  2. Convert all parameter strings to UTF-8 as per algorithm description:
    project_id:200
    payment:id:abc12345
    payment:type:purchase
    payment:status:success
    payment:date:2025-03-20T14:22:06+0000
    payment:method:Greek Banks
    payment:sum:amount:1000
    payment:sum:currency:EUR
    payment:description:Success
    customer:id:123
    operation:id:9529253065607
    operation:type:sale
    operation:status:success
    operation:date:2025-03-20T14:22:06+0000
    operation:created_date:2025-03-20T14:22:00+0000
    operation:request_id:f1de353331a01fd14163fe4226-00009530
    operation:sum_initial:amount:1000
    operation:sum_initial:currency:EUR
    operation:sum_converted:amount:1000
    operation:sum_converted:currency:EUR
    operation:code:0
    operation:message:Success
    operation:provider:id:1914
    operation:provider:payment_id:
    operation:provider:auth_code:
  3. Sort the strings in natural sort order:
    customer:id:123
    operation:code:0
    operation:created_date:2025-03-20T14:22:00+0000
    operation:date:2025-03-20T14:22:06+0000
    operation:id:9529253065607
    operation:message:Success
    operation:provider:auth_code:
    operation:provider:id:1914
    operation:provider:payment_id:
    operation:request_id:f1de353331a01fd14163fe4226-00009530
    operation:status:success
    operation:sum_converted:amount:1000
    operation:sum_converted:currency:EUR
    operation:sum_initial:amount:1000
    operation:sum_initial:currency:EUR
    operation:type:sale
    payment:date:2025-03-20T14:22:06+0000
    payment:description:Success
    payment:id:abc12345
    payment:method:Greek Banks
    payment:status:success
    payment:sum:amount:1000
    payment:sum:currency:EUR
    payment:type:purchase
    project_id:200
  4. Join all strings into a single string by using semicolon (;) as a delimiter:
    customer:id:123;operation:code:0;operation:created_date:2025-03-20T14:22:00+0000;operation:date:2025-03-20T14:22:06+0000;operation:id:9529253065607;operation:message:Success;operation:provider:auth_code:;operation:provider:id:1914;operation:provider:payment_id:;operation:request_id:f1de353331a01fd14163fe4226-00009530;operation:status:success;operation:sum_converted:amount:1000;operation:sum_converted:currency:EUR;operation:sum_initial:amount:1000;operation:sum_initial:currency:EUR;operation:type:sale;payment:date:2025-03-20T14:22:06+0000;payment:description:Success;payment:id:abc12345;payment:method:Greek Banks;payment:status:success;payment:sum:amount:1000;payment:sum:currency:EUR;payment:type:purchase;project_id:200
  5. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key, and then encode the HMAC code by using the Base64 scheme:
    jOBjT3RaJnOWsDXOclvWoC6+CFSCtLprTo8VFbN6BYVQD2tVK/3d9k+RRA/7N9TV6OQqk+0uPUnx4/c8uaUurw==
  6. Compare the generated signature and the one included in the callback.

    In our case, the signatures differ which means that the callback is invalid and must be ignored.

Signature verification form for callbacks

Below you can find an interactive form that allows you to test signature verification.

Example of verifying a response via the Gate API

Suppose that you need to verify the signature of a response in the following scenario:

  • Signing key : secret.
  • The response body contains the following information:
    Figure 2. Response body
    {
        "project_id": 131221,
        "payment": {
            "id": "abc12345",
            "type": "purchase",
            "status": "awaiting confirmation",
            "date": "2025-04-11T05:22:03+0000",
            "method": "Austrian Banks",
            "sum": {
                "amount": 22500,
                "currency": "EUR"
            },
            "description": ""
        },
        "account": {
            "number": "AT0000******2000"
        },
        "customer": {
            "id": "test@testmail.mail"
        },
        "operations": [
            {
                "id": 9529253065607,
                "type": "sale",
                "status": "success",
                "date": "2025-04-11T05:22:03+0000",
                "created_date": "2025-04-11T05:19:57+0000",
                "request_id": "a7B9kLmQwP2X8rTg-uV3n6Zc1RbEyHd-00002000",
                "sum_initial": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "sum_converted": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "code": "0",
                "message": "Success",
                "provider": {
                    "id": 1234,
                    "payment_id": "X1E6D23319ETBXT",
                    "auth_code": ""
                }
            },
            {
                "id": 9529253065608,
                "type": "payment confirmation",
                "status": "processing",
                "date": "2025-04-11T05:22:03+0000",
                "created_date": "2025-04-11T05:22:03+0000",
                "request_id": "9kLmga7BQwP2X8rT-EyuV3Hn6Zc1Rbd-00002000",
                "sum_initial": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "sum_converted": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "code": "29999",
                "message": "Awaiting processing",
                "provider": {
                    "id": 10001,
                    "payment_id": "",
                    "auth_code": ""
                }
            }
        ],
      "signature": "EksxDdDygDQ30JKsfK6QSvubpNRSj3wtLI5FzWDJuNY0nEhLXt65Y77dtKMJRcd39NegA7YK1eojA2EB1hIbnQ=="
    }

The signature is verified as follows:

  1. Remove the signature parameter and its value.

    {
        "project_id": 131221,
        "payment": {
            "id": "abc12345",
            "type": "purchase",
            "status": "awaiting confirmation",
            "date": "2025-04-11T05:22:03+0000",
            "method": "Austrian Banks",
            "sum": {
                "amount": 22500,
                "currency": "EUR"
            },
            "description": ""
        },
        "account": {
            "number": "AT0000******2000"
        },
        "customer": {
            "id": "test@testmail.mail"
        },
        "operations": [
            {
                "id": 9529253065607,
                "type": "sale",
                "status": "success",
                "date": "2025-04-11T05:22:03+0000",
                "created_date": "2025-04-11T05:19:57+0000",
                "request_id": "a7B9kLmQwP2X8rTg-uV3n6Zc1RbEyHd-00002000",
                "sum_initial": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "sum_converted": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "code": "0",
                "message": "Success",
                "provider": {
                    "id": 1234,
                    "payment_id": "X1E6D23319ETBXT",
                    "auth_code": ""
                }
            },
            {
                "id": 9529253065608,
                "type": "payment confirmation",
                "status": "processing",
                "date": "2025-04-11T05:22:03+0000",
                "created_date": "2025-04-11T05:22:03+0000",
                "request_id": "9kLmga7BQwP2X8rT-EyuV3Hn6Zc1Rbd-00002000",
                "sum_initial": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "sum_converted": {
                    "amount": 22500,
                    "currency": "EUR"
                },
                "code": "29999",
                "message": "Awaiting processing",
                "provider": {
                    "id": 10001,
                    "payment_id": "",
                    "auth_code": ""
                }
            }
        ],
      "signature": "EksxDdDygDQ30JKsfK6QSvubpNRSj3wtLI5FzWDJuNY0nEhLXt65Y77dtKMJRcd39NegA7YK1eojA2EB1hIbnQ=="
    }
  2. Convert all parameter strings to UTF-8 as per algorithm description:
    project_id:131221
    payment:id:abc12345
    payment:type:purchase
    payment:status:awaiting confirmation
    payment:date:2025-04-11T05:22:03+0000
    payment:method:Austrian Banks
    payment:sum:amount:22500
    payment:sum:currency:EUR
    payment:description:
    account:number:AT0000******2000
    customer:id:test@testmail.mail
    operations:0:id:9529253065607
    operations:0:type:sale
    operations:0:status:success
    operations:0:date:2025-04-11T05:22:03+0000
    operations:0:created_date:2025-04-11T05:19:57+0000
    operations:0:request_id:a7B9kLmQwP2X8rTg-uV3n6Zc1RbEyHd-00002000
    operations:0:sum_initial:amount:22500
    operations:0:sum_initial:currency:EUR
    operations:0:sum_converted:amount:22500
    operations:0:sum_converted:currency:EUR
    operations:0:code:0
    operations:0:message:Success
    operations:0:provider:id:1234
    operations:0:provider:payment_id:X1E6D23319ETBXT
    operations:0:provider:auth_code:
    operations:1:id:9529253065608;
    operations:1:type:payment confirmation
    operations:1:status:processing
    operations:1:date:2025-04-11T05:22:03+0000
    operations:1:created_date:2025-04-11T05:22:03+0000
    operations:1:request_id:9kLmga7BQwP2X8rT-EyuV3Hn6Zc1Rbd-00002000
    operations:1:sum_initial:amount:22500
    operations:1:sum_initial:currency:EUR
    operations:1:sum_converted:amount:22500
    operations:1:sum_converted:currency:EUR
    operations:1:code:29999
    operations:1:message:Awaiting processing
    operations:1:provider:id:10001
    operations:1:provider:payment_id:
    operations:1:provider:auth_code:
  3. Sort the strings in natural sort order:
    account:number:AT0000******2000
    customer:id:test@testmail.mail
    operations:0:code:0
    operations:0:created_date:2025-04-11T05:19:57+0000
    operations:0:date:2025-04-11T05:22:03+0000
    operations:0:id:9529253065607
    operations:0:message:Success
    operations:0:provider:auth_code:
    operations:0:provider:id:1234
    operations:0:provider:payment_id:X1E6D23319ETBXT
    operations:0:request_id:a7B9kLmQwP2X8rTg-uV3n6Zc1RbEyHd-00002000
    operations:0:status:success
    operations:0:sum_converted:amount:22500
    operations:0:sum_converted:currency:EUR
    operations:0:sum_initial:amount:22500
    operations:0:sum_initial:currency:EUR
    operations:0:type:sale
    operations:1:code:29999
    operations:1:created_date:2025-04-11T05:22:03+0000
    operations:1:date:2025-04-11T05:22:03+0000
    operations:1:id:9529253065608
    operations:1:message:Awaiting processing
    operations:1:provider:auth_code:
    operations:1:provider:id:10001
    operations:1:provider:payment_id:
    operations:1:request_id:9kLmga7BQwP2X8rT-EyuV3Hn6Zc1Rbd-00002000
    operations:1:status:processing
    operations:1:sum_converted:amount:22500
    operations:1:sum_converted:currency:EUR
    operations:1:sum_initial:amount:22500
    operations:1:sum_initial:currency:EUR
    operations:1:type:payment confirmation
    payment:date:2025-04-11T05:22:03+0000
    payment:description:
    payment:id:abc12345
    payment:method:Austrian Banks
    payment:status:awaiting confirmation
    payment:sum:amount:22500
    payment:sum:currency:EUR
    payment:type:purchase
    project_id:131221
  4. Join all strings into a single string by using semicolon (;) as a delimiter:
    account:number:AT0000******2000;customer:id:test@testmail.mail;operations:0:code:0;operations:0:created_date:2025-04-11T05:19:57+0000;operations:0:date:2025-04-11T05:22:03+0000;operations:0:id:9529253065607;operations:0:message:Success;operations:0:provider:auth_code:;operations:0:provider:id:1234;operations:0:provider:payment_id:X1E6D23319ETBXT;operations:0:request_id:a7B9kLmQwP2X8rTg-uV3n6Zc1RbEyHd-00002000;operations:0:status:success;operations:0:sum_converted:amount:22500;operations:0:sum_converted:currency:EUR;operations:0:sum_initial:amount:22500;operations:0:sum_initial:currency:EUR;operations:0:type:sale;operations:1:code:29999;operations:1:created_date:2025-04-11T05:22:03+0000;operations:1:date:2025-04-11T05:22:03+0000;operations:1:id:9529253065608;operations:1:message:Awaiting processing;operations:1:provider:auth_code:;operations:1:provider:id:10001;operations:1:provider:payment_id:;operations:1:request_id:9kLmga7BQwP2X8rT-EyuV3Hn6Zc1Rbd-00002000;operations:1:status:processing;operations:1:sum_converted:amount:22500;operations:1:sum_converted:currency:EUR;operations:1:sum_initial:amount:22500;operations:1:sum_initial:currency:EUR;operations:1:type:payment confirmation;payment:date:2025-04-11T05:22:03+0000;payment:description:;payment:id:abc12345;payment:method:Austrian Banks;payment:status:awaiting confirmation;payment:sum:amount:22500;payment:sum:currency:EUR;payment:type:purchase;project_id:131221
  5. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key, and then encode the HMAC code by using the Base64 scheme:
    BpEgi+OOOWeuwoQjEEz6CP3Cwp5UxkxnkibOQSoBDYdcb8ab4CCm4yGxM05A6VK3XUi2hQMXIZGfVm7JLJ0pKw==
  6. Compare the generated signature and the one included in the response.

    In our case, the signatures differ which means that the response is invalid and must be ignored.

Signature verification form for responses via the Gate API

Below you can find an interactive form that allows you to test signature verification.

Example of verifying a response via the Data API

Suppose that you need to verify the signature of a response in the following scenario:

  • Signing key : secret.
  • The response body contains the following information:
    Figure 3. Response body
    {
      "operations": [
        {
          "project_id": "200",
          "operation_id": "9529253065607",
          "payment_id": "abc12345",
          "operation_type": "sale",
          "operation_status": "success",
          "payment_method_name": "Greek Banks",
          "payment_description": null,
          "operation_created_at": "2025-03-20T14:22:00+0000",
          "operation_completed_at": "2025-03-20T14:22:06+0000",
          "sum_initial": {
            "amount": 1000,
            "currency": "EUR"
          },
          "sum_converted": {
            "amount": 1000,
            "currency": "EUR"
          }
        }
      ],
      "signature": "EksxDdDygDQ30JKsfK6QSvubpNRSj3wtLI5FzWDJuNY0nEhLXt65Y77dtKMJRcd39NegA7YK1eojA2EB1hIbnQ=="
      }

The signature is verified as follows:

  1. Remove the signature parameter and its value.

    {
      "operations": [
        {
          "project_id": "200",
          "operation_id": "9529253065607",
          "payment_id": "abc12345",
          "operation_type": "sale",
          "operation_status": "success",
          "payment_method_name": "Greek Banks",
          "payment_description": null,
          "operation_created_at": "2025-03-20T14:22:00+0000",
          "operation_completed_at": "2025-03-20T14:22:06+0000",
          "sum_initial": {
            "amount": 1000,
            "currency": "EUR"
          },
          "sum_converted": {
            "amount": 1000,
            "currency": "EUR"
          }
        }
      ],
      "signature": "EksxDdDygDQ30JKsfK6QSvubpNRSj3wtLI5FzWDJuNY0nEhLXt65Y77dtKMJRcd39NegA7YK1eojA2EB1hIbnQ=="
    }
  2. Replace the data nested at the fourth level with an empty string:
    {
      "operations": [
        {
          "project_id": "200",
          "operation_id": "9529253065607",
          "payment_id": "abc12345",
          "operation_type": "sale",
          "operation_status": "success",
          "payment_method_name": "Greek Banks",
          "payment_description": null,
          "operation_created_at": "2025-03-20T14:22:00+0000",
          "operation_completed_at": "2025-03-20T14:22:06+0000",
          "sum_initial": {
            "amount": 1000,
            "currency": "EUR"
          },
          "sum_initial":"",
          "sum_converted": {
            "amount": 1000,
            "currency": "EUR"
          }
          "sum_converted":""
        }
      ]
    }
  3. Convert all parameter strings to UTF-8 as per algorithm description:
    operations:0:project_id:200
    operations:0:operation_id:9529253065607
    operations:0:payment_id:abc12345
    operations:0:operation_type:sale
    operations:0:operation_status:success
    operations:0:payment_method_name:Greek Banks
    operations:0:payment_description:
    operations:0:operation_created_at:2025-03-20T14:22:00+0000
    operations:0:operation_completed_at:2025-03-20T14:22:00+0000
    operations:0:sum_initial:
    operations:0:sum_converted:
  4. Sort the strings in natural sort order:
    operations:0:operation_completed_at:2025-03-20T14:22:00+0000
    operations:0:operation_created_at:2025-03-20T14:22:00+0000
    operations:0:operation_id:9529253065607
    operations:0:operation_status:success
    operations:0:operation_type:sale
    operations:0:payment_description:
    operations:0:payment_id:abc12345
    operations:0:payment_method_name:Greek Banks
    operations:0:project_id:200
    operations:0:sum_converted:
    operations:0:sum_initial:
  5. Join all strings into a single string by using semicolon (;) as a delimiter:
    operations:0:operation_completed_at:2025-03-20T14:22:06+0000;operations:0:operation_created_at:2025-03-20T14:22:00+0000;operations:0:operation_id:9529253065607;operations:0:operation_status:success;operations:0:operation_type:sale;operations:0:payment_description:;operations:0:payment_id:abc12345;operations:0:payment_method_name:Greek Banks;operations:0:project_id:200;operations:0:sum_converted:;operations:0:sum_initial:
  6. Calculate the HMAC code for the string by using the SHA-512 hash function and secret key, and then encode the HMAC code by using the Base64 scheme:
    Jc57w8OfFEF/FOjemn/3rRp+4U1Krx8AmLhPUW4+MEVJ+hE9ffspLT+NLAjGjVSweLYkOdzFG6xx6O6EFsmyIw==
  7. Compare the generated signature and the one included in the response.

    In our case, the signatures differ which means that the response is invalid and must be ignored.

Signature verification form for responses via the Data API

Below you can find an interactive form that allows you to test signature verification.

Note: When working with the requests sent to the platform via the Data API and the responses to such requests, mind the restriction for signing multi-level nested data included in the payload. The signature is generated for data with three levels of nesting and the data nested at deeper levels is ignored.