# Transaction Inquiry

***

Valify offers an API to retrieve transaction results, any time after the service has been called. This API receives a reference to the transaction being inquired, either the Transaction ID returned in the service's response, or the Access Token used to call the API, and returns the service's data.

{% hint style="info" %}
This is a very sensitive API, as it allows access to data for all your transactions. Therefore, to secure your data, it is a requirement that the Transaction Inquiry response is encrypted in transit and decrypted on the recipient's side.
{% endhint %}

To gain access to this API, you need to contact Valify to avail this service. You also need to generate an RSA 4096 key pair. The private key is stored on the recipient side, and the public key is provided to Valify to be stored. This way, the API response payload can be encrypted for you to decrypt it on your side. Please contact **techsupport@valify.me** for more information.

The RSA 4096 key pair can be generated using the following commands:

* **With** Passphrase:

`$ openssl genrsa -des3 -out private.pem 4096`\
`$ openssl rsa -in private.pem -outform PEM -pubout -out public.pem`

* **Without** Passphrase:

`$ openssl genrsa -out private.pem 4096`\
`$ openssl rsa -in private.pem -outform PEM -pubout -out public.pem`

The encryption process works as follows:

1. Each time this API is called, a new AES 256 key is generated.
2. The response data (JSON string) is encrypted with the AES key.
3. The AES key is then encrypted with the public key provided to Valify.
4. The encrypted key and encrypted data are encoded into base64 format is sent in the API response.
5. The response recipient should then decode the base64-encoded key and data, decrypt the AES key using their RSA private key, and use the decrypted AES key to decrypt the transaction data, producing a JSON string.

The transaction reference options are:

* **Transaction ID:** can be found in the Service API response. Only the data for this particular transaction is returned. The response would look like this:

`{`\
&#x20;   `'transaction_id': <str>,`\
&#x20;   `'token': '<str>',`\
&#x20;   `'time': '<dd/MM/yy hh:mm:ss',`\
&#x20;   `'status': <bool>,`\
&#x20;   `'service': <str>,`\
&#x20;   `'data': {`\
&#x20;       `...`\
&#x20;   `}`\
`}`

* **Access Token:** token used to authenticate one or more Valify service API calls. In this case, the API returns a list of all transactions called using this access token. The response would look like this:

`{`\
&#x20;   `'transactions': [`\
&#x20;       `{`\
&#x20;           `'transaction_id': <str>,`\
&#x20;           `'token': '<str>',`\
&#x20;           `'time': '<dd/MM/yy hh:mm:ss',`\
&#x20;           `'status': <bool>,`\
&#x20;           `'service': <str>,`\
&#x20;           `'data': {`\
&#x20;               `...`\
&#x20;           `}`\
&#x20;       `},`\
&#x20;       `...`\
&#x20;   `]`\
`}`

**Note:** The access token used to authenticate the Transaction Inquiry API call (added to the header), is different from the access token added to the request body, which references the transaction(s) being inquired by this API call.

## Transaction Inquire (Transaction ID)

<mark style="color:green;">`POST`</mark> `https://<base-url>/api/v1/transaction/inquire/`

#### Headers

| Name          | Type   | Description            |
| ------------- | ------ | ---------------------- |
| Content-Type  | string | application/json       |
| Authorization | string | Bearer \<access-token> |

#### Request Body

| Name            | Type   | Description                                                       |
| --------------- | ------ | ----------------------------------------------------------------- |
| bundle\_key     | string | A bundle key provided to you by Valify.                           |
| transaction\_id | string | Transaction reference ID, returned in the service API's response. |

{% tabs %}
{% tab title="200 " %}
```python
{
    'key': '<string>',
    'data': '<string>'
}
```
{% endtab %}

{% tab title="400 " %}
```python
{
    "message": "Bad Request – invalid request received (e.g. missing Bundle key, required parameters or invalid json) | Make sure all the required parameters are included"
}
```
{% endtab %}

{% tab title="401 " %}
```python
{
    "message": "Unauthorized – your Bundle key is invalid"
}
```
{% endtab %}

{% tab title="403 " %}
```python
{
    "message": "Forbidden – specified access_token could not be found"
}
```
{% endtab %}

{% tab title="404 " %}
```python
{
    "message": "Not Found"
}
```
{% endtab %}

{% tab title="415 " %}
```python
{
    "message": "Unsupported Media Type"
}
```
{% endtab %}

{% tab title="422 " %}
```python
{
    "message": "<error-description>",
    "error_code": <valify-error-code>
}
```
{% endtab %}

{% tab title="500 " %}
```python
{
    "message": "Internal Server Error"
}
```
{% endtab %}
{% endtabs %}

## Transaction Inquire (Access Token)

<mark style="color:green;">`POST`</mark> `https://<base-url>/api/v1/transaction/inquire/`

#### Headers

| Name          | Type   | Description            |
| ------------- | ------ | ---------------------- |
| Content-Type  | string | application/json       |
| Authorization | string | Bearer \<access-token> |

#### Request Body

| Name          | Type   | Description                                                         |
| ------------- | ------ | ------------------------------------------------------------------- |
| bundle\_key   | string | A bundle key provided to you by Valify.                             |
| access\_token | string | Access Token used to authenticate the transaction(s) being inquired |

{% tabs %}
{% tab title="200 " %}
```python
{
    'key': '<string>',
    'data': '<string>'
}
```
{% endtab %}

{% tab title="400 " %}
```python
{
    "message": "Bad Request – invalid request received (e.g. missing Bundle key, required parameters or invalid json) | Make sure all the required parameters are included"
}
```
{% endtab %}

{% tab title="401 " %}
```python
{
```
{% endtab %}
{% endtabs %}

## Code Snippets

{% tabs %}
{% tab title="Python 3" %}
```python
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import base64
import json
import requests

private_key_str = "<rsa 4096 private key>"
private_key_bytes = str.encode(private_key_str)
private_key = serialization.load_pem_private_key(
        private_key_bytes,
        password=None,
        backend=default_backend()
    )
    
def unpad(s): return s[0:-s[-1]]

def decrypt_aes_key(encrypted_aes_key):
    aes_key = private_key.decrypt(
        encrypted_aes_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )
    return aes_key

def decrypt_data(enc_data, key, iv):
    backend = default_backend()
    sha256 = algorithms.AES(key)
    cipher = Cipher(sha256, modes.CBC(iv), backend=backend)
    decryptor = cipher.decryptor()

    dec_data = decryptor.update(enc_data)
    return unpad(dec_data)

def request_data():
    token = "<token>"
    data = {
        "bundle_key": "<bundle key>",
        "transaction_id": "<str>"
    }

    r = requests.post("https://<base-url>/api/v1/transaction/inquire/",
            json=data,
            headers={'Authorization' :'Bearer %s' % token}
        )
    return r.json()

response = request_data()
encrypted_data = base64.b64decode(response['data'])
encrypted_aes_key = base64.b64decode(response['key'])
iv = base64.b64decode(response['iv'])

aes_key = decrypt_aes_key(encrypted_aes_key)
decrypted_data = decrypt_data(encrypted_data, aes_key, iv)
data = json.loads(decrypted_data)

```
{% endtab %}
{% endtabs %}

## Postman Collection

{% file src="https://content.gitbook.com/content/mzgYXwSfAFtfOUAPpKlY/blobs/ep2GLO8sNHnwSKxTnQ34/Transaction%20Inquiry%20(v1).postman_collection.json" %}
Transaction Inquiry (v1)
{% endfile %}
