> For the complete documentation index, see [llms.txt](https://docs.mmoweb.biz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mmoweb.biz/rest-api/master-akkaunt/platezhi/zavershenie-platezhnogo-ordera.md).

# Завершение платежного ордера

### Описание

Endpoint используется для финализации платежного ордера и обработки платежа.&#x20;

При успешном завершении:

* Статус ордера изменяется на **завершённый**
* Баланс пользователя пополняется согласно сумме платежа
* Операция логируется в систему

Вы можете использовать данный endpoint для обработки вебхуков и колбеков от платежных шлюзов.

***

### Endpoint

```
POST https://api.mmoweb.biz/v2/payment/order/complete
```

**Content-Type:** `application/json`

***

### Параметры

Все параметры передаются в JSON теле запроса.

| Параметр         | Тип    | Обязателен | Формат                    | Описание                                                                 |
| ---------------- | ------ | ---------- | ------------------------- | ------------------------------------------------------------------------ |
| `payment_system` | string | Да         | `cstm:[a-z]{4,20}`        | Идентификатор платежной системы (например: `cstm:yandex`, `cstm:paypal`) |
| `order_id`       | string | Да         | `Order:[A-Za-z0-9]{8,11}` | Уникальный идентификатор ордера, выданный при создании                   |
| `payment_id`     | string | Нет        | Строчное значение         | ID платежа в платежной системе (используется для отслеживания)           |

> **Форматы параметров:**
>
> * `payment_system`: начинается с `cstm:`, за которым следуют 4-20 строчных букв (пример: `cstm:stripe`, `cstm:cryptobox`)
> * `order_id`: начинается с `Order:`, за которым следуют 8-11 буквенно-цифровых символов (пример: `Order:abc12345`)

***

### Примеры

#### Базовое завершение платежа

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

```bash
curl -X POST "https://api.mmoweb.biz/v2/payment/order/complete" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_system": "cstm:yandex",
    "order_id": "Order:abc12345",
    "payment_id": "yandex_payment_123456"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const payload = {
  payment_system: 'cstm:yandex',
  order_id: 'Order:abc12345',
  payment_id: 'yandex_payment_123456'
};

fetch('https://api.mmoweb.biz/v2/payment/order/complete', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/payment/order/complete';

$payload = [
  'payment_system' => 'cstm:yandex',
  'order_id' => 'Order:abc12345',
  'payment_id' => 'yandex_payment_123456'
];

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($payload),
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

#### Завершение платежа без payment\_id

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

```bash
curl -X POST "https://api.mmoweb.biz/v2/payment/order/complete" \
  -H "Authorization: Bearer APPLICATION_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_system": "cstm:paypal",
    "order_id": "Order:xyz98765"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const token = 'APPLICATION_TOKEN_HERE';

const payload = {
  payment_system: 'cstm:paypal',
  order_id: 'Order:xyz98765'
};

fetch('https://api.mmoweb.biz/v2/payment/order/complete', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$token = 'APPLICATION_TOKEN_HERE';
$url = 'https://api.mmoweb.biz/v2/payment/order/complete';

$payload = [
  'payment_system' => 'cstm:paypal',
  'order_id' => 'Order:xyz98765'
];

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => json_encode($payload),
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json'
  ]
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);

echo "HTTP Status: " . $httpCode . "\n";
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>
```

{% endtab %}
{% endtabs %}

***

### Ответы

#### Успешное завершение (200 OK)

```json
{
  "success": true,
  "code": "PAYMENT_PROCESSED",
  "message": "Payment processed successfully",
  "order": {
    "id": 12345,
    "mid": 789,
    "sid": 2,
    "pid": 1,
    "team": 1,
    "order_id": "Order:abc12345",
    "payment_system": "cstm:yandex",
    "amount": "500.00",
    "currency": "RUB",
    "status": 1,
    "date_create": "2026-08-05 10:30:00",
    "date_complete": "2026-08-05 10:32:15",
    "payment_id": "yandex_payment_123456",
    "custom_data": null
  }
}
```

#### Ошибка валидации параметров (400 Bad Request)

```json
{
  "success": false,
  "code": "VALIDATION_ERROR",
  "message": {
    "payment_system": "payment_system field must match the regex pattern cstm:[a-z]{4,20}",
    "order_id": "order_id field must match the regex pattern Order:[A-Za-z0-9]{8,11}"
  }
}
```

#### Ордер не найден (404 Not Found)

```json
{
  "success": false,
  "code": "ORDER_NOT_FOUND",
  "message": "Order not found"
}
```

> **Когда встречается:** ордер не существует, не принадлежит текущему проекту/команде или платежная система не совпадает

#### Ордер уже завершен (409 Conflict)

```json
{
  "success": false,
  "code": "ORDER_ALREADY_COMPLETED",
  "message": "Order has already been completed"
}
```

#### Ошибка обновления статуса (500 Internal Server Error)

```json
{
  "success": false,
  "code": "ORDER_UPDATE_FAILED",
  "message": "Failed to update order status"
}
```

#### Ошибка при обработке платежа (зависит от конкретной ошибки)

```json
{
  "success": false,
  "code": "PAYMENT_PROCESSING_ERROR",
  "message": "An error occurred while processing the payment"
}
```

***

### Коды ошибок

| Код                        | HTTP Status | Описание                                                                       | Что делать                                                                        |
| -------------------------- | ----------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`         | 400         | Один или несколько параметров не соответствуют формату                         | Проверьте формат `payment_system` и `order_id` согласно спецификации              |
| `ORDER_NOT_FOUND`          | 404         | Ордер не существует, не принадлежит проекту или платежная система не совпадает | Убедитесь что используете правильный `order_id` и `payment_system`                |
| `ORDER_ALREADY_COMPLETED`  | 409         | Этот ордер уже был завершен                                                    | Дублированная обработка вебхука; это нормально — повторно завершение не требуется |
| `ORDER_UPDATE_FAILED`      | 500         | Ошибка при обновлении статуса в БД                                             | Повторите попытку позже; если ошибка повторяется, свяжитесь с поддержкой          |
| `PAYMENT_PROCESSING_ERROR` | Переменный  | Ошибка при обработке платежа в системе                                         | Проверьте логи; платеж может быть обработан, но сообщение не отправлено           |

***

### Поток обработки платежа

1. **Получение вебхука** — платежная система отправляет колбек на ваш сервер
2. **Вызов API** — ваш сервер вызывает этот endpoint с данными платежа
3. **Валидация** — проверяется формат параметров и существование ордера
4. **Обновление статуса** — статус ордера изменяется на завершённый
5. **Обработка платежа** — платеж обрабатывается (зачисление на баланс и т.д.)
6. **Логирование** — операция записывается в логи для аудита
7. **Ответ** — возвращается результат обработки

***

### Важные особенности

#### Идемпотентность

Если ордер уже завершен, endpoint вернет ошибку `ORDER_ALREADY_COMPLETED` (409). **Это нормальное поведение** и означает, что платеж уже был обработан. Не пересылайте запрос повторно.

#### Совпадение платежной системы

Параметр `payment_system` в запросе **должен совпадать** с платежной системой, которая была указана при создании ордера. Если системы не совпадают, ордер не будет найден.

#### Payment ID (опционально)

Параметр `payment_id` не обязателен, но рекомендуется передавать ID платежа из платежной системы для отслеживания и согласования.

#### Время обработки

После завершения ордера баланс пользователя пополняется немедленно. Убедитесь, что платеж действительно прошел в платежной системе перед вызовом этого endpoint'а.

***

### Рекомендации

**Безопасность:**&#x20;

* Проверяйте подпись вебхука от платежной системы перед вызовом API
* Убедитесь что `payment_system` соответствует вашей конфигурации
* Используйте HTTPS для всех запросов

**Надёжность:**

* Реализуйте retry logic с экспоненциальной задержкой при ошибках 5xx
* Сохраняйте полные логи всех вебхуков для отладки
* Обрабатывайте ответ `ORDER_ALREADY_COMPLETED` как успех (платеж уже обработан)

**Интеграция:**

* Тестируйте с тестовыми платежами перед запуском в production
* Проверяйте что все параметры имеют правильный формат
* Убедитесь что токен приложения имеет необходимые разрешения
