# Authentication

## 1. Signing an API Request

To ensure the security and integrity of your API requests, you need to sign your requests using [<mark style="color:blue;">HMAC SHA256</mark>](https://en.wikipedia.org/wiki/HMAC).&#x20;

This process involves creating a specific string from your request, and then generating a signature using your secret key.

{% hint style="warning" %}
**Requirement:** Request an API Key and Secret Key from Tyga Support at <support@tygapay.com> to access APIs.
{% endhint %}

## 2. Step-by-Step Guide

This guide provides a clear process for signing an API request, from converting a JSON body to a query string (handling nested fields with a dot `.`), constructing the string to sign, and finally signing it using <mark style="color:blue;">HMAC SHA256</mark>.&#x20;

This ensures your API requests are secure and authenticated.

### 2.1 **Create the Query String from JSON**

Depending on your programming language, use the following methods to convert a JSON object to a query string. Note that nested fields are handled using a dot (`.`).

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const qs = require('qs');

const jsonObj = {
    field1: "value2",
    nestedField: {
        nestedField1: "nestedValue1"
    }
};

const queryString = qs.stringify(jsonObj, { encode: false, delimiter: '&', allowDots: true });
console.log(queryString); // Output: field1=value2&nestedField.nestedField1=nestedValue1
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Collections.Generic;
using System.Web;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
        var jsonObj = new Dictionary<string, object>
        {
            { "field1", "value2" },
            { "nestedField", new Dictionary<string, object> { { "nestedField1", "nestedValue1" } } }
        };

        var flatDict = FlattenObject(jsonObj);
        var query = HttpUtility.ParseQueryString(string.Empty);

        foreach (var kvp in flatDict)
        {
            query[kvp.Key] = kvp.Value.ToString();
        }

        string queryString = query.ToString().Replace("&amp;", "&");
        Console.WriteLine(queryString); // Output: field1=value2&nestedField.nestedField1=nestedValue1
    }

    public static Dictionary<string, object> FlattenObject(Dictionary<string, object> obj, string parentKey = "", string sep = ".")
    {
        var items = new Dictionary<string, object>();
        foreach (var kvp in obj)
        {
            var newKey = string.IsNullOrEmpty(parentKey) ? kvp.Key : $"{parentKey}{sep}{kvp.Key}";

            if (kvp.Value is Dictionary<string, object> nestedDict)
            {
                var nestedItems = FlattenObject(nestedDict, newKey, sep);
                foreach (var nestedKvp in nestedItems)
                {
                    items[nestedKvp.Key] = nestedKvp.Value;
                }
            }
            else
            {
                items[newKey] = kvp.Value;
            }
        }
        return items;
    }
}
```

{% endtab %}

{% tab title="PHP" %}

```php
$jsonObj = [
    "field1" => "value2",
    "nestedField" => [
        "nestedField1" => "nestedValue1"
    ]
];

function flattenArray($arr, $parentKey = '', $sep = '.') {
    $items = [];
    foreach ($arr as $key => $value) {
        $newKey = $parentKey ? $parentKey . $sep . $key : $key;
        if (is_array($value)) {
            $items = array_merge($items, flattenArray($value, $newKey, $sep));
        } else {
            $items[$newKey] = $value;
        }
    }
    return $items;
}

$flatArr = flattenArray($jsonObj);
$queryString = urldecode(http_build_query($flatArr));
echo $queryString; // Output: field1=value2&nestedField.nestedField1=nestedValue1
```

{% endtab %}
{% endtabs %}

### 2.2 **Construct the String to Sign**

|                                                           |                                                      |
| --------------------------------------------------------- | ---------------------------------------------------- |
| FULL URL:                                                 | <https://api.com/users?test=xxx>                     |
| <mark style="color:green;">API PATH:</mark>               | /users?test=xxx                                      |
| <mark style="color:yellow;">QUERYSTRING FROM BODY:</mark> | field1=value2\&nestedField.nestedField1=nestedValue1 |

{% hint style="success" %}
Construct the string to sign by concatenating the <mark style="color:green;">API PATH</mark> and the <mark style="color:yellow;">QUERYSTRING FROM BODY</mark>:

stringToSign = "<mark style="color:green;">/users?test=xxx</mark><mark style="color:yellow;">field1=value2\&nestedField.nestedField1=nestedValue1</mark>"
{% endhint %}

### 2.3 **Sign the String using&#x20;**<mark style="color:blue;">**HMAC SHA256**</mark>

Use your programming language's libraries to sign the string using <mark style="color:blue;">HMAC SHA256</mark>.

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
const secretKey = 'your-secret-key';
const stringToSign = '/users?test=xxxfield1=value2&nestedField.nestedField1=nestedValue1';

const signature = crypto.createHmac('sha256', secretKey)
                        .update(stringToSign)
                        .digest('hex');
console.log(signature);
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Text;
using System.Security.Cryptography;

public class Program
{
    public static void Main()
    {
        string secretKey = "your-secret-key";
        string stringToSign = "/users?test=xxxfield1=value2&nestedField.nestedField1=nestedValue1";

        string signature = SignString(secretKey, stringToSign);
        Console.WriteLine(signature);
    }

    public static string SignString(string key, string data)
    {
        var encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(key);
        byte[] messageBytes = encoding.GetBytes(data);

        using (var hmacsha256 = new HMACSHA256(keyByte))
        {
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            return BitConverter.ToString(hashmessage).Replace("-", "").ToLower();
        }
    }
}
```

{% endtab %}

{% tab title="PHP" %}

```php
$secretKey = 'your-secret-key';
$stringToSign = '/users?test=xxxfield1=value2&nestedField.nestedField1=nestedValue1';

$signature = hash_hmac('sha256', $stringToSign, $secretKey);
echo $signature;
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tygapay.com/api/api-integration-setup/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
