# Проведение платежа

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

**Headers**

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

**Body**

<table><thead><tr><th width="185">Name</th><th width="92">Type</th><th width="488">Description</th></tr></thead><tbody><tr><td>username<mark style="color:red;">*</mark></td><td>String</td><td>Идентификатор пользователя</td></tr><tr><td>amount<mark style="color:red;">*</mark></td><td>Float</td><td>Сумма транзакции</td></tr><tr><td>agent<mark style="color:red;">*</mark></td><td>String</td><td>Код витрины в системе Tarlan</td></tr><tr><td>project<mark style="color:red;">*</mark></td><td>String</td><td>Код Проекта присваиваемый Tarlan-ом</td></tr><tr><td>service_code<mark style="color:red;">*</mark></td><td>String</td><td>Идентификатор услуги на стороне витрины</td></tr><tr><td>external_id<mark style="color:red;">*</mark></td><td>String</td><td>Уникальный идентификатор платежа на стороне витрины</td></tr><tr><td>datetime<mark style="color:red;">*</mark></td><td>String</td><td>Время инициации платежа в системе витрины. Формат ISO 8601 Current Timestamp</td></tr><tr><td>callback_url</td><td>String</td><td>URL на который будет отправлен <a href="callback-platezhnoi-sistemy">callback запрос</a></td></tr></tbody></table>

**Response**

<table><thead><tr><th width="193">Параметры</th><th width="128">Формат</th><th>Описание</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>uint</td><td>Код ошибки</td></tr><tr><td>-message</td><td>String</td><td>Описание ошибки</td></tr><tr><td>-data</td><td>Object</td><td>Информация о данных</td></tr><tr><td>--status_code</td><td>String</td><td>Код статуса транзакции</td></tr><tr><td>--status_message</td><td>String</td><td>Описание статуса транзакции</td></tr><tr><td>--username</td><td>String</td><td>Идентификатор пользователя</td></tr><tr><td>--amount</td><td>Float</td><td>Зачисленная сумма </td></tr><tr><td>--datetime</td><td>String</td><td>Время инициации платежа в системе витрины. Формат ISO 8601 Current Timestamp</td></tr><tr><td>--project</td><td>String</td><td>Код Проекта присваиваемый Tarlan-ом</td></tr><tr><td>--service_code</td><td>String</td><td>Идентификатор услуги на стороне витрины</td></tr><tr><td>--external_id</td><td>String</td><td>Идентификатор платежа на стороне витрины</td></tr><tr><td>--fail_reason</td><td>Object</td><td><a href="prichina-otkloneniya-operacii">Причина</a> неуспеха проведения платежа</td></tr><tr><td>---code</td><td>Int</td><td>Код причины отклонения операции</td></tr><tr><td>---message</td><td>String</td><td>Описание причины отклонения операции</td></tr><tr><td>--info</td><td>Object</td><td><a href="../proverka-sostoyaniya-akkaunta#confirmation">Дополнительные параметры </a>зависящие от категории услуг</td></tr></tbody></table>

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

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "status": true,
    "message": "Success",
    "status_code": 0,
    "result": {
        "error_code": 0,
        "message": "",
        "data": {
            "external_id": "111111111111111",
            "project": "project-1",
            "service_code": "service_code1",
            "username": "415304197",
            "amount": 9.56,
            "datetime": "2025-01-01T01:01:01+05:00",
            "status_code": "2",
            "status_message": "Transaction successfully processed"
        },
        "fail_reason": {},
        "info": {
            "confirmation": {
                "code": "967056",
                "expiration_date": "2025-09-09T13:22:18Z"
            }
        }
    }
}
</code></pre>

{% endtab %}

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

```json
{
    "status": true,
    "message": "Success",
    "status_code": 0,
    "result": {
        "error_code": 0,
        "message": "",
        "data": {
            "external_id": "111111111111111",
            "project": "project-1",
            "service_code": "service_code1",
            "username": "415304197",
            "amount": 9.56,
            "datetime": "1747393302",
            "status_code": "1",
            "status_message": "Transaction created"
        },
        "fail_reason": {},
        "info": {
            "confirmation": {
                "code": "967056",
                "expiration_date": "2025-09-09T13:22:18Z"
            }
        }
    }
}

```

{% endtab %}

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

```json
{
    "status": true,
    "status_code": 0,
    "message": "Success",
    "result" : {
        "error_code" : 1042,
        "message": "Duplicate external_id",
        "data": null,
        "additional_data":null
    }
}
```

{% endtab %}

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

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

{% endtab %}
{% endtabs %}

Проведение платежа

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

```go
package main

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

const (
	// agent - код витрины на стороне Tarlan
	agent = "agent"
	// serviceCode - идентификатор услуги витрины
	serviceCode = "service"
	// project - код проекта на стороне Tarlan
	project = "project"
	// requestURL - URL для отправки запроса
	requestURL = "https://agwsapi.tarlanpayments.kz/showcase-gateway/api/v1/action/cash-in"
	// 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      uint32                 `json:"error_code"`
	Message        string                 `json:"message"`
	Data           Data                   `json:"data"`
}

type Data struct {
	StatusCode    string    `json:"status_code"`
	StatusMessage string    `json:"status_message"`
	Username      string    `json:"username"`
	Amount        float64   `json:"amount"`
	Datetime      time.Time `json:"datetime"`
	Project       string    `json:"project"`
	ServiceCode   string    `json:"service_code"`
	ExternalID    string    `json:"external_id"`
}

// Body представляет структуру запроса
type Body struct {
	UserName    string  `json:"username"`
	Agent       string  `json:"agent"`
	Project     string  `json:"project"`
	ServiseCode string  `json:"service_code"`
	Amount      float64 `json:"amount"`
	ExternalID  string  `json:"external_id"`
	DateTime    string  `json:"datetime"`
	CallBackUrl string  'json:"callback_url,omitempty"`
}

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

	// Сортируем ключи по алфавиту
	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
}

// MakeCashIn отправляет POST-запрос и обрабатывает ответ
func MakeCashIn(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 && response.Result.ErrorCode == 0 {
	message = response.Result.Data.StatusMessage + ", reference " + response.Result.Data.ExternalID
	} else {
	message = response.Result.Message
	}
	}
	if resp.StatusCode != http.StatusOK {
	message = response.Message
	}

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

func main() {
	var (
		// login - логин пользователя
		login string = "login"
		// externalID - номер заказа
		externalID string = "reference"
		// amount - сумма платежа
		amount float64 = 10.01
	)
	// Тело запроса
	requestBody := Body{
		UserName:    login,
		Agent:       agent,
		Project:     project,
		ServiseCode: serviceCode,
		Amount:      amount,
		ExternalID:  externalID,
		DateTime:    time.Now().Format(time.RFC3339),
	}

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

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

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

	}
}

```

{% endtab %}
{% endtabs %}
