ТЗ на подключение Сбер QR СБП
---
## Подключение Сбер QR СБП к InSales
Техническое задание на интеграцию системы быстрых платежей (СБП) через Сбербанк для приема оплат по QR-кодам в интернет-магазине на платформе InSales.
---
### Описание решения
**Сбер QR СБП** — сервис приема платежей через Систему быстрых платежей с использованием QR-кодов. Позволяет клиентам оплачивать заказы мгновенно через мобильное приложение любого банка-участника СБП.
**Преимущества для магазина:**
- Минимальная комиссия (от 0.4% до 0.7%)
- Мгновенное зачисление средств
- Высокая конверсия оплаты
- Поддержка возвратов и отмен
- Отсутствие необходимости в эквайринге
**Преимущества для покупателей:**
- Оплата из любого банковского приложения
- Без комиссий для покупателя
- Быстрая авторизация платежа
- Безопасность транзакций
---
### Требования для подключения
| Компонент | Требование |
|:----------|:-----------|
| Платформа | InSales |
| Юридическое лицо | Договор со Сбербанком |
| Технические навыки | Разработка API интеграций |
| Сертификаты | SSL-сертификат для webhook |
| Сервер | Для обработки callback от СБП |
---
### Этап 1. Регистрация и подготовка
#### Регистрация в личном кабинете разработчика
Шаг 1. Создание аккаунта
**Процесс регистрации:**
1. Перейдите на [портал разработчика Сбербанка](https://auth.developer.sber.ru/)
2. Выберите способ регистрации:
- Через электронную почту
- Через Сбер ID
3. Подтвердите email и завершите регистрацию
> **Note:** Рекомендуется использовать корпоративную почту для регистрации.
Шаг 2. Заключение договора
**Необходимые документы:**
- [ ] Заявление на подключение к СБП
- [ ] Анкета по продукту "QR СБП"
- [ ] Копии учредительных документов
- [ ] Реквизиты расчетного счета
- [ ] Образцы подписей
**Процесс заключения:**
1. Обратитесь в ближайшее отделение Сбербанка для бизнеса
2. Заполните **Анкету по продукту QR СБП**
3. Предоставьте пакет документов
4. Дождитесь одобрения (обычно 3-5 рабочих дней)
5. Подпишите договор
> **Important:** Без действующего договора невозможно использовать API в продакшене.
Шаг 3. Настройка организации
**В личном кабинете разработчика:**
1. Создайте организацию:
```
Личный кабинет → Организации → Создать организацию
```
2. Заполните данные компании:
- ИНН
- Наименование
- Юридический адрес
- Контактные данные
3. Привяжите договор к организации:
```
Организация → Договоры → Добавить договор
```
4. Переключитесь в режим организации:
```
Верхнее меню → Переключиться на организацию
```
---
### Этап 2. Создание приложения и получение ключей
#### Создание приложения
Регистрация приложения
**Создание приложения в портале:**
1. Перейдите в раздел **"Мои приложения"**
2. Нажмите **"Создать приложение"**
3. Заполните форму:
| Поле | Значение |
|:-----|:---------|
| Название | "InSales QR СБП" |
| Тип | Серверное приложение |
| Redirect URI | `https://your-store.com/payment/callback` |
| Описание | Интеграция СБП для интернет-магазина |
4. Сохраните приложение
Получение учетных данных
**После создания приложения вы получите:**
```
ClientId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ClientSecret: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
```
> **Important:** Сохраните ClientId и ClientSecret в безопасном месте. ClientSecret показывается только один раз!
**Где хранить credentials:**
```bash
# .env файл на сервере
SBER_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
SBER_CLIENT_SECRET=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
SBER_MEMBER_ID=your_member_id
```
#### Создание и настройка сертификатов
Генерация сертификата
**Способ 1. Использование готового SSL-сертификата**
Если у вас уже есть SSL-сертификат для домена:
```bash
# Экспорт сертификата из существующего
openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes
```
**Способ 2. Генерация нового сертификата**
```bash
# Генерация приватного ключа
openssl genrsa -out private.key 2048
# Генерация запроса на сертификат (CSR)
openssl req -new -key private.key -out certificate.csr
# Самоподписанный сертификат (для тестирования)
openssl x509 -req -days 365 -in certificate.csr -signkey private.key -out certificate.crt
```
**Загрузка сертификата в портал:**
1. Перейдите в настройки приложения
2. Раздел **"Сертификаты"**
3. Загрузите публичную часть сертификата
4. Сохраните изменения
> **Note:** Для продакшена используйте сертификат от доверенного центра сертификации (Let's Encrypt, Comodo, и т.д.).
---
### Этап 3. Подключение к API
#### Подписка на тариф
Активация API
**Процесс подписки:**
1. Откройте [каталог API Сбербанка](https://api.developer.sber.ru/product/PlatiQR)
2. Найдите продукт **"QR для Продавца" API v3.0**
3. Нажмите **"Подписаться"**
4. Выберите ваше приложение
5. Подтвердите подписку
**Доступные эндпоинты:**
| Эндпоинт | Назначение |
|:---------|:-----------|
| `/order/v3/creation` | Создание заказа СБП |
| `/order/v3/status` | Проверка статуса платежа |
| `/order/v3/revocation` | Отмена/возврат платежа |
| `/qr/v3/order` | Генерация QR-кода |
---
### Этап 4. Техническая реализация
#### Архитектура решения
```
┌──────────────┐
│ Клиент │
│ (браузер) │
└──────┬───────┘
│ 1. Оформление заказа
▼
┌──────────────┐
│ InSales │
└──────┬───────┘
│ 2. Создание заказа
│ 3. Выбор оплаты СБП
▼
┌──────────────┐
│ Внешний │
│ сервис (API) │
└──────┬───────┘
│ 4. Запрос в Сбер API
▼
┌──────────────┐
│ Сбер СБП │
│ API │
└──────┬───────┘
│ 5. Возврат QR/ссылки
▼
┌──────────────┐
│ Клиент │
│ (оплата) │
└──────┬───────┘
│ 6. Callback после оплаты
▼
┌──────────────┐
│ Webhook │
│ обработчик │
└──────┬───────┘
│ 7. Обновление статуса
▼
┌──────────────┐
│ InSales │
│ (оплачено) │
└──────────────┘
```
---
### Реализация компонентов
#### Компонент 1. Внешний способ оплаты в InSales
Создание способа оплаты
**Настройка в админ-панели:**
```
InSales → Настройки → Оплата и доставка → Способы оплаты → Добавить способ оплаты
```
**Параметры:**
| Параметр | Значение |
|:---------|:---------|
| Название | "Оплата по QR СБП" |
| Тип | Внешний способ оплаты |
| URL обработчика | `https://your-server.com/api/sbp/create-payment` |
| Метод | POST |
| Активен | Да |
#### Компонент 2. Дополнительное поле заказа
Создание поля для статуса СБП
**Через API InSales:**
```javascript
// POST /admin/custom_status_for_orders.json
const createCustomField = async () => {
const response = await fetch('https://your-store.myinsales.ru/admin/custom_status_for_orders.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('api_key:api_password')
},
body: JSON.stringify({
custom_status: {
title: 'Статус СБП',
type: 'TextField',
handle: 'sbp_status'
}
})
});
return await response.json();
};
```
**Возможные статусы СБП:**
| Статус | Описание |
|:-------|:---------|
| `CREATED` | Заказ создан |
| `IN_PROGRESS` | Ожидание оплаты |
| `PAID` | Успешно оплачен |
| `REVOKED` | Отменен |
| `EXPIRED` | Истек срок оплаты |
#### Компонент 3. Внешний сервис обработки платежей
Создание заказа СБП
**Эндпоинт на вашем сервере:**
```javascript
// POST /api/sbp/create-payment
app.post('/api/sbp/create-payment', async (req, res) => {
const { order_id, amount, customer_phone } = req.body;
try {
// 1. Получение токена доступа
const accessToken = await getSberAccessToken();
// 2. Создание заказа в СБП
const sbpOrder = await createSberOrder({
orderId: order_id,
amount: amount,
phone: customer_phone,
accessToken: accessToken
});
// 3. Сохранение информации о заказе СБП
await updateInSalesOrderField(order_id, 'sbp_status', 'IN_PROGRESS');
await updateInSalesOrderField(order_id, 'sbp_order_id', sbpOrder.order_id);
// 4. Возврат ссылки на оплату
res.json({
success: true,
payment_url: sbpOrder.order_form_url,
qr_code: sbpOrder.payload
});
} catch (error) {
console.error('Ошибка создания заказа СБП:', error);
res.status(500).json({ success: false, error: error.message });
}
});
```
**Функция получения токена:**
```javascript
const getSberAccessToken = async () => {
const credentials = Buffer.from(
`${process.env.SBER_CLIENT_ID}:${process.env.SBER_CLIENT_SECRET}`
).toString('base64');
const response = await fetch('https://api.sberbank.ru/ru/prod/tokens/v2/oauth', {
method: 'POST',
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/x-www-form-urlencoded',
'RqUID': generateUUID(),
'Accept': 'application/json'
},
body: 'scope=https://api.sberbank.ru/qr/order.create'
});
const data = await response.json();
return data.access_token;
};
```
**Функция создания заказа:**
```javascript
const createSberOrder = async ({ orderId, amount, phone, accessToken }) => {
const orderData = {
rq_uid: generateUUID(),
rq_tm: new Date().toISOString(),
member_id: process.env.SBER_MEMBER_ID,
order_number: orderId,
order_create_date: new Date().toISOString(),
order_params_type: [
{
position_name: `Заказ №${orderId}`,
position_count: 1,
position_sum: Math.round(amount * 100), // В копейках
position_description: `Оплата заказа №${orderId}`
}
],
id_qr: generateUUID(),
order_sum: Math.round(amount * 100), // В копейках
currency: '643', // RUB
description: `Оплата заказа №${orderId}`,
sbp_member_id: phone ? formatPhone(phone) : null
};
const response = await fetch('https://api.sberbank.ru/qr/order/v3/creation', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
'RqUID': generateUUID()
},
body: JSON.stringify(orderData)
});
const data = await response.json();
if (data.error_code) {
throw new Error(`Сбер API Error: ${data.error_description}`);
}
return data;
};
```
Перенаправление клиента на оплату
**Клиентская часть (JavaScript на странице оплаты):**
```javascript
// После создания заказа СБП
const initiatePayment = async (orderId) => {
const response = await fetch('/api/sbp/create-payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
order_id: orderId,
amount: orderAmount,
customer_phone: customerPhone
})
});
const data = await response.json();
if (data.success) {
// Вариант 1: Перенаправление на страницу Сбербанка
window.location.href = data.payment_url;
// Вариант 2: Показ QR-кода на текущей странице
// displayQRCode(data.qr_code);
} else {
alert('Ошибка при создании платежа');
}
};
```
**HTML страницы оплаты:**
```html
Оплата заказа
Оплата заказа №{{ order.number }}
Сумма: {{ order.total_price }} ₽
Как оплатить:
- Откройте мобильное приложение вашего банка
- Найдите раздел "Оплата по QR" или "СБП"
- Наведите камеру на QR-код
- Подтвердите платеж
```
#### Компонент 4. Webhook для уведомлений от СБП
Обработчик callback от Сбербанка
**Эндпоинт для приема уведомлений:**
```javascript
// POST /api/sbp/callback
app.post('/api/sbp/callback', async (req, res) => {
const notification = req.body;
try {
// 1. Валидация подписи уведомления
if (!validateSberSignature(req)) {
console.error('Invalid signature');
return res.status(403).send('Invalid signature');
}
// 2. Извлечение данных
const {
order_id,
order_number,
order_state,
operation_type,
operation_sum
} = notification;
console.log(`Получено уведомление СБП: заказ ${order_number}, статус ${order_state}`);
// 3. Обновление статуса в InSales
await handlePaymentNotification({
orderNumber: order_number,
status: order_state,
amount: operation_sum / 100 // Из копеек в рубли
});
// 4. Возврат успешного ответа
res.status(200).send('OK');
} catch (error) {
console.error('Ошибка обработки callback:', error);
res.status(500).send('Error');
}
});
```
**Функция валидации подписи:**
```javascript
const validateSberSignature = (req) => {
const signature = req.headers['x-ibm-client-id'];
const body = JSON.stringify(req.body);
// Проверка подписи с использованием сертификата
const crypto = require('crypto');
const verify = crypto.createVerify('RSA-SHA256');
verify.update(body);
// Загрузка публичного ключа Сбербанка
const publicKey = fs.readFileSync('sber_public_key.pem');
return verify.verify(publicKey, signature, 'base64');
};
```
**Обработка статуса платежа:**
```javascript
const handlePaymentNotification = async ({ orderNumber, status, amount }) => {
// Поиск заказа в InSales
const order = await findInSalesOrder(orderNumber);
if (!order) {
throw new Error(`Заказ ${orderNumber} не найден`);
}
// Обработка статуса
switch (status) {
case 'PAID':
// Оплата успешна
await updateOrderPaymentStatus(order.id, 'paid');
await updateInSalesOrderField(order.id, 'sbp_status', 'PAID');
await sendPaymentConfirmationEmail(order);
break;
case 'REVOKED':
// Платеж отменен
await updateInSalesOrderField(order.id, 'sbp_status', 'REVOKED');
break;
case 'EXPIRED':
// Истек срок оплаты
await updateInSalesOrderField(order.id, 'sbp_status', 'EXPIRED');
await sendPaymentExpiredEmail(order);
break;
default:
console.log(`Неизвестный статус: ${status}`);
}
};
```
Регистрация webhook URL в Сбербанке
**В личном кабинете разработчика:**
1. Перейдите в настройки приложения
2. Раздел **"Callback URL"**
3. Укажите URL: `https://your-server.com/api/sbp/callback`
4. Сохраните изменения
> **Important:** URL должен быть доступен по HTTPS с валидным SSL-сертификатом.
**Требования к URL:**
- Протокол HTTPS обязателен
- Валидный SSL-сертификат (не самоподписанный)
- Доступность 24/7
- Время ответа < 5 секунд
- Возврат HTTP 200 OK при успешной обработке
#### Компонент 5. Обработка возвратов и отмен
Webhook на изменение заказа
**Создание webhook в InSales:**
```
InSales → Настройки → API и веб-хуки → Создать веб-хук
```
**Параметры:**
| Параметр | Значение |
|:---------|:---------|
| Событие | `order/update` |
| URL | `https://your-server.com/api/insales/order-update` |
| Формат | JSON |
**Обработчик webhook:**
```javascript
// POST /api/insales/order-update
app.post('/api/insales/order-update', async (req, res) => {
const order = req.body;
try {
// Проверка, что заказ оплачен через СБП
const sbpStatus = order.custom_fields?.sbp_status;
const sbpOrderId = order.custom_fields?.sbp_order_id;
if (!sbpOrderId || sbpStatus !== 'PAID') {
return res.status(200).send('OK');
}
// Обработка возврата или отмены
if (order.financial_status === 'returned' || order.financial_status === 'cancelled') {
console.log(`Инициация возврата для заказа ${order.number}`);
await processSberRefund({
orderId: sbpOrderId,
orderNumber: order.number,
amount: order.total_price,
reason: order.financial_status === 'returned' ? 'Возврат' : 'Отмена'
});
}
res.status(200).send('OK');
} catch (error) {
console.error('Ошибка обработки изменения заказа:', error);
res.status(500).send('Error');
}
});
```
Запрос возврата в СБП
**Функция возврата платежа:**
```javascript
const processSberRefund = async ({ orderId, orderNumber, amount, reason }) => {
try {
// 1. Получение токена
const accessToken = await getSberAccessToken();
// 2. Формирование запроса на отмену
const refundData = {
rq_uid: generateUUID(),
rq_tm: new Date().toISOString(),
member_id: process.env.SBER_MEMBER_ID,
order_id: orderId,
id_qr: generateUUID(),
cancel_operation_sum: Math.round(amount * 100), // В копейках
operation_currency: '643',
operation_description: reason || 'Возврат средств'
};
// 3. Отправка запроса
const response = await fetch('https://api.sberbank.ru/qr/order/v3/revocation', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
'RqUID': generateUUID()
},
body: JSON.stringify(refundData)
});
const data = await response.json();
if (data.error_code) {
throw new Error(`Ошибка возврата: ${data.error_description}`);
}
console.log(`Возврат для заказа ${orderNumber} успешно инициирован`);
// 4. Обновление статуса в InSales
await updateInSalesOrderField(orderNumber, 'sbp_status', 'REFUND_PENDING');
return data;
} catch (error) {
console.error('Ошибка возврата платежа:', error);
// Уведомление администратора о проблеме
await sendAdminNotification({
type: 'refund_error',
order: orderNumber,
error: error.message
});
throw error;
}
};
```
**Обработка результата возврата:**
```javascript
// В обработчике callback от СБП добавляем:
case 'REFUNDED':
await updateInSalesOrderField(order.id, 'sbp_status', 'REFUNDED');
await updateOrderPaymentStatus(order.id, 'refunded');
await sendRefundConfirmationEmail(order);
break;
```
---
### Проверка статуса платежа
Ручная проверка статуса
**Эндпоинт проверки:**
```javascript
// GET /api/sbp/status/:order_id
app.get('/api/sbp/status/:order_id', async (req, res) => {
const { order_id } = req.params;
try {
// Получение информации о заказе из InSales
const order = await getInSalesOrder(order_id);
const sbpOrderId = order.custom_fields.sbp_order_id;
if (!sbpOrderId) {
return res.json({ status: 'NOT_FOUND' });
}
// Запрос статуса в Сбер API
const accessToken = await getSberAccessToken();
const response = await fetch(`https://api.sberbank.ru/qr/order/v3/status?order_id=${sbpOrderId}`, {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Accept': 'application/json',
'RqUID': generateUUID()
}
});
const data = await response.json();
res.json({
status: data.order_state,
sbp_order_id: sbpOrderId,
amount: data.order_sum / 100
});
} catch (error) {
console.error('Ошибка проверки статуса:', error);
res.status(500).json({ error: error.message });
}
});
```
---
### Тестирование интеграции
#### Тестовая среда (Sandbox)
Настройка тестового окружения
**Endpoints для тестирования:**
```javascript
const SBER_API_ENDPOINTS = {
production: 'https://api.sberbank.ru',
sandbox: 'https://api.sberbank.ru/sandbox'
};
// Использование sandbox
const apiUrl = process.env.NODE_ENV === 'production'
? SBER_API_ENDPOINTS.production
: SBER_API_ENDPOINTS.sandbox;
```
**Тестовые данные:**
| Параметр | Тестовое значение |
|:---------|:------------------|
| Сумма для успешной оплаты | 100.00 ₽ |
| Сумма для отклонения | 500.00 ₽ |
| Тестовый телефон | +79991234567 |
#### Чек-лист тестирования
**Сценарии для проверки:**
- [ ] **Успешная оплата**
- Создание заказа
- Генерация QR-кода
- Имитация оплаты
- Получение callback
- Обновление статуса в InSales
- [ ] **Отмена оплаты**
- Создание заказа
- Истечение времени оплаты
- Получение статуса EXPIRED
- [ ] **Возврат средств**
- Успешная оплата заказа
- Изменение статуса заказа на "возврат"
- Инициация возврата в СБП
- Получение подтверждения возврата
- [ ] **Обработка ошибок**
- Недостаточно средств
- Технические ошибки API
- Таймауты запросов
- Некорректные данные
---
### Мониторинг и логирование
#### Система логирования
Структура логов
**Рекомендуемый формат логов:**
```javascript
const logger = require('winston');
// Конфигурация логгера
const sbpLogger = logger.createLogger({
format: logger.format.combine(
logger.format.timestamp(),
logger.format.json()
),
transports: [
new logger.transports.File({ filename: 'sbp-error.log', level: 'error' }),
new logger.transports.File({ filename: 'sbp-combined.log' })
]
});
// Пример логирования
sbpLogger.info('Создание заказа СБП', {
order_id: orderId,
amount: amount,
phone: phone,
timestamp: new Date().toISOString()
});
```
**Ключевые события для логирования:**
| Событие | Уровень | Данные |
|:--------|:--------|:-------|
| Создание заказа | INFO | order_id, amount, phone |
| Успешная оплата | INFO | order_id, sbp_order_id, amount |
| Ошибка API | ERROR | order_id, error_code, error_message |
| Возврат средств | WARNING | order_id, refund_amount, reason |
| Callback получен | INFO | order_id, status, timestamp |
#### Метрики для отслеживания
**Dashboard метрик:**
| Метрика | Описание | Целевое значение |
|:--------|:---------|:-----------------|
| Успешность платежей | % успешно оплаченных заказов | > 95% |
| Время создания заказа | Среднее время от запроса до QR | < 2 сек |
| Uptime webhook | Доступность callback endpoint | > 99.9% |
| Конверсия оплаты | % заказов, завершивших оплату | > 70% |
| Средняя сумма | Средний чек СБП-платежей | Мониторинг |
---
### Безопасность
#### Критические требования безопасности
> **Important:** Несоблюдение требований безопасности может привести к компрометации данных и финансовым потерям.
**Обязательные меры:**
1. **Хранение credentials:**
```javascript
// ❌ НЕ ДЕЛАЙТЕ ТАК
const CLIENT_ID = 'xxx-xxx-xxx';
// ✅ ПРАВИЛЬНО
const CLIENT_ID = process.env.SBER_CLIENT_ID;
```
2. **Валидация webhook:**
- Проверка подписи каждого запроса
- Проверка IP адреса отправителя
- Защита от replay-атак
3. **HTTPS обязателен:**
- Все эндпоинты только по HTTPS
- Валидный SSL-сертификат
- TLS 1.2 или выше
4. **Логирование без sensitive data:**
```javascript
// ❌ НЕ ЛОГИРУЙТЕ
logger.info('Token:', accessToken);
logger.info('Client Secret:', clientSecret);
// ✅ ПРАВИЛЬНО
logger.info('Token получен успешно');
logger.info('Аутентификация прошла');
```
5. **Rate limiting:**
```javascript
const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 минут
max: 100 // максимум 100 запросов
});
app.use('/api/sbp/', apiLimiter);
```
---
### Производительность и масштабирование
#### Оптимизация
Кэширование токенов
```javascript
const NodeCache = require('node-cache');
const tokenCache = new NodeCache({ stdTTL: 3000 }); // 50 минут
const getSberAccessToken = async () => {
// Проверка кэша
const cachedToken = tokenCache.get('sber_access_token');
if (cachedToken) {
return cachedToken;
}
// Получение нового токена
const token = await requestNewToken();
// Сохранение в кэш
tokenCache.set('sber_access_token', token);
return token;
};
```
Очередь обработки
**Использование Bull для асинхронной обработки:**
```javascript
const Queue = require('bull');
const paymentQueue = new Queue('sbp-payments');
// Добавление задачи в очередь
paymentQueue.add('create-payment', {
order_id: orderId,
amount: amount
});
// Обработчик задач
paymentQueue.process('create-payment', async (job) => {
const { order_id, amount } = job.data;
try {
const result = await createSberOrder({ order_id, amount });
return result;
} catch (error) {
// Автоматический retry при ошибке
throw error;
}
});
```
---
### Устранение типичных проблем
| Проблема | Причина | Решение |
|:---------|:--------|:--------|
| Ошибка 401 при запросах | Неверный токен или истек срок | Обновите токен, проверьте credentials |
| Callback не приходит | Неверный URL или недоступен | Проверьте доступность webhook URL по HTTPS |
| Платеж не проходит | Технические проблемы Сбербанка | Проверьте статус через API, свяжитесь с поддержкой |
| QR-код не генерируется | Ошибка в параметрах заказа | Проверьте формат данных, сумма в копейках |
| Возврат не работает | Превышен срок возврата | Возврат возможен в течение 90 дней |
| Дублирование платежей | Повторная отправка callback | Добавьте идемпотентность обработки |
---
### Чек-лист запуска в продакшен
**Административная часть:**
- [ ] Заключен договор со Сбербанком
- [ ] Заполнена анкета по продукту QR СБП
- [ ] Создана организация в личном кабинете разработчика
- [ ] Договор привязан к организации
- [ ] Получены и сохранены ClientId и ClientSecret
**Техническая часть:**
- [ ] Создано приложение в портале разработчика
- [ ] Настроены сертификаты
- [ ] Подписка на API "QR для Продавца" активирована
- [ ] Развернут внешний сервис обработки платежей
- [ ] Создан способ оплаты в InSales
- [ ] Созданы дополнительные поля для статуса СБП
- [ ] Настроен webhook для получения уведомлений от СБП
- [ ] Настроен webhook на изменение заказа в InSales
- [ ] Реализована логика возвратов и отмен
- [ ] Настроено логирование
- [ ] Проведено полное тестирование в sandbox
- [ ] Настроен мониторинг и алерты
- [ ] Созданы инструкции для поддержки
**Безопасность:**
- [ ] Все credentials в переменных окружения
- [ ] HTTPS настроен с валидным сертификатом
- [ ] Валидация подписей webhook
- [ ] Rate limiting настроен
- [ ] Логи не содержат sensitive data
---
### Документация для команды
#### Инструкция для операторов
Обработка заказов СБП
**Стандартный процесс:**
1. **Создание заказа:**
- Клиент выбирает способ оплаты "Оплата по QR СБП"
- Система автоматически создает заказ в СБП
- Клиент перенаправляется на страницу с QR-кодом
2. **Ожидание оплаты:**
- Статус заказа: "Ожидает оплаты"
- Поле "Статус СБП": IN_PROGRESS
- Клиент сканирует QR и оплачивает
3. **После оплаты:**
- Система автоматически получает уведомление
- Статус меняется на "Оплачен"
- Поле "Статус СБП": PAID
- Клиент получает подтверждение на email
**Действия при проблемах:**
| Ситуация | Действия оператора |
|:---------|:-------------------|
| Клиент не может оплатить | Проверить поле "Статус СБП", при необходимости создать новый QR |
| Оплата прошла, но статус не обновился | Вручную проверить через /api/sbp/status, обновить статус |
| Клиент просит возврат | Изменить статус заказа на "Возврат", система автоматически инициирует возврат |
| Технические проблемы | Связаться с технической поддержкой WS24.pro |
---
### Техническая поддержка
> **Important:** При возникновении технических сложностей обращайтесь к специалистам.
**Контакты для консультации:**
**Сбербанк:**
- Техподдержка API: api-support@sberbank.ru
- Телефон: 8 (800) 555-55-50
- [Портал разработчика](https://developer.sber.ru/)
**WS24.pro:**
- Специалисты по API интеграциям
- Полный цикл разработки и внедрения
- Техническая поддержка 24/7
- Обучение команды
**Полезные ресурсы:**
- [Документация API Сбербанк](https://api.developer.sber.ru/product/PlatiQR/doc)
- [Документация InSales API](https://www.insales.ru/collection/api)
- [Спецификация СБП](https://sbp.nspk.ru/)
---
> **Note:** Интеграция СБП — сложный технический процесс, требующий опыта работы с API и понимания платежных систем. Рекомендуется привлечь опытных разработчиков или обратиться к специалистам WS24.pro для профессиональной реализации. Правильно настроенная интеграция обеспечит бесперебойный прием платежей и высокую конверсию заказов.