Checking the refill status

ATTENTION: New Error Response Format In the near future, errors in our system will be classified as expected and unexpected. Depending on the type of error, the format of the JSON response will be changed. Please review the new formats on the Error Codes page. This change will be applied to all APIs in the AGWS system except ''Make a payment'.

Click here to view the old and new JSON error responses. Please take note of this update and ensure your system is ready for these changes, if necessary.

POST https://agwsapi.tarlanpayments.kz/showcase-gateway/api/v1/action/status

Headers

Name
Value

Content-Type

application/json

Body

Name
Type
Description

agent*

String

Showcase code in Tarlan system

project*

String

Project Code assigned by Tarlan

service_code*

String

Service ID on the showcase side

external_id*

String

Payment ID on the showcase side

Response

Name
Type
Description

status

bool

Request processing status

status_code

uint

Error code

message

string

Description of error

result

Object

The result of a query that contains information

-error_code

uint

Error code

-message

String

Error description

-data

Object

Information about data

--status_code

String

Transaction status code

--status_message

String

Description of transaction status

--username

String

User ID

--amount

Float

Amount credited

--datetime

String

Time of payment initiation in the storefront system. ISO 8601 Current Timestamp format

--project

String

Project Code assigned by Tarlan

--fail_reason

Object

Field Containing the Failure Reason

---code

Int

Rejection Reason Code

---message

String

Description of the Operation Rejection Reason

--external_id

String

Payment ID on the showcase side

-additional_data

Object

Additional information returned depending on the service (Depending on the service, this field may vary)

{    
    "status": true,
    "status_code": 0,
    "message": "Success",
    "result":{
        "error_code" : 0,
        "message": "",
        "data": {
            "status_code": "2",
            "status_message": "Transaction successfully processed",
            "username": "989898",
            "amount": 100,
            "datetime": "2022-12-01T15:45:00Z",
            "project": "mobile",
            "fail_reason": {
                "code": 100,
                "message": "Unknown reason, clarification required"
            },
            "service_code": "201106",
            "external_id": "200001",
        },
        "additional_data":{}
}

Examples of error responses before the changes

{
    "status": false,
    "status_code": 1041,
    "message": "Order not found",
    "result": {}
}

Examples of error responses after the changes

{
    "status": true,
    "status_code": 0,
    "message": "Success",
    "result": {
        "error_code" : 1041,
        "message": "Order not found",
        "data": {},
        "additional_data":{}
    }
}

Checking the refill status

package main

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

// Response представляет ответ от сервера

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

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

// CheckCashStatus отправляет POST-запрос и обрабатывает ответ
func CheckCashStatus(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
	}

	response := string(bodyBytes)

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

func main() {
	// URL Запроса
	RequestURL := "https://agwsapi.tarlanpayments.kz/showcase-gateway/api/v1/action/status"
	// Secret Проекта
	SecretKey := "12345"

	// Тело запроса
	requestBody := Body{
		Agent:       "agent",
		Project:     "project",
		ServiseCode: "service",
		ExternalID:  "reference_id",
	}

	// Генерация заголовка
	sign, err := MakeSign(requestBody, SecretKey)
	if err != nil {
		log.Println("Error generating signature:", err)
		return
	}
	// Отправка запроса
	Response, err := CheckCashStatus(requestBody, RequestURL, sign)
	if err != nil {
		log.Panic("Error sending request", err)
		return
	}

	if Response != "" {
		log.Println(Response)
	}
}

Last updated