Page tree
Skip to end of metadata
Go to start of metadata

Пример конфигурации

HPD

В этом плагине нестандартный путь для подтверждения платежа (вебхуков): /sber_sbp/<instance_name>/notify

Пример конфига HPD
plugins:
  sber_sbp:
    main:
      bank_code: sber_sbp
      bank_account: sber_sbp_account
      currency: RUB
      currency_number: 643
      member_id: "00001234"
      terminal_id: 12345678 # он же TID
      description: ''
      secret_key: secret
      certificate_path: /opt/hydra/hpd/cert_sber.pem
      api:
        url: https://mc.api.sberbank.ru:443/prod/
        username: client_id
        password: client_secret

listeners:
  http:
    plain:
      plugins: [sber_sbp/main]

workers:
  - listeners: [http/plain]

URL для подтверждения платежа в гидре в данном случае:  <hpd_base_url>/sber_sbp/main/notify, причём Сберу принципиально, чтобы этот урл оканчивался на /notify, следует учесть это при настройке.

Сбер принимает запросы только со своим сертификатом, поэтому нужно сложить его формате .pem в certificate_path при этом не забыв выдать пользователю HPD (UID можно посмотреть в статье: Докеризация приложений) права на чтение файла сертификата.

Сертификат генерируется в формате pkc12 для преобразования используется команда: 
p12toPem
openssl pkcs12 -in certificate_name.p12 -out cert_sber.pem -nodes

Если при генерации сертификата получаем сообщение вида

Error
Error outputting keys and certificates
8032BFF6167F0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:355:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()

то в команду генерации добавляем ключ legacy

p12toPem
openssl pkcs12 -in certificate_name.p12 -out cert_sber.pem -nodes -legacy

Промышленный стенд: https://mc.api.sberbank.ru:443/prod/qr/order/v3/creation
Тестовый: https://mc.api.sberbank.ru:443/prod/qr/order/stub/v3/creation

URL до точки авторизации не меняется. Только сам запрос.(https://mc.api.sberbank.ru:443/prod/tokens/v3/oauth - не меняется)

HUPO

Пример конфига HUPO
payments:
  gateways:
    sber_sbp:
      default:
        hpd_url: http://127.0.0.1:9080
        hpd_plugin_name: sber_sbp
        hpd_plugin_instance: main
        hpd_secret: secret
 
 
  available_payment_gateways:
    - sber_sbp

Проверка статуса платежа

Проверка статуса платежа через curl

1) Получить Base64 кодировку логина-пароля для авторизации

echo -n "API_USERNAME:API_PASSWORD" | base64

2) Получить токен. Здесь и далее URL для продакшн среды. Для тестовой среды https://dev.api.sberbank.ru/prod/ (но это не точно)

 curl -X POST "https://mc.api.sberbank.ru:443/prod/tokens/v3/oauth" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Accept: application/json" \
  -H "Authorization: Basic $BASE64$" \
  -H "rquid: 9b4e7a1d3c6f8025e9b2d5a7c1f08e34" \
  --cert cert_sber.pem \
  --key cert_sber.pem \
  -d "grant_type=client_credentials" \
  -d "scope=https://api.sberbank.ru/qr/order.status" -k

Где:

$BASE64$ - логин и пароль в кодироке Base64

rquid - Строка в 32 символа ([0-9]|[a-f]|[A-F]){32})

cert и key - Путь до сертификата Сбера


3) Получить статус платежа

curl -X POST "https://mc.api.sberbank.ru:443/prod/qr/order/v3/status" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "RqUID: 3d8c1f6a9e2b4d70c5a8f1e3b7d90c46" \
  -H "Authorization: Bearer %TOKEN%" \
  --cert cert_sber.pem \
  --key cert_sber.pem \
  -d '{
    "rq_uid": "3d8c1f6a9e2b4d70c5a8f1e3b7d90c46",
    "rq_tm": "2026-04-02T17:34:03Z",
    "tid": "12345678",
    "partner_order_number": "22595020701"
  }' -k

Где:

RqUID и rq_uid - Строка в 32 символа ([0-9]|[a-f]|[A-F]){32})

%TOKEN% - Токен полученный на этапе 2

cert и key - Путь до сертификата Сбера

rq_tm - Текущая дата в фомарте %Y-%m-%dT%H:%M:%SZ

tid - ID терминала

partner_order_number - ID платежного поручения в Гидре

Скрипт для проверки статуса платежа

Можно использовать скрипт, куда передается только ID платежного поручения. В самом скрипте задаются логины-пароли, ID терминала и путь до сертификата:

check_status.sh
#!/bin/bash

#==============================================================================
# Скрипт получения статуса заказа через API СБП (Сбербанк)
# Использование: ./check_status.sh <partner_order_number>
#==============================================================================

set -e  # Выход при ошибке

#------------------------------------------------------------------------------
# НАСТРОЙКИ (заполните перед использованием)
#------------------------------------------------------------------------------
CLIENT_ID="ВАШ_CLIENT_ID"
CLIENT_SECRET="ВАШ_CLIENT_SECRET"
TID="ID_Терминала"  # ID терминала

# Пути к сертификату (один файл с сертификатом и ключом)
CERT_FILE="cert_sber.pem"

# Endpoint'ы (PROD)
TOKEN_URL="https://mc.api.sberbank.ru:443/prod/tokens/v3/oauth"
STATUS_URL="https://mc.api.sberbank.ru:443/prod/qr/order/v3/status"

#------------------------------------------------------------------------------
# Вспомогательные функции
#------------------------------------------------------------------------------

# Генерация случайной строки из 32 hex-символов [0-9a-f]
generate_hex32() {
    openssl rand -hex 16
}

# Получение текущей даты в формате ISO 8601 UTC
get_iso_timestamp() {
    date -u +"%Y-%m-%dT%H:%M:%SZ"
}

# Получение токена доступа
get_access_token() {
    local rq_uid="$1"
    
    # Формируем Basic Auth: base64(client_id:client_secret)
    local credentials=$(echo -n "${CLIENT_ID}:${CLIENT_SECRET}" | base64 -w 0)
    
    local response
    response=$(curl -s -X POST "$TOKEN_URL" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -H "Accept: application/json" \
        -H "Authorization: Basic ${credentials}" \
        -H "rquid: ${rq_uid}" \
        --cert "${CERT_FILE}" \
        --key "${CERT_FILE}" \
        -k \
        -d "grant_type=client_credentials" \
        -d "scope=https://api.sberbank.ru/qr/order.status")
    
    # Парсим ответ
    local access_token
    access_token=$(echo "$response" | grep -oP '"access_token"\s*:\s*"\K[^"]+' || true)
    
    if [ -z "$access_token" ]; then
        echo "❌ Ошибка получения токена: $response" >&2
        return 1
    fi
    
    echo "$access_token"
}

# Запрос статуса заказа
check_order_status() {
    local token="$1"
    local partner_order="$2"
    local rq_uid="$3"
    local rq_tm="$4"
    
    curl -s -X POST "$STATUS_URL" \
        -H "Content-Type: application/json" \
        -H "Accept: application/json" \
        -H "RqUID: ${rq_uid}" \
        -H "Authorization: Bearer ${token}" \
        --cert "${CERT_FILE}" \
        --key "${CERT_FILE}" \
        -k \
        -d "{
            \"rq_uid\": \"${rq_uid}\",
            \"rq_tm\": \"${rq_tm}\",
            \"tid\": \"${TID}\",
            \"partner_order_number\": \"${partner_order}\"
        }"
}

#------------------------------------------------------------------------------
# Основная логика
#------------------------------------------------------------------------------

main() {
    # Проверка аргументов
    if [ $# -ne 1 ]; then
        echo "Использование: $0 <partner_order_number>" >&2
        exit 1
    fi
    
    local PARTNER_ORDER_NUMBER="$1"
    
    # Проверка наличия сертификата
    if [ ! -f "$CERT_FILE" ]; then
        echo "❌ Файл сертификата не найден: $CERT_FILE" >&2
        exit 1
    fi
    
    # 1. Генерируем идентификаторы и время
    local token_rq_uid=$(generate_hex32)      # для запроса токена
    local status_rq_uid=$(generate_hex32)     # для запроса статуса
    local rq_tm=$(get_iso_timestamp)
    
    # 2. Получаем токен
    echo "🔄 Получение токена..." >&2
    local access_token
    access_token=$(get_access_token "$token_rq_uid")
    
    if [ $? -ne 0 ] || [ -z "$access_token" ]; then
        exit 1
    fi
    echo "✅ Токен получен" >&2
    
    # 3. Запрашиваем статус заказа
    echo "🔄 Запрос статуса для partner_order_number: $PARTNER_ORDER_NUMBER" >&2
    local api_response
    api_response=$(check_order_status "$access_token" "$PARTNER_ORDER_NUMBER" "$status_rq_uid" "$rq_tm")
    
    # 4. Возвращаем ответ (на stdout для дальнейшего использования)
    echo "$api_response"
    
    # Опционально: вывод статуса заказа в читаемом виде (на stderr)
    local error_code order_state
    error_code=$(echo "$api_response" | grep -oP '"error_code"\s*:\s*"\K[^"]+' || echo "N/A")
    order_state=$(echo "$api_response" | grep -oP '"order_state"\s*:\s*"\K[^"]+' || echo "N/A")
    
    if [ "$error_code" = "000000" ]; then
        echo "📊 Статус заказа: $order_state" >&2
    else
        echo "⚠️  Код ошибки: $error_code" >&2
    fi
}

# Запуск
main "$@"








  • No labels