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

ВНИМАНИЕ: Новый формат ответа для ошибок

В ближайшее время в нашей системе ошибки будут разделены на ожидаемые и неожидаемые. Это приведет к изменению формата JSON-ответа в зависимости от типа ошибки. Пожалуйста, ознакомьтесь с изменениями на странице Коды Ошибок. Изменения будут применены ко всем API в системе AGWS, за исключением методов «Проведение платежа».

Нажмите здесь, чтобы просмотреть старые и новые ответы об ошибках JSON. Обратите внимание на это обновление и убедитесь, что ваша система готова к изменениям, если это необходимо.

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

POST https://agwsapi.tarlanpayments.kz/showcase-gateway/api/v1/user/check

Headers

Name
Value

Content-Type

application/json

X-Signature

Body

Name
Type
Description

username*

String

Идентификатор пользователя

agent*

String

Код витрины в системе Tarlanpayments

project*

String

Код Проекта присваиваемый Tarlanpayments

service_code*

String

Идентификатор услуги на стороне витрины

info

Object

{
    "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

Name
Type
Description

status

bool

Статус обработки запроса

status_code

uint

Код ошибки

message

string

Описание ошибки

result

Object

Результат запроса, в котором содержится информация

-error_code

Integer

Код ошибки

-message

String

Описание ошибки

-account_status

Integer

-amount

Float

Фиксированная сумма платежа

-upper_commission

Float

Верхняя коммиссия

-fail_reason

Object

-info

Object

-additional_data

Object

Дополнительная информация возвращаемая в зависимости от услуги(В зависимости от услуги данное поле может меняться)

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

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

"info": {
    "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"
    }
}
param
type
Desc

in_date

timestamp

Время начала парковки

left_free_time_minutes

Float

Кол-во оставшихся минут на выезд

sum

Float

Стоимость парковки

current_balance

Float

Текущий баланс

{
    "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"
        },
        "info": {
            "parking": {
                "in_date": "2024-08-02T12:24:07+05:00",
                "left_free_time_minutes": 0,
                "sum": 118,
                "current_balance": -1
            }
        }
    }
}

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

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

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

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

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

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"`
	AdditionalData struct{} `json:"additional_data"`
}

// 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)
	}
}

Last updated