# Проверка состояния аккаунта

{% hint style="danger" %}
**ВНИМАНИЕ: Новый формат ответа для ошибок**

В ближайшее время в нашей системе ошибки будут разделены на **ожидаемые** и **неожидаемые**. Это приведет к изменению формата JSON-ответа в зависимости от типа ошибки. Пожалуйста, ознакомьтесь с изменениями на странице [**Коды Ошибок**](https://docs.tarlanpayments.kz/agws/kody-oshibok). Изменения будут применены ко всем API в системе AGWS, за исключением методов «[Проведение платежа](https://docs.tarlanpayments.kz/agws/provedenie-platezha)».

Нажмите [здесь](#primery-otvetov-ob-oshibkakh-do-vneseniya-izmenenii), чтобы просмотреть старые и новые ответы об ошибках JSON. Обратите внимание на это обновление и убедитесь, что ваша система готова к изменениям, если это необходимо.
{% endhint %}

## Проверка статуса аккаунта по username

<mark style="color:green;">`POST`</mark> `https://agwsapi.tarlanpayments.kz/showcase-gateway/api/v1/user/check`

**Headers**

| Name         | Value                                                                                        |
| ------------ | -------------------------------------------------------------------------------------------- |
| Content-Type | `application/json`                                                                           |
| X-Signature  | [Авторизационный хэш](https://docs.tarlanpayments.kz/platezhnyi-shlyuz/formirovanie-podpisi) |

**Body**

<table><thead><tr><th width="199">Name</th><th width="128">Type</th><th>Description</th></tr></thead><tbody><tr><td>username<mark style="color:red;">*</mark></td><td>String</td><td>Идентификатор пользователя</td></tr><tr><td>agent<mark style="color:red;">*</mark></td><td>String</td><td>Код витрины в системе Tarlanpayments</td></tr><tr><td>project<mark style="color:red;">*</mark></td><td>String</td><td>Код Проекта присваиваемый Tarlanpayments</td></tr><tr><td>service_code<mark style="color:red;">*</mark></td><td>String</td><td>Идентификатор услуги на стороне витрины</td></tr><tr><td>info</td><td>Object</td><td><a href="#dopolnitelnyi-parametry-info">Дополнительные параметры </a>зависящие от категории услуг</td></tr></tbody></table>

```json
{
    "username": "1234AAA05",
    "agent": "agent1",
    "project": "project1",
    "service_code": "123",
    "info": {
        "parking": {
            "in_date": "2024-08-02T12:24:07+05:00",
            "left_free_time_minutes": 0,
            "sum": 118,
            "current_balance": -1,
            "zone": "1223-123",
            "duration":1,
            "coordinates": {
                "latitude": 123.12,
                "longitude": 123.0212
            },
            "phone": "77077777777"
        }
    }
}
```

**Response**

<table><thead><tr><th width="225">Name</th><th width="127">Type</th><th>Description</th></tr></thead><tbody><tr><td>status</td><td>bool</td><td>Статус обработки запроса</td></tr><tr><td>status_code</td><td>uint</td><td>Код ошибки</td></tr><tr><td>message</td><td>string</td><td>Описание ошибки</td></tr><tr><td>result</td><td>Object</td><td>Результат запроса, в котором содержится информация</td></tr><tr><td>-error_code</td><td>Integer</td><td>Код ошибки</td></tr><tr><td>-message</td><td>String</td><td>Описание ошибки</td></tr><tr><td>-account_status</td><td>Integer</td><td>Состояние аккаунта. Подробнее см. <a href="kody-sostoyaniya-akkaunta">в справочнике состояния аккаунта</a></td></tr><tr><td>-amount</td><td>Float</td><td>Фиксированная сумма платежа</td></tr><tr><td>-upper_commission</td><td>Float</td><td>Верхняя коммиссия</td></tr><tr><td>-fail_reason</td><td>Object</td><td><a href="prichina-otkloneniya-operacii">Причина</a> неуспеха проведения платежа</td></tr><tr><td>-info</td><td>Object</td><td><a href="#dopolnitelnyi-parametry-info">Дополнительные параметры </a>зависящие от категории услуг</td></tr></tbody></table>

## Дополнительные параметры (info)

В теле ответа приходят дополнительные параметры зависящие от категории услуги, тип услуги записывается как  ключ в объекте info <br>

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

<pre class="language-json"><code class="lang-json"><strong>"info": {
</strong>    "parking": {
        "in_date": "2024-08-02T12:24:07+05:00",
        "left_free_time_minutes": 0,
        "sum": 118,
        "current_balance": -1,
        "zone":"1223-123",
        "coordinates": {
            "latitude":123.12,
            "longitude":123.0212
        },
        "duration":1,
        "phone":"77077777777"
    }
}
</code></pre>

<table><thead><tr><th width="287">param</th><th>type</th><th>Desc</th></tr></thead><tbody><tr><td>in_date</td><td>timestamp</td><td>Время начала парковки</td></tr><tr><td>left_free_time_minutes</td><td>Float</td><td>Кол-во оставшихся минут на выезд</td></tr><tr><td>sum</td><td>Float</td><td>Стоимость парковки</td></tr><tr><td>current_balance</td><td>Float</td><td>Текущий баланс</td></tr><tr><td>zone </td><td>string</td><td>Зона парковки</td></tr><tr><td>coordinates</td><td>object</td><td>Объект с координатами</td></tr><tr><td>├latitude</td><td>float64</td><td>Широта</td></tr><tr><td>├longitude</td><td>float64</td><td>Долгота</td></tr><tr><td>duration</td><td>uint</td><td>Длительность в секундах</td></tr><tr><td>phone</td><td>string</td><td>Номер телефона</td></tr></tbody></table>
{% endtab %}

{% tab title="finance" %}

<pre class="language-json"><code class="lang-json"><strong>"info": {
</strong>    "finance": {
        "phone": "7777777777",
        "credit_days": 10,
        "contracts": [
            {
                "contract_id":"123456789",
                "contract_name":"Contract name",
                "contract_date": "03.01.2025 12:59:59",
                "client": "John Doe",
                "amount": 12.12,
                "total_amount": 12.12,
                "min": 1.23,
                "max": 12.12
            },
            {
                "contract_id":"987654321",
                "contract_name":"Name Contract",
                "contract_date": "17.02.2025 23:23:39",
                "client": "Doe John",
                "amount": 1292.64,
                "total_amount": 1292.64,
                "min": 100.21,
                "max": 1292.64
            }
        ]
    }
}

</code></pre>

<table><thead><tr><th width="287">param</th><th>type</th><th>Desc</th></tr></thead><tbody><tr><td>phone</td><td>string</td><td>Номер телефона</td></tr><tr><td>credit_days</td><td>uint</td><td>Количество дней для продления кредита</td></tr><tr><td>contracts</td><td>array</td><td>Массив контрактов</td></tr><tr><td>├contract_id</td><td>string</td><td>ID договора</td></tr><tr><td>├contract_name</td><td>string</td><td>Название контракта</td></tr><tr><td>├contract_date</td><td>string</td><td>Дата контракта</td></tr><tr><td>├client</td><td>string</td><td>Имя клиента</td></tr><tr><td>├amount</td><td>float</td><td>Сумма ежемесячного погашения</td></tr><tr><td>├total_amount</td><td>float</td><td>Остаток суммы по кредиту</td></tr><tr><td>├min</td><td>float</td><td>Минимальная сумма погашения</td></tr><tr><td>├max</td><td>float</td><td>Максимальная сумма погашения</td></tr></tbody></table>
{% endtab %}

{% tab title="utilities" %}

<pre class="language-json"><code class="lang-json"><strong>"info": {
</strong>    "utilities": {
        "customer": {
            "address": "г.Алматы, ул. Пушкина д. 10008 кв. 111112"
        },
        "invoice": {
            "invoice_id": "89878766212421",
            "period_date": "2025-01",
            "formed_date": "2025-01-11 21:39:00",
            "expire_date": "2025-01-21"
        },
        "service": [
<strong>            {
</strong>                "fix_sum": 1234.32,
                "service_id": "1123",
                "service_name": "Service Name",
                "measure": "тг/кВт.сағ.",
                "fix_count": 0,
                "prev_count": 500,
                "last_count": 570,
                "debt_sum": 0,
                "debt_info": "",
                "prev_count_date": "2024-12-31",
                "last_count_date": "2025-01-25",
                "sum": 0,
                "pay_sum": 0,
                "is_counter_service": true
            },
            {
                "fix_sum": 1234.32,
                "service_id": "1123",
                "service_name": "Service Name",
                "measure": "тг/кВт.сағ.",
                "fix_count": 0,
                "prev_count": 500,
                "last_count": 570,
                "debt_sum": 0,
                "debt_info": "",
                "prev_count_date": "2024-12-31",
                "last_count_date": "2025-01-25",
                "sum": 0,
                "pay_sum": 0,
                "is_counter_service": false
            }                
        ]
    }
}
</code></pre>

<table><thead><tr><th width="287">param</th><th width="161">type</th><th>Desc</th></tr></thead><tbody><tr><td>customer</td><td>object</td><td>Объяект с информацией о клиенте</td></tr><tr><td>├address</td><td>string</td><td>Адрес клиента</td></tr><tr><td>invoice</td><td>object</td><td>Объект с данными о счете</td></tr><tr><td>├invoice_id</td><td>string</td><td>Уникальный идентификатор счета</td></tr><tr><td>├period_date</td><td>string</td><td>Период счета</td></tr><tr><td>├formed_date</td><td>string</td><td>Дата формирования счета</td></tr><tr><td>├expire_date</td><td>string</td><td>Дата окончания срока оплаты</td></tr><tr><td>service</td><td>array</td><td>Массив сервисов</td></tr><tr><td>├fix_sum</td><td>float</td><td>Фиксированная сумма к оплате</td></tr><tr><td>├service_id</td><td>string</td><td>Идентификатор услуги</td></tr><tr><td>├service_name</td><td>string</td><td>Название сервиса</td></tr><tr><td>├measure</td><td>string</td><td>Единица измерения услуги</td></tr><tr><td>├fix_count</td><td>float</td><td>Фиксированное показание счетчика</td></tr><tr><td>├prev_count</td><td>float</td><td>Предыдущие показания счетчика</td></tr><tr><td>├last_count</td><td>float</td><td>Последние показания счетчика</td></tr><tr><td>├debt_sum</td><td>float</td><td>Сумма задолженности</td></tr><tr><td>├debt_info</td><td>string</td><td>Информация о задолженности</td></tr><tr><td>├prev_count_date</td><td>string</td><td>Дата предыдущих показаний</td></tr><tr><td>├last_count_date</td><td>string</td><td>Дата текущих показаний</td></tr><tr><td>├sum</td><td>float</td><td>Общая сумма</td></tr><tr><td>├pay_sum</td><td>float</td><td>Сумма которую платит клиент</td></tr><tr><td>├is_counter_service</td><td>bool</td><td>Является ли услуга счетчиком (<code>true</code> – да, <code>false</code> – нет)</td></tr></tbody></table>
{% endtab %}

{% tab title="confirmation" %}

```json
"info": {
    "confirmation": {
        "code": "967056",
        "expiration_date": "2025-09-09T13:22:18Z" //Дата и Время в стандарте RFC 3339
    }
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="200: OK Пример успешного ответа" %}

```json
{
  "status": true,
  "message": "Success",
  "status_code": 0,
  "result": {
    "error_code": 0,
    "message": "This account is active",
    "account_status": 1,
    "info": {
      "parking": {
        "in_date": "2025-01-06T16:32:00Z",
        "left_free_time_minutes": 0,
        "sum": 1137,
        "current_balance": -1,
        "coordinates": {
          "latitude": 0,
          "longitude": 0
        },
        "zone": "",
        "duration": 0,
        "phone": ""
      }
    },
    "fail_reason": {},
    "amount": 1138,
    "upper_commission": 122
  }
}
```

{% endtab %}

{% tab title="200: OK Пример неуспешного ответа" %}

```json
{
    "status": true,
    "status_code": 0,
    "message": "Success",
    "result":{
        "error_code" : 0,
        "message": "This account is inactive",
        "account_status": 0,
        "additional_data": {},
        "fail_reason": {
            "code": 100,
            "message": "Unknown reason, clarification required"
        }
    }
}
```

{% endtab %}
{% endtabs %}

#### Примеры ответов об ошибках *до* внесения изменений

{% tabs %}
{% tab title="404 Not Found" %}

```json
{
    "status": false,
    "status_code": 1407,
    "message": "Cache: item not found",
    "result": {}
}
```

{% endtab %}

{% tab title="400 Bad Request" %}

```json
{
    "status": false,
    "status_code": 1014,
    "message": "Invalid signature",
    "result": {}
}
```

{% endtab %}
{% endtabs %}

#### Примеры ответов об ошибках *после* внесения изменений

{% tabs %}
{% tab title="200 OK: Ожидаемая ошибка" %}

```json
{
    "status": true,
    "status_code": 0,
    "message": "Success",
    "result": {
        "error_code": 1407,
        "message": "Cache: item not found",
        "data": null,
    }
}
```

{% endtab %}

{% tab title="400 Bad Request: Неожидаемая ошибка" %}

```json
{
    "status": false,
    "status_code": 1014,
    "message": "Invalid signature",
    "result": {}
}
```

{% endtab %}
{% endtabs %}

Проверка аккаунта

{% tabs %}
{% tab title="Golang" %}
{% code fullWidth="true" %}

```go
package main

import (
	"bytes"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"sort"
)

const (
	// agent - код витрины на стороне Tarlan
	agent = "agent"
	// serviceCode - идентификатор услуги витрины
	serviceCode = "service"
	// project - код проекта на стороне Tarlan
	project = "project"
	// requestURL - URL для отправки запроса
	requestURL = "https://agwsapi.tarlanpayments.kz/showcase-gateway/api/v1/user/check"
	// secretKey - secret проекта
	secretKey = "12345"
)

// Response представляет ответ от сервера
type Response struct {
	Status     bool   `json:"status"`
	StatusCode uint32 `json:"status_code"`
	Message    string `json:"message"`
	Result     Result `json:"result"`
}

type Result struct {
	ErrorCode      int      `json:"error_code"`
	Message        string   `json:"message"`
	AccountStatus  uint64   `json:"account_status"`
}

// Body представляет структуру запроса
type Body struct {
	Agent       string `json:"agent"`
	UserName    string `json:"username"`
	Project     string `json:"project"`
	ServiseCode string `json:"service_code"`
}

// MakeSign генерирует подпись для HTTP-запроса
func MakeSign(body Body, secretKey string) (string, error) {
	// Конвертируем структуру в map для сортировки
	dataMap := make(map[string]interface{})
	jsonData, _ := json.Marshal(body)
	json.Unmarshal(jsonData, &dataMap)

	// Удаляем "additional_data", если нужно
	delete(dataMap, "additional_data")

	// Сортируем ключи по алфавиту
	keys := make([]string, 0, len(dataMap))
	for key := range dataMap {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	// Создаем отсортированный JSON
	sortedData := make(map[string]interface{})
	for _, key := range keys {
		sortedData[key] = dataMap[key]
	}

	// Преобразуем отсортированные данные в JSON
	sortedJson, err := json.Marshal(sortedData)
	if err != nil {
		return "", err
	}

	// Кодируем JSON в base64
	base64EncodedData := base64.StdEncoding.EncodeToString(sortedJson)
	// Конкатенируем base64-данные с секретом
	dataToSign := base64EncodedData + secretKey

	// Хешируем SHA-256
	sha256Hash := sha256.Sum256([]byte(dataToSign))
	sign := hex.EncodeToString(sha256Hash[:])

	return sign, nil
}

// CheckLogin отправляет POST-запрос и обрабатывает ответ
func CheckLogin(body Body, url, signature string) (string, error) {
	// Конвертируем структуру в JSON для отправки
	jsonData, err := json.Marshal(body)
	if err != nil {
		return "", err
	}

	// Создаем и отправляем POST-запрос
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return "", err
	}

	// Устанавливаем подпись запроса
	req.Header.Set("X-Signature", signature)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	// Чтение и обработка ответа
	bodyBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	jsonResponse := string(bodyBytes)

	// Структура для парсинга ответа
	var response Response
	err = json.Unmarshal([]byte(jsonResponse), &response)
	if err != nil {
		return "", err
	}

	log.Printf("Status-%v, %v", resp.StatusCode, jsonResponse)

	// Определение поля message
	var message string

	// Извлечение ответа
	if resp.StatusCode == http.StatusOK {
	if response.StatusCode == 0 {
	message = response.Result.Message + " " + body.UserName
	} else {
	message = response.Message
	}
	}
	if resp.StatusCode != http.StatusOK {
	message = response.Message
	}

	// Вывод ответа и результата
	return message, nil
}

func main() {
	// login пользователя
	var login string = "login"

	// requestBody тело запроса
	requestBody := Body{
		Agent:       agent,
		UserName:    login,
		Project:     project,
		ServiseCode: serviceCode,
	}

	// Генерация заголовка
	sign, err := MakeSign(requestBody, secretKey)
	if err != nil {
		log.Println("Error generating signature: ", err)
		return
	}

	// Отправка запроса
	Message, err := CheckLogin(requestBody, requestURL, sign)
	if err != nil {
		log.Panic("Error sending request ", err)
		return
	}

	// Вывод message из лога
	if Message != "" {
		log.Println(Message)
	}
}

```

{% endcode %}
{% endtab %}
{% endtabs %}
