# Form payment creation

Integration via the 1Payment payment form is the simplest way to start accepting payments through the **Faster Payments System (SBP)**. You do not need to generate QR codes or integrate with bank APIs yourself — 1Payment handles the technical side.

## How it works

The SBP payment flow consists of four steps:

1. **Initialization** — your server sends a request with order parameters to the 1Payment endpoint.
2. **Receiving the link** — the system returns a unique URL of the payment page.
3. **Payment** — you redirect the user to the received address; there they select a bank, open the mobile app, and confirm the payment.
4. **Notification (callback)** — after the transaction completes, we send a payment status notification to your `notify_url`.


## Technical details

|  |  |
|  --- | --- |
| **Endpoint** | `https://api.1payment.com/init_form` |
| **Methods** | `GET`, `POST` |
| **Response format** | JSON |
| **Payment type** | The request must include `payment_type=sbp` |


## Request parameters

### Required

These fields are required to create the payment form correctly.

| Parameter | Type | Description |
|  --- | --- | --- |
| `partner_id` | Integer | Your unique identifier in the 1Payment system. |
| `project_id` | Integer | Your project identifier. |
| `amount` | Number | Payment amount (for example, `100.00`). |
| `payment_type` | String | For SBP payments, always pass `sbp`. |
| `user_data` | String | Your internal order ID for payment matching. |
| `shop_url` | String | URL of the site where the purchase is made. |
| `sign` | String | Request signature (see the "Signature" section). |


### Optional

Configure form behavior and pass customer data.

| Parameter | Type | Description |
|  --- | --- | --- |
| `description` | String | Purchase description shown to the customer on the payment form. |
| `success_url` | String | URL to redirect the customer after successful payment. |
| `failure_url` | String | URL to redirect the customer on error. |
| `user_id` | String | Internal payer ID in your system. |
| `lang` | String | Form language (for example, `ru`, `en`). |


## Signature generation (`sign`)

Signature: MD5, lowercase (hex). General rules — [API request format](/en/pages/init-request#request-signature-sign).

**Formula:**


```text
MD5(init_form + <параметры_без_sign_в_алфавитном_порядке_через_&> + <API_KEY>)
```

**Example string before hashing:**


```text
init_formamount=100.00&partner_id=123&payment_type=sbp&project_id=456&shop_url=myshop.ru&user_data=order_777secret_key
```

### Signature verification in the documentation

## Request examples

Node.js

```javascript
const crypto = require('crypto');
const axios = require('axios');

async function createSbpForm(apiKey, params) {
  // 1. Сортируем параметры по алфавиту
  const sortedKeys = Object.keys(params).sort();
  const queryString = sortedKeys.map((key) => `${key}=${params[key]}`).join('&');

  // 2. Генерируем подпись с префиксом init_form
  const baseString = `init_form${queryString}${apiKey}`;
  params.sign = crypto.createHash('md5').update(baseString).digest('hex');

  // 3. Отправляем POST-запрос
  try {
    const response = await axios.post('https://api.1payment.com/init_form', params);
    return response.data; // в ответе поле url — ссылка на форму
  } catch (error) {
    console.error('Ошибка:', error.message);
  }
}

// Пример данных запроса
const mockApiKey = process.env.ONEPAYMENT_API_KEY;
const mockData = {
  partner_id: 123,
  project_id: 456,
  amount: '100.00',
  payment_type: 'sbp',
  user_data: 'order_777',
  shop_url: 'myshop.ru',
};

createSbpForm(mockApiKey, mockData).then(console.log);
```

Python

```python
import hashlib
import os
import requests

def create_sbp_form(api_key: str, params: dict) -> dict:
    # 1. Сортировка параметров по алфавиту
    sorted_keys = sorted(params.keys())
    query_string = "&".join(f"{k}={params[k]}" for k in sorted_keys)

    # 2. Формирование подписи (префикс init_form)
    base_string = f"init_form{query_string}{api_key}"
    params["sign"] = hashlib.md5(base_string.encode("utf-8")).hexdigest()

    # 3. Запрос к API
    response = requests.post("https://api.1payment.com/init_form", data=params)
    response.raise_for_status()
    return response.json()  # в ответе поле url — ссылка на форму

# Пример данных запроса
api_key = os.environ["ONEPAYMENT_API_KEY"]
data = {
    "partner_id": 123,
    "project_id": 456,
    "amount": "100.00",
    "payment_type": "sbp",
    "user_data": "order_777",
    "shop_url": "myshop.ru",
}

print(create_sbp_form(api_key, data))
```

PHP

```php
<?php

function createSbpForm(string $apiKey, array $params): string
{
    // 1. Сортировка параметров по алфавиту
    ksort($params, SORT_LOCALE_STRING);
    $tail = '';
    foreach ($params as $k => $v) {
        if ($k === 'sign') {
            continue;
        }
        $tail .= "{$k}={$v}&";
    }
    $tail = substr($tail, 0, -1);

    // 2. Формирование подписи (префикс init_form)
    $params['sign'] = md5('init_form' . $tail . $apiKey);

    // 3. Запрос к API
    $ch = curl_init('https://api.1payment.com/init_form');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);

    return $response; // JSON с полем url
}

// Пример данных запроса (обязательные поля)
$apiKey = getenv('ONEPAYMENT_API_KEY');
$data = [
    'partner_id' => 123,
    'project_id' => 456,
    'amount' => '100.00',
    'payment_type' => 'sbp',
    'user_data' => 'order_777',
    'shop_url' => 'myshop.ru',
];

echo createSbpForm($apiKey, $data);
```

cURL

```bash
# 1–2. Подпись: md5("init_form" + параметры_по_алфавиту_через_& + API_KEY)
# Пример строки: init_formamount=100.00&partner_id=123&payment_type=sbp&project_id=456&shop_url=myshop.ru&user_data=order_777{API_KEY}

# 3. GET-запрос (можно также POST с теми же полями)
curl -sS "https://api.1payment.com/init_form?partner_id=123&project_id=456&amount=100.00&payment_type=sbp&user_data=order_777&shop_url=myshop.ru&sign=PASTE_MD5_HEX"
```

## API response

Successful response (`200`):


```json
{
  "url": "https://merchant.1payment.com/xZ5g7F"
}
```

The `url` field is the payment page address to redirect the payer to.

Request error (`400`):


```json
{
  "error_code": 2
}
```

## Status notifications (callbacks)

After the transaction status changes, our server sends a **POST** request in JSON format to your `notify_url`.

| Parameter | Type | Req. | Description |
|  --- | --- | --- | --- |
| `payment_type` | String | Yes | Payment type (`sbp`). |
| `order_id` | String | Yes | Payment ID in the 1Payment system. |
| `project_id` | Integer | Yes | Your project ID. |
| `status` | Integer | Yes | Status: `2` (pending), `3` (success), `4` (failure). |
| `status_description` | String | Yes | `PENDING`, `SUCCESS`, or `FAILURE`. |
| `init_time` | String | Yes | Payment creation time. |
| `status_time` | String | Yes | Time the final status was received. |
| `merchant_price` | Number | Yes | Payment amount. |
| `init_price` | Number | Yes | Payment amount at initiation. |
| `user_price` | Number | Yes | Final amount charged to the payer. |
| `currency` | String | Yes | Payment currency (ISO 4217). |
| `user_data` | String | Yes | Transaction ID passed at creation. |
| `account` | String | Yes | SBP account details (value `sbp`). |
| `sign` | String | Yes | Callback signature. |
| `test` | Integer | No | `1` for test payments. |
| `status_code` | String | Yes | Always sent. Default `0` on success — ignore it. Handle only on decline (`status` = `4`); see [Decline error codes](/en/pages/decline-error-codes). |
| `payer_name` | String | No | Payer name. |
| `ip` | String | No | Payer IP address. |
| `ip_country` | String | No | Country of the payer IP address. |
| `trx_id` | String | No | Transaction ID in the payment system. |
| `rrn` | String | No | Operation RRN (Retrieval Reference Number). |
| `bank_nspk_id` | String | No | Payer bank ID in NSPK. |
| `bank_name` | String | No | Payer bank name. |


**Important:** your server must return **HTTP 200 OK**. Otherwise the system retries the callback **once per minute for 10 minutes**.

**Callback signature verification:** MD5 of all parameters in alphabetical order joined by `&` + `API_KEY` (**without** the `init_form` prefix). See [API request format](/en/pages/init-request#callbacks-notifications).

## Related sections

- [Payment status](/en/pages/sbp/status)
- [Payment refunds](/en/pages/sbp/refund)
- [Host-to-host payment creation (GATE)](/en/pages/sbp/host2host)
- [Transaction statuses](/en/pages/transaction-statuses)
- [Error codes (API)](/en/pages/error-codes-api)
- [Decline error codes](/en/pages/decline-error-codes)