> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meridian.vip/llms.txt
> Use this file to discover all available pages before exploring further.

# Трансграничные платежи — Redirect

## Обзор

Redirect-интеграция позволяет перенаправить клиента на hosted-страницу оплаты Meridian. Клиент увидит реквизиты, таймер обратного отсчёта и кнопку для открытия банковского приложения (deeplink). После завершения платежа клиент автоматически перенаправляется обратно на ваш сайт.

<Info>
  **Поддерживаемые банки**: Сбербанк, ВТБ, Т-Банк, Газпромбанк, Солидарность
</Info>

### Поддержка deeplink (открытие банковского приложения)

| Код | Банк         | Deeplink |
| --- | ------------ | -------- |
| `1` | ВТБ          | ✅        |
| `2` | Сбербанк     | ✅        |
| `3` | Газпромбанк  | ❌        |
| `4` | Т-Банк       | ✅        |
| `5` | Солидарность | ❌        |

***

## Создание платежа

```
POST https://api.meridian.vip/api/v1/transgran/redirect-payments
```

### Обязательные параметры

| Параметр            | Тип      | Описание                                                               |
| ------------------- | -------- | ---------------------------------------------------------------------- |
| `amount`            | `number` | Сумма платежа в рублях (не в копейках). Пример: `1000` = 1000 RUB      |
| `currency`          | `string` | Код валюты. Только `"RUB"`                                             |
| `bank`              | `number` | Предпочтительный банк клиента. См. [Коды банков](#коды-банков)         |
| `internalId`        | `string` | Уникальный идентификатор заказа в вашей системе (ключ идемпотентности) |
| `customerEmail`     | `string` | Email клиента                                                          |
| `notificationUrl`   | `string` | URL для webhook-уведомлений                                            |
| `notificationToken` | `string` | Секретный токен для подписи webhook-уведомлений                        |
| `successUrl`        | `string` | URL для перенаправления при успешной оплате                            |
| `cancelUrl`         | `string` | URL для перенаправления при отмене                                     |
| `errorUrl`          | `string` | URL для перенаправления при ошибке/истечении                           |

***

## Пример запроса

<CodeGroup>
  ```javascript Node.js theme={null}
  const crypto = require('crypto');

  function calculateSignature(method, url, body, secret) {
    const stringToSign = method + url + (body || '');
    const hmac = crypto.createHmac('sha256', secret);
    hmac.update(stringToSign);
    return hmac.digest('base64');
  }

  const method = 'POST';
  const url = 'https://api.meridian.vip/api/v1/transgran/redirect-payments';
  const body = JSON.stringify({
    amount: 1000,
    currency: 'RUB',
    bank: 2, // Sberbank
    internalId: 'order-12345',
    customerEmail: 'customer@example.com',
    notificationUrl: 'https://your-site.com/webhooks/transgran',
    notificationToken: 'your-webhook-secret-token',
    successUrl: 'https://your-site.com/payment/success',
    cancelUrl: 'https://your-site.com/payment/cancel',
    errorUrl: 'https://your-site.com/payment/error'
  });

  const apiKey = 'meridian_abc123...:meridian_xyz789...';
  const [keyId, secret] = apiKey.split(':');
  const signature = calculateSignature(method, url, body, secret);

  const response = await fetch(url, {
    method,
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': apiKey,
      'X-Signature': signature
    },
    body
  });

  const result = await response.json();

  // Перенаправьте клиента на страницу оплаты
  console.log('Redirect URL:', result.paymentUrl);
  // → "https://luma-gate.com/pay/aB3xK9mN..."
  ```

  ```python Python theme={null}
  import hmac
  import hashlib
  import base64
  import requests
  import json

  def calculate_signature(method, url, body, secret):
      string_to_sign = method + url + (body or '')
      signature = hmac.new(
          secret.encode('utf-8'),
          string_to_sign.encode('utf-8'),
          hashlib.sha256
      ).digest()
      return base64.b64encode(signature).decode('utf-8')

  method = 'POST'
  url = 'https://api.meridian.vip/api/v1/transgran/redirect-payments'
  body = json.dumps({
      'amount': 1000,
      'currency': 'RUB',
      'bank': 2,  # Sberbank
      'internalId': 'order-12345',
      'customerEmail': 'customer@example.com',
      'notificationUrl': 'https://your-site.com/webhooks/transgran',
      'notificationToken': 'your-webhook-secret-token',
      'successUrl': 'https://your-site.com/payment/success',
      'cancelUrl': 'https://your-site.com/payment/cancel',
      'errorUrl': 'https://your-site.com/payment/error'
  })

  api_key = 'meridian_abc123...:meridian_xyz789...'
  key_id, secret = api_key.split(':')
  signature = calculate_signature(method, url, body, secret)

  response = requests.post(
      url,
      headers={
          'Content-Type': 'application/json',
          'X-API-Key': api_key,
          'X-Signature': signature
      },
      data=body
  )

  result = response.json()

  # Перенаправьте клиента на страницу оплаты
  print('Redirect URL:', result['paymentUrl'])
  # → "https://luma-gate.com/pay/aB3xK9mN..."
  ```

  ```php PHP theme={null}
  <?php

  function calculateSignature($method, $url, $body, $secret) {
      $stringToSign = $method . $url . ($body ?? '');
      $signature = hash_hmac('sha256', $stringToSign, $secret, true);
      return base64_encode($signature);
  }

  $method = 'POST';
  $url = 'https://api.meridian.vip/api/v1/transgran/redirect-payments';
  $body = json_encode([
      'amount' => 1000,
      'currency' => 'RUB',
      'bank' => 2, // Sberbank
      'internalId' => 'order-12345',
      'customerEmail' => 'customer@example.com',
      'notificationUrl' => 'https://your-site.com/webhooks/transgran',
      'notificationToken' => 'your-webhook-secret-token',
      'successUrl' => 'https://your-site.com/payment/success',
      'cancelUrl' => 'https://your-site.com/payment/cancel',
      'errorUrl' => 'https://your-site.com/payment/error'
  ]);

  $apiKey = 'meridian_abc123...:meridian_xyz789...';
  list($keyId, $secret) = explode(':', $apiKey);
  $signature = calculateSignature($method, $url, $body, $secret);

  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Content-Type: application/json',
      'X-API-Key: ' . $apiKey,
      'X-Signature: ' . $signature
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  curl_close($ch);

  $result = json_decode($response, true);

  // Перенаправьте клиента на страницу оплаты
  echo 'Redirect URL: ' . $result['paymentUrl'];
  // → "https://luma-gate.com/pay/aB3xK9mN..."
  ?>
  ```
</CodeGroup>

***

## Пример ответа (успех)

**HTTP Status: 201 Created**

```json theme={null}
{
  "id": "cm3k8x7y80001z8j4k5m6n7o8",
  "status": "new",
  "bankName": "sberbank",
  "amount": "1000",
  "currency": "RUB",
  "expireAt": "2025-11-03T15:10:00.000Z",
  "dealRequisites": "{\"bankName\":\"garant_bank\",\"cardNumber\":\"**** 1234\",\"fullName\":\"Ivan Ivanov\"}",
  "dealRate": "95.50",
  "createdAt": "2025-11-03T15:00:00.000Z",
  "updatedAt": "2025-11-03T15:00:00.000Z",
  "internalId": "order-12345",
  "merchantName": "MerchantName",
  "clientEmail": "customer@example.com",
  "paymentUrl": "https://luma-gate.com/pay/aB3xK9mNpQ7rS2tU4vW6xY8z"
}
```

<Warning>
  **Важно**: Поле `paymentUrl` — это ссылка для перенаправления клиента. Токен в URL является единственным способом авторизации на странице оплаты. Не передавайте его третьим лицам.
</Warning>

***

## Поля ответа

| Поле             | Тип      | Описание                                                                                       |
| ---------------- | -------- | ---------------------------------------------------------------------------------------------- |
| `id`             | `string` | Уникальный идентификатор платежа в системе Meridian                                            |
| `status`         | `string` | Статус: `new`, `processing`, `paid`, `expired`, `failed`                                       |
| `bankName`       | `string` | Запрошенный банк из параметра `bank`. **Не является банком назначения** — см. `dealRequisites` |
| `amount`         | `string` | Сумма платежа                                                                                  |
| `currency`       | `string` | Валюта (`RUB`)                                                                                 |
| `expireAt`       | `string` | Время истечения платежа. ISO 8601                                                              |
| `dealRequisites` | `string` | JSON-строка с реквизитами. См. [Структура dealRequisites](#структура-dealrequisites)           |
| `dealRate`       | `string` | Курс сделки                                                                                    |
| `createdAt`      | `string` | Время создания платежа. ISO 8601                                                               |
| `updatedAt`      | `string` | Время последнего обновления. ISO 8601                                                          |
| `internalId`     | `string` | Ваш идентификатор заказа                                                                       |
| `merchantName`   | `string` | Название мерчанта                                                                              |
| `clientEmail`    | `string` | Email клиента                                                                                  |
| `paymentUrl`     | `string` | **URL для перенаправления клиента** на hosted-страницу оплаты                                  |

***

<a id="структура-dealrequisites" />

## Структура dealRequisites

Поле `dealRequisites` содержит JSON-строку с реквизитами, куда клиент должен отправить платёж.

<Warning>
  **Важно**: Поле `bankName` в ответе — это запрошенный банк. Фактический банк назначения находится в `dealRequisites.bankName`.
</Warning>

| Поле          | Тип      | Описание        |
| ------------- | -------- | --------------- |
| `bankName`    | `string` | Банк назначения |
| `cardNumber`  | `string` | Номер карты     |
| `fullName`    | `string` | ФИО получателя  |
| `phoneNumber` | `string` | Номер телефона  |

***

## Проверка статуса

```
GET https://api.meridian.vip/api/v1/transgran/payments/:id
```

Используется тот же endpoint, что и для [H2H интеграции](/docs/transgran#проверка-статуса).

### Пример запроса

```javascript theme={null}
const method = 'GET';
const paymentId = 'cm3k8x7y80001z8j4k5m6n7o8';
const url = `https://api.meridian.vip/api/v1/transgran/payments/${paymentId}`;

const signature = calculateSignature(method, url, '', secret);

const response = await fetch(url, {
  method,
  headers: {
    'X-API-Key': apiKey,
    'X-Signature': signature
  }
});

const payment = await response.json();
console.log('Status:', payment.status);
```

***

## Webhook-уведомления

Webhook-уведомления работают идентично [H2H интеграции](/docs/transgran#webhook-уведомления). При изменении статуса платежа система отправляет POST-запрос на указанный `notificationUrl`.

### Формат и верификация

См. полную документацию в разделе [Трансграничные платежи — Webhook](/docs/transgran#webhook-уведомления).

***

## Создание апелляции

Если клиент оплатил, но статус не изменился, создайте апелляцию. Процесс идентичен [H2H интеграции](/docs/transgran#создание-апелляции).

```
POST https://api.meridian.vip/api/v1/transgran/payments/:id/disputes
```

***
