API платёжного шлюза интернет-эквайринга Help

Уведомление об изменении статуса заказа

При изменении статуса заказа платежный шлюз автоматически отправляет уведомление.

Примечание

Схема работы

Сайт ТСПAPI ТСППлатёжный шлюзПлательщикСайт ТСПAPI ТСППлатёжный шлюзПлательщикЗакрытие вкладки/браузера плательщиком не влияет на отправку callback-уведомленияВыполняет оплатуОбработка транзакцииОтправка callbackПеренаправление плательщика на hppRedirectUrl

Форматы

Параметры: POST, application/x-www-form-urlencoded

Пример получаемых данных:

ORDER_ID: 2000000005753 ORDER_RID: null ORDER_STATUS: Preparing

Параметры: POST, application/json;charset=UTF-8

Пример получаемых данных:

{ "order_status": "Preparing", "order_title": "TT00001", "order_description": "Заказ № 123", "order_id": 2000006686461 }

Примеры обработки запросов

Формат по умолчанию (Form Data)
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) === '/bspb/callback') { $order_id = $_POST['ORDER_ID'] ?? null; $order_rid = $_POST['ORDER_RID'] ?? null; $order_status = $_POST['ORDER_STATUS'] ?? null; if ($order_id !== null && $order_rid !== null && $order_status !== null) { echo "ORDER_ID: $order_id\n"; echo "ORDER_RID: $order_rid\n"; echo "ORDER_STATUS: $order_status\n"; http_response_code(200); echo "POST запрос успешно получен\n"; } else { http_response_code(400); echo "Ошибка: не все необходимые поля предоставлены\n"; } } else { http_response_code(404); echo "Ресурс не найден\n"; }
from flask import Flask, request app = Flask(__name__) @app.route('/bspb/callback', methods=['POST']) def bspb_callback(): if request.method == 'POST': data = request.form order_id = data.get('ORDER_ID') order_rid = data.get('ORDER_RID') order_status = data.get('ORDER_STATUS') print('ORDER_ID:', order_id) print('ORDER_RID:', order_rid) print('ORDER_STATUS:', order_status) return 'POST запрос успешно получен', 200 else: return 'Ресурс не найден', 404 if __name__ == '__main__': app.run(host='0.0.0.0', port=443, ssl_context=('server.pem', 'server.key'))
from typing import Optional from fastapi import FastAPI, Form app = FastAPI() @app.post("/bspb/callback", status_code=200) async def bspb_callback(order_id: str = Form(..., alias="ORDER_ID"), order_rid: Optional[str] = Form(None, alias="ORDER_RID"), order_status: str = Form(..., alias="ORDER_STATUS") ): print(f"ORDER_ID: {order_id}") print(f"ORDER_RID: {order_rid}") print(f"ORDER_STATUS: {order_status}") return {"status": "success", "message": "POST запрос успешно получен"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=443, ssl_keyfile="server.key", ssl_certfile="server.pem")
const https = require('https'); const fs = require('fs'); const querystring = require('querystring'); const options = { key: fs.readFileSync('server.key'), cert: fs.readFileSync('server.pem') }; const server = https.createServer(options, (req, res) => { if (req.method === 'POST' && req.url === '/bspb/callback') { let body = ''; req.on('data', (chunk) => { body += chunk.toString(); }); req.on('end', () => { const parsedBody = querystring.parse(body); console.log('ORDER_ID:', parsedBody.ORDER_ID); console.log('ORDER_RID:', parsedBody.ORDER_RID); console.log('ORDER_STATUS:', parsedBody.ORDER_STATUS); res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('POST запрос успешно получен'); }); } else { res.writeHead(404, {'Content-Type': 'text/plain'}); res.end('Ресурс не найден'); } }); const port = 443; server.listen(port, () => { console.log(`Сервер запущен на порту ${port}`); });
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/bspb/callback", func(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { err := r.ParseForm() if err != nil { http.Error(w, "Ошибка при парсинге данных", http.StatusBadRequest) return } orderID := r.FormValue("ORDER_ID") orderRID := r.FormValue("ORDER_RID") orderStatus := r.FormValue("ORDER_STATUS") fmt.Println("ORDER_ID:", orderID) fmt.Println("ORDER_RID:", orderRID) fmt.Println("ORDER_STATUS:", orderStatus) w.WriteHeader(http.StatusOK) w.Write([]byte("POST запрос успешно получен\n")) } else { http.NotFound(w, r) } }) err := http.ListenAndServeTLS(":443", "server.pem", "server.key", nil) if err != nil { fmt.Println("Ошибка запуска сервера:", err) } }
// Зависимости (Maven / Gradle): // Source: https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web // // Конфигурация HTTPS (application.properties): // server.port=443 // server.ssl.enabled=true // server.ssl.key-store=classpath:server.p12 // server.ssl.key-store-password=password // server.ssl.key-store-type=PKCS12 // // Или для PEM формата: // server.port=443 // server.ssl.enabled=true // server.ssl.certificate=classpath:server.pem // server.ssl.certificate-private-key=classpath:server.key package ru.bspb.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.logging.Logger; @SpringBootApplication public class CallbackApplication { static void main(String[] args) { SpringApplication.run(CallbackApplication.class, args); } } @RestController class CallbackController { private static final Logger LOGGER = Logger.getLogger(CallbackController.class.getName()); @PostMapping("/bspb/callback") public ResponseEntity<String> bspbCallback( @RequestParam(value = "ORDER_ID") String orderId, @RequestParam(value = "ORDER_RID", required = false) String orderRid, @RequestParam(value = "ORDER_STATUS") String orderStatus ) { LOGGER.info(() -> String.format("ORDER_ID: %s", orderId)); LOGGER.info(() -> String.format("ORDER_RID: %s", orderRid)); LOGGER.info(() -> String.format("ORDER_STATUS: %s", orderStatus)); return ResponseEntity.status(HttpStatus.OK).body("POST запрос успешно получен"); } }
JSON
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) === '/bspb/callback') { $json = file_get_contents('php://input'); $data = json_decode($json, true); $order_id = $data['order_id'] ?? null; $order_status = $data['order_status'] ?? null; $order_title = $data['order_title'] ?? null; $order_description = $data['order_description'] ?? null; if ($order_id !== null && $order_status !== null && $order_title !== null && $order_description !== null) { header('Content-Type: application/json'); http_response_code(200); echo json_encode([ "status" => "success", "message" => "Данные получены", "received_id" => $order_id ]); } else { http_response_code(400); echo "Ошибка: не все необходимые поля предоставлены"; } } else { http_response_code(404); echo "Ресурс не найден"; }
from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/bspb/callback', methods=['POST']) def bspb_callback(): data = request.get_json() if not data: return 'Ошибка: ожидался JSON', 400 order_id = data.get('order_id') order_status = data.get('order_status') order_title = data.get('order_title') order_description = data.get('order_description') if all([order_id, order_status, order_title, order_description]): print(f'ORDER_ID: {order_id}') print(f'STATUS: {order_status}') print(f'TITLE: {order_title}') print(f'DESCRIPTION: {order_description}') return jsonify({"message": "JSON callback получен успешно"}), 200 else: return 'Ошибка: отсутствуют обязательные поля', 400 if __name__ == '__main__': app.run(host='0.0.0.0', port=443, ssl_context=('server.pem', 'server.key'))
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Order(BaseModel): order_id: int order_status: str order_title: str order_description: str @app.post("/bspb/callback", status_code=200) async def bspb_callback(order: Order): print( f"ID: {order.order_id}, Status: {order.order_status}, Title: {order.order_title}, Description: {order.order_description}") return {"status": "success", "message": "JSON received"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=443, ssl_keyfile="server.key", ssl_certfile="server.pem")
const https = require('https'); const fs = require('fs'); const options = { key: fs.readFileSync('server.key'), cert: fs.readFileSync('server.pem') }; const server = https.createServer(options, (req, res) => { if (req.method === 'POST' && req.url === '/bspb/callback') { let body = ''; req.on('data', (chunk) => { body += chunk.toString(); }); req.on('end', () => { try { const data = JSON.parse(body); const {order_id, order_status, order_title, order_description} = data; if (order_id && order_status && order_title && order_description) { console.log('ORDER_ID:', order_id); console.log('STATUS:', order_status); console.log('TITLE:', order_title); console.log('DESCRIPTION:', order_description); res.writeHead(200, {'Content-Type': 'application/json'}); res.end(JSON.stringify({status: 'ok', received: order_id})); } else { res.writeHead(400); res.end('Missing required fields'); } } catch (e) { res.writeHead(400); res.end('Invalid JSON format'); } }); } else { res.writeHead(404, {'Content-Type': 'text/plain'}); res.end('Ресурс не найден'); } }); const port = 443; server.listen(port, () => { console.log(`Сервер запущен на порту ${port}`); });
package main import ( "encoding/json" "fmt" "net/http" ) type OrderCallback struct { OrderID int `json:"order_id"` OrderStatus string `json:"order_status"` OrderTitle string `json:"order_title"` OrderDescription string `json:"order_description"` } func main() { http.HandleFunc("/bspb/callback", func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { var callback OrderCallback err := json.NewDecoder(r.Body).Decode(&callback) if err != nil { http.Error(w, "Некорректный JSON", http.StatusBadRequest) return } fmt.Printf("ORDER_ID: %d\n", callback.OrderID) fmt.Printf("STATUS: %s\n", callback.OrderStatus) fmt.Printf("TITLE: %s\n", callback.OrderTitle) fmt.Printf("DESCRIPTION: %s\n", callback.OrderDescription) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`{"status": "success"}`)) } else { http.NotFound(w, r) } }) err := http.ListenAndServeTLS(":443", "server.pem", "server.key", nil) if err != nil { fmt.Println("Ошибка запуска сервера:", err) } }
// Зависимости (Maven / Gradle): // Source: https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web // // Конфигурация HTTPS (application.properties): // server.port=443 // server.ssl.enabled=true // server.ssl.key-store=classpath:server.p12 // server.ssl.key-store-password=password // server.ssl.key-store-type=PKCS12 // // Или для PEM формата: // server.port=443 // server.ssl.enabled=true // server.ssl.certificate=classpath:server.pem // server.ssl.certificate-private-key=classpath:server.key package ru.bspb.example; import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; @SpringBootApplication public class CallbackJsonApplication { static void main(String[] args) { SpringApplication.run(CallbackJsonApplication.class, args); } } @RestController class CallbackJsonController { private static final Logger LOGGER = Logger.getLogger(CallbackJsonController.class.getName()); @PostMapping("/bspb/callback") public ResponseEntity<Map<String, String>> bspbCallback(@RequestBody OrderCallback order) { LOGGER.info(() -> String.format("ORDER_ID: %d, STATUS: %s, TITLE: %s, DESCRIPTION: %s", order.orderId, order.orderStatus, order.orderTitle, order.orderDescription)); Map<String, String> response = new HashMap<>(); response.put("status", "success"); response.put("message", "JSON received"); return ResponseEntity.status(HttpStatus.OK).body(response); } // Класс для десериализации JSON static class OrderCallback { @JsonProperty("order_id") private long orderId; @JsonProperty("order_status") private String orderStatus; @JsonProperty("order_title") private String orderTitle; @JsonProperty("order_description") private String orderDescription; public long getOrderId() { return orderId; } public void setOrderId(long orderId) { this.orderId = orderId; } public String getOrderStatus() { return orderStatus; } public void setOrderStatus(String orderStatus) { this.orderStatus = orderStatus; } public String getOrderTitle() { return orderTitle; } public void setOrderTitle(String orderTitle) { this.orderTitle = orderTitle; } public String getOrderDescription() { return orderDescription; } public void setOrderDescription(String orderDescription) { this.orderDescription = orderDescription; } } }
21 мая 2026