> ## Documentation Index
> Fetch the complete documentation index at: https://developer.transactbridge.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authorization

## Signature Generation

A signature is a mandatory header if using APIs. We are generating signatures using two details, the public **`API KEY`** and private **`SECRET KEY`**. There is a third **`PUBLISH KEY`** as well which is used for specific modules, but not requried for signature generation.

**Sample Example**:

Let partner Api key: `tb_test_q47Wqf04e1sIZu22kVwWBrDncigOkIPN`

Let partner Secret key: `tb_test_CT5u9ZeNMBEL884g6gP3`

**Step 1**: Create a new string by concatenating the API key and secret key with a colon in between. In our sample, the string becomes `"tb_test_q47Wqf04e1sIZu22kVwWBrDncigOkIPN:tb_test_CT5u9ZeNMBEL884g6gP3"`

**Step 2**: Create a signature using the above string using SHA-512 Algorithm. In our sample, the signature becomes `7ae85bcc8d0af6ceacd271da52d22d1fa091733b891ff133169ef959647f5d23232c6b6709150f1cbbabc5d2a815cb05b91448c3c3eabc9447343b689eba7606`

Below are different examples for different languages

> [tab] javascript
>
> ```javascript theme={null}
> const crypto = require('crypto');
> function generateChecksumString(str) {
>     return crypto.createHash('sha512').update(str).digest('hex');
> }
> let signature = generateChecksumString('tb_test_q47Wqf04e1sIZu22kVwWBrDncigOkIPN:tb_test_CT5u9ZeNMBEL884g6gP3');
> console.log(signature);
> // will print below signature
> // 7ae85bcc8d0af6ceacd271da52d22d1fa091733b891ff133169ef959647f5d23232c6b6709150f1cbbabc5d2a815cb05b91448c3c3eabc9447343b689eba7606
> ```

> [tab] php
>
> ```php theme={null}
> $shatest = ("tb_test_q47Wqf04e1sIZu22kVwWBrDncigOkIPN:tb_test_CT5u9ZeNMBEL884g6gP3");
> $sha512test = hash("sha512",$shatest);
> echo $sha512test;
> // will print below signature
> // 7ae85bcc8d0af6ceacd271da52d22d1fa091733b891ff133169ef959647f5d23232c6b6709150f1cbbabc5d2a815cb05b91448c3c3eabc9447343b689eba7606
> ```

> [tab] python
>
> ```python theme={null}
> import hashlib
> text = 'tb_test_q47Wqf04e1sIZu22kVwWBrDncigOkIPN:tb_test_CT5u9ZeNMBEL884g6gP3'
> m = hashlib.sha512(text.encode('UTF-8'))
> print(m.hexdigest())
> # will print below signature
> # 7ae85bcc8d0af6ceacd271da52d22d1fa091733b891ff133169ef959647f5d23232c6b6709150f1cbbabc5d2a815cb05b91448c3c3eabc9447343b689eba7606
> ```

> [tab] ruby
>
> ```ruby theme={null}
> def generate_signature(api_key, secret_key)
>     require 'digest'
>     # Concatenate API key and secret key with colon
>     signature_string = "#{api_key}:#{secret_key}"
>     puts "\nSignature String:"
>     puts signature_string
>     # Generate SHA-512 hash
>     signature = Digest::SHA512.hexdigest(signature_string)
>     puts "\nFinal Signature:"
>     puts signature
>     signature
>   end
> # --------- INVOCATION ----------
> api_key = "tb_test_q47Wqf04e1sIZu22kVwWBrDncigOkIPN"
> secret_key = "tb_test_CT5u9ZeNMBEL884g6gP3"
> signature = generate_signature(api_key, secret_key)
> ```

**Step 3**: Pass the public **`API KEY`** and the generated signature in the headers like below.

| **Headers** | **Type** | **Description** |
| - | - | - |
| Content-Type | String `Mandatory` | application/json |
| x-api-key | String `Mandatory` | Public API key provided by the platform to the partner. |
| x-signature | String `Mandatory` | A signature is created by the secret key provided by the platform to the partner. We use SHA-256 for creating signatures |

## Extended Signature Generation

An extended signature is an optional authorization mechanism. To enable this feature, the partner will need to enable the extended signature for the API in the platform. This adds extra layer by using the request body to generate the signature making each request more secure and unique. We are generating extended signatures using three details, the public **`API KEY`** and private **`SECRET KEY`** and the **`REQUEST BODY`**.

**Sample Example**:

Let partner Api key: `tb_test_q47Wqf04e1sIZu22kVwWBrDncigOkIPN`

Let partner Secret key: `tb_test_CT5u9ZeNMBEL884g6gP3`

Let request body:

**json**

```json theme={null}
{ "returnUrl": "https://www.transactbridge.com/demo", "quoteCurrCode": "USD" }
```

We use a specific format to create the token with three components.

**Token Format:** `${encodedAuthHeader}.${encodedPayload}.${signature}`

**Generating encodedAuthHeader**: We use a static payload `{"alg":"HS512","typ":"JWT"}` which is encoded with Base64 to create **`encodedAuthHeader`**. In our sample the generated output will be `"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9"`

**Generating encodedPayload:** Encode the request body with Base64 to generate **`encodedPayload`**. In our sample the generated output will be `"eyJyZXR1cm5VcmwiOiJodHRwczovL3d3dy50cmFuc2FjdGJyaWRnZS5jb20vZGVtbyIsInF1b3RlQ3VyckNvZGUiOiJVU0QifQ"`

**Generating Signature**: Create a string by concatenating the **`encodedAuthHeader`** and **`encodedPayload`** with a **`period`** in between. In our sample, the string becomes `"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJyZXR1cm5VcmwiOiJodHRwczovL3d3dy50cmFuc2FjdGJyaWRnZS5jb20vZGVtbyIsInF1b3RlQ3VyckNvZGUiOiJVU0QifQ"`. The string is then signed using SHA-512 Algorithm. In our sample the generated output will be `"LQKyKPK9Sw_cXyuBxr7gnaUICYY-zASOcKezCr5ed5Vly0E1DXR1-8TZSVfPc9AGymTCjt3kvg48Z93es3slew"`

**Generating Extended Signature**: Using the token format concate the different components to created the final extended signature. In our sample, the token becomes `"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJyZXR1cm5VcmwiOiJodHRwczovL3d3dy50cmFuc2FjdGJyaWRnZS5jb20vZGVtbyIsInF1b3RlQ3VyckNvZGUiOiJVU0QifQ.LQKyKPK9Sw_cXyuBxr7gnaUICYY-zASOcKezCr5ed5Vly0E1DXR1-8TZSVfPc9AGymTCjt3kvg48Z93es3slew"`

Pass the public **`API KEY`** and the generated token in the headers like below.

| **Headers** | **Type** | **Description** |
| - | - | - |
| Content-Type | String `Mandatory` | application/json |
| x-api-key | String `Mandatory` | Public API key provided by the platform to the partner. |
| x-signature-extended | String `Mandatory` | Token generated from the above steps. We use SHA-256 for creating signatures |

Below are different examples for different languages

> [tab] javascript
>
> ```javascript theme={null}
> const crypto = require('crypto');
> function getApiExtendedSignature(payload, secret) {
>     try {
>         const authHeadersJson = {
>             alg: 'HS512',
>             typ: 'JWT',
>         };
>         const authHeadersStr = JSON.stringify(authHeadersJson);
>         const encodedAuthHeader = Buffer.from(authHeadersStr, 'utf8').toString('base64url');
>         const payloadStr = JSON.stringify(payload);
>         const encodedPayload = Buffer.from(payloadStr, 'utf8').toString('base64url');
>         let token = `${encodedAuthHeader}.${encodedPayload}`;
>         const signature = crypto.createHmac('sha512', secret).update(token, 'utf8').digest('base64url');
>         return `${token}.${signature}`;
>     } catch (error) {
>         throw error;
>     }
> }
> let signature = getApiExtendedSignature(
>     { returnUrl: 'https://www.transactbridge.com/demo', quoteCurrCode: 'USD' },
>     'tb_test_CT5u9ZeNMBEL884g6gP3',
> );
> console.log(signature);
> // will print below signature
> // eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJyZXR1cm5VcmwiOiJodHRwczovL3d3dy50cmFuc2FjdGJyaWRnZS5jb20vZGVtbyIsInF1b3RlQ3VyckNvZGUiOiJVU0QifQ.LQKyKPK9Sw_cXyuBxr7gnaUICYY-zASOcKezCr5ed5Vly0E1DXR1-8TZSVfPc9AGymTCjt3kvg48Z93es3slew
> ```

> [tab] php
>
> ```php theme={null}
> function base64url_encode($data) {
>     // Base64 encode, then convert to URL-safe format and remove padding
>     return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
> }
> function getApiExtendedSignature($payload, $secret) {
>     try {
>         // Header
>         $authHeadersJson = [
>             "alg" => "HS512",
>             "typ" => "JWT"
>         ];
>         $encodedHeader = base64url_encode(json_encode($authHeadersJson, JSON_UNESCAPED_SLASHES));
>         $encodedPayload = base64url_encode(json_encode($payload, JSON_UNESCAPED_SLASHES));
>         $token = $encodedHeader . "." . $encodedPayload;
>         // HMAC-SHA512 Signature
>         $signature = hash_hmac("sha512", $token, $secret, true);
>         $encodedSignature = base64url_encode($signature);
>         return $token . "." . $encodedSignature;
>     } catch (Exception $e) {
>         throw $e;
>     }
> }
> // Example usage:
> $payload = [
>     "returnUrl" => "https://www.transactbridge.com/demo",
>     "quoteCurrCode" => "USD"
> ];
> $secret = "tb_test_CT5u9ZeNMBEL884g6gP3";
> $token = getApiExtendedSignature($payload, $secret);
> echo $token;
> // will print below signature
> // eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJyZXR1cm5VcmwiOiJodHRwczovL3d3dy50cmFuc2FjdGJyaWRnZS5jb20vZGVtbyIsInF1b3RlQ3VyckNvZGUiOiJVU0QifQ.LQKyKPK9Sw_cXyuBxr7gnaUICYY-z_
> ```

> [tab] python
>
> ```python theme={null}
>
> import json
> import hmac
> import hashlib
> import base64
> def base64url_encode(data: bytes) -> str:
>     """Encodes bytes into base64url without padding."""
>     return base64.urlsafe_b64encode(data).rstrip(b'=').decode('utf-8')
> def get_api_extended_signature(payload: dict, secret: str) -> str:
>     try:
>         # Header
>         auth_headers_json = {
>             "alg": "HS512",
>             "typ": "JWT"
>         }
>         encoded_header = base64url_encode(json.dumps(auth_headers_json).encode("utf-8"))
>         encoded_payload = base64url_encode(json.dumps(payload).encode("utf-8"))
>         token = f"{encoded_header}.{encoded_payload}"
>         # Signature using HMAC SHA-512
>         signature = hmac.new(
>             secret.encode("utf-8"),
>             token.encode("utf-8"),
>             hashlib.sha512
>         ).digest()
>         encoded_signature = base64url_encode(signature)
>         return f"{token}.{encoded_signature}"
>     except Exception as e:
>         raise e
> # Example usage
> payload = {"returnUrl":"https://www.transactbridge.com/demo","quoteCurrCode":"USD"}
> secret = "tb_test_CT5u9ZeNMBEL884g6gP3"
> signed_token = get_api_extended_signature(payload, secret)
> print(signed_token)
> # will print below signature
> # eyJhbGciOiAiSFM1MTIiLCAidHlwIjogIkpXVCJ9.eyJyZXR1cm5VcmwiOiAiaHR0cHM6Ly93d3cudHJhbnNhY3RicmlkZ2UuY29tL2RlbW8iLCAicXVvdGVDdXJyQ29kZSI6ICJVU0QifQ.ipnnEhwj0kzUhkGvcXD_maWFt17IVxdmR68ETrruku3WSif-NDMOMH-DrAu78tV-T9TxR2coO8lLM9A2EZSlfw
> ```

## Aggregators Authorization

An aggregator can use both signature or extended signature to authorize using their API keys. The aggregator might have multiple merchants and can use the same API keys of the main aggregator account to authorize. To call the aggregator's account API, don't pass **`x-partner-merchant-id`** .

| **Headers** | **Type** | **Description** |
| - | - | - |
| Content-Type | String `Mandatory` | application/json |
| x-api-key | String `Mandatory` | Public API key provided by the platform to the partner. |
| x-signature | String `Mandatory` | Token generated from the signature creation steps. We use SHA-256 for creating signatures  |
| x-partner-merchant-id | String `Mandatory` | Aggregator's merchant id to be passed here |
| x-signature-extended | String `Optional` | Token generated from the extended signature creation steps. We use SHA-256 for creating signatures |

## Encryption

Encryption is used to send sensitive data like credit card and debit card details in the S2S API. We use **RSA (Padding: `RSA_PKCS1_OAEP_PADDING`)** algorithm to encrypt the data string using a key.

To use this module, the partner must be **PCI-certified**. There is no need to integrate this if the partner is not using [Create Payment Request](https://developer.transactbridge.com/api-reference/sessions/generate-billing-session.md).

> [tab] JavaScript
>
> ```javascript theme={null}
> // Crypto module is used to encrypt a data string
> const crypto = require('crypto');
>
> // data is the payload string that needs to be encrypted
> // publicKey is provided to the partner by Transact Bridge
> function encryptRsa(publicKey, data) {
>     try {
>         const encryptMe = crypto.publicEncrypt(
>             {
>                 key: publicKey,
>                 padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
>             },
>             Buffer.from(data),
>         );
>
>         let hash = encryptMe.toString('base64');
>         return hash;
>     } catch (error) {
>         throw error;
>     }
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.