# Создание платежа (форма оплаты)

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

<mark style="color:blue;">`GET`</mark> `https://unitpay.ru/pay/PUBLIC-KEY?sum&account&desc&signature`

Для инициализации платежа посредством единой формы оплаты вам достаточно направить пользователя по специальному URL и передать ряд обязательных для оплаты параметров.

#### Основные параметры:

<table><thead><tr><th width="169.66668701171875">name</th><th width="129.8887939453125">type</th><th>description</th></tr></thead><tbody><tr><td>sum</td><td>number</td><td><p>Сумма платежа. По умолчанию в рублях*. </p><p></p><p>*- см. дополнительный параметр currency.</p></td></tr><tr><td>account</td><td>string</td><td>Идентификатор абонента в вашей системе (например email или номер заказа).</td></tr><tr><td>desc</td><td>string</td><td>Описание заказа. Используется только для информирования при совершении платежа.</td></tr><tr><td>signature</td><td>string</td><td>Цифровая подпись запроса. Она защищает вас от злоумышленников - подмены описания или стоимости заказа, размещения ссылки на оплату на ресурсах мошенников. <br>Образуется как <code>sha256(account + "{up}" + currency + "{up}" + desc + "{up}" + sum + "{up}" + secretKey)</code> ,<br>где sha256 - метод хеширования;  <br>"{up}" - разделитель параметров в хеш-функции;  <br>secretKey - секретный ключ проекта (доступен в настройках проекта);  <br><br><strong>Важно</strong>. Если вы не передаете currency на форму оплаты, то этот параметр не должен участвовать в формировании подписи.</td></tr></tbody></table>

Значение PUBLIC KEY и SECRET KEY проекта можно найти на странице **Настройки** проекта

<figure><img src="/files/Aih86AXgsDAOloUJrS2P" alt=""><figcaption></figcaption></figure>

**Дополнительные параметры:**

<table><thead><tr><th width="169">name</th><th width="143.4444580078125">type</th><th>description</th></tr></thead><tbody><tr><td>currency</td><td>string</td><td>Валюта заказа по стандарту ISO 4217 (EUR, USD, RUB, UAH, BYN и тд. <a href="https://help.unitpay.money/book-of-reference/currency-codes">Полный список валют</a>). <br><br>Если платежная система не поддерживает требуемую валюту, то сумма будет сконвертирована в валюту системы оплаты.</td></tr><tr><td>cashItems</td><td>string</td><td>Передача данных по онлайн кассе. Используется, если вы выбиваете чеки на выполненные услуги. <a href="/pages/-MBD4MOkSgZaYFD6SuGB">Подробнее</a>.</td></tr><tr><td>locale</td><td>string</td><td><p>Принудительное указание языка платежной формы, допустимые значения: ru, en. </p><p>По умолчанию язык формы определяется исходя из страны, к которой относится IP адрес пользователя.</p></td></tr><tr><td>backUrl</td><td>string</td><td>платежной формы без совершения покупки, по умолчанию используется адрес проекта. В адресе обязательно должен использоваться домен проекта. <br><br>Примеры:<br><code>https://redirect.&#x3C;домен проекта>/?someParams</code> <code>https://&#x3C;домен проекта>/redirect/</code></td></tr><tr><td>resultUrl</td><td>string</td><td><p>Полный URL адрес перехода пользователя после оплаты (например, <a href="http://unitpay.ru/">http://вашсайт.ru</a>), принудительно отправляет плательщика по этому адресу после оплаты.</p><p></p><p><strong>Важно:</strong> домен не должен отличаться от домена проекта. Если параметр не задан, то будет использован адрес страницы чека платежа.</p></td></tr><tr><td>subscription</td><td>string</td><td>Используйте данный флаг, если требуется создать подписку по карте плательщика. Идентификатор подписки (subscriptionId) будет передан в методе PAY на ваш обработчик платежа. <br>Использование подписок возможно только после согласования со службой безопасности.</td></tr></tbody></table>

**Пример формирования цифровой подписи:**

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

```php
function getFormSignature($account, $desc, $sum, $secretKey, $currency = null) {
    $parts = [$account];
    if ($currency !== null && $currency !== '') $parts[] = $currency;
    $parts[] = $desc;
    $parts[] = $sum;
    $parts[] = $secretKey;
    return hash('sha256', implode('{up}', $parts));
}

$sig = getFormSignature('customer@gmail.com', 'TEST_DESCRIPTION', '150', 'YOUR_SECRET', 'RUB');

```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require "digest"

def form_signature(account:, desc:, sum:, secret_key:, currency: nil)
  parts = [account]
  parts << currency unless currency.nil? || currency.empty?
  parts += [desc, sum, secret_key]
  Digest::SHA256.hexdigest(parts.join("{up}"))
end

# Пример
sig = form_signature(account: "customer@gmail.com", desc: "TEST_DESCRIPTION", sum: "150", secret_key: "YOUR_SECRET", currency: "RUB")

```

{% endtab %}

{% tab title="Python" %}

```python
import hashlib

def get_form_signature(account, desc, sum_, secret_key, currency=None):
    parts = [str(account)]
    if currency is not None and str(currency) != "":
        parts.append(str(currency))
    parts += [str(desc), str(sum_), str(secret_key)]
    return hashlib.sha256("{up}".join(parts).encode("utf-8")).hexdigest()

# Пример
sig = get_form_signature("customer@gmail.com", "TEST_DESCRIPTION", "150", "YOUR_SECRET", "RUB")

```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const crypto = require("crypto");

function getFormSignature({ account, desc, sum, secretKey, currency }) {
  const parts = [String(account)];
  if (currency != null && String(currency) !== "") parts.push(String(currency));
  parts.push(String(desc), String(sum), String(secretKey));
  return crypto.createHash("sha256").update(parts.join("{up}")).digest("hex");
}

// Пример
const sig = getFormSignature({
  account: "customer@gmail.com",
  desc: "TEST_DESCRIPTION",
  sum: "150",
  secretKey: "YOUR_SECRET",
  currency: "RUB",
});

```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"strings"
)

func GetFormSignature(account, desc, sum, secretKey string, currency *string) string {
	parts := []string{account}
	if currency != nil && *currency != "" {
		parts = append(parts, *currency)
	}
	parts = append(parts, desc, sum, secretKey)
	payload := strings.Join(parts, "{up}")
	sumBytes := sha256.Sum256([]byte(payload))
	return hex.EncodeToString(sumBytes[:])
}

func main() {
	cur := "RUB"
	sig := GetFormSignature("customer@gmail.com", "TEST_DESCRIPTION", "150", "YOUR_SECRET", &cur)
	fmt.Println(sig)
}

```

{% endtab %}

{% tab title=".NET" %}

```csharp
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

static class UnitpaySign
{
    public static string GetFormSignature(string account, string desc, string sum, string secretKey, string currency = null)
    {
        var parts = new List<string> { account };
        if (!string.IsNullOrEmpty(currency)) parts.Add(currency);
        parts.Add(desc);
        parts.Add(sum);
        parts.Add(secretKey);

        var payload = string.Join("{up}", parts);
        using var sha = SHA256.Create();
        var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(payload));
        return Convert.ToHexString(bytes).ToLowerInvariant();
    }
}

class Program
{
    static void Main()
    {
        var sig = UnitpaySign.GetFormSignature("customer@gmail.com", "TEST_DESCRIPTION", "150", "YOUR_SECRET", "RUB");
        Console.WriteLine(sig);
    }
}
C#
```

{% endtab %}

{% tab title="Java" %}

```java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;

public class UnitpaySignature {
    public static String getFormSignature(String account, String desc, String sum, String secretKey, String currency) {
        List<String> parts = new ArrayList<>();
        parts.add(account);
        if (currency != null && !currency.isEmpty()) parts.add(currency);
        parts.add(desc);
        parts.add(sum);
        parts.add(secretKey);

        String payload = String.join("{up}", parts);
        return sha256Hex(payload);
    }

    private static String sha256Hex(String data) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(data.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder(hash.length * 2);
            for (byte b : hash) sb.append(String.format("%02x", b));
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // Пример
    public static void main(String[] args) {
        String sig = getFormSignature("customer@gmail.com", "TEST_DESCRIPTION", "150", "YOUR_SECRET", "RUB");
        System.out.println(sig);
    }
}

```

{% endtab %}
{% endtabs %}

**Пример кода для формирования ссылки на оплату:**&#x20;

```php
<?php

$params = [
    'account' => 'test_unitpay',
    'currency' => 'RUB',
    'desc' => 'test_unitpay',
    'sum' => '100',
] ;

$billingCode = 'card';
$projectPublicId = '123456-1bfac';

$secretKey = 'secretKey';
$signatureParams = ['desc' => $params['desc'], 'sum' => $params['sum'], 'account' => $params['account'], 'currency' => $params['currency']];
ksort($signatureParams);
$signatureParams[] = $secretKey;
$signature =  hash('sha256', implode('{up}', $signatureParams));
$baseUrl = 'https://unitpay.ru';

$params['signature'] = $signature;
$uri = http_build_query($params);

echo $baseUrl.'/pay/'.$projectPublicId.'/'.$billingCode.'?'.$uri.PHP_EOL;
```

**Пример правильно сформированной ссылки на оплату**:&#x20;

```http
https://unitpay.ru/pay/123456-1bfac/card?account=test_unitpay&currency=RUB&desc=test_unitpay&sum=10&signature=0d3904fc3f46aaf6d153621541a54f85e921d491d43cc36728d21bed47457790
```

#### Метод оплаты по умолчанию

Вы можете определить платежный метод, который будет использоваться по умолчанию для пользователя. Для этого в конец URL вашей платежной формы добавьте параметр billingCode, соответствующий буквенному [коду платежной системы](https://help.unitpay.money/book-of-reference/payment-system-codes).

#### Возврат на сайт магазина

После инициализации оплаты пользователь переходит на страницу чека, где отслеживается статус платежа. При получении успешного либо ошибочного статуса пользователь переходит на сайт партнера по кнопке "В магазин" (поля Fail URL/Success URL в настройках личного кабинета) с GET параметрами:

<table data-header-hidden><thead><tr><th width="160.44447835286456">name</th><th width="174.111083984375">type</th><th>description</th></tr></thead><tbody><tr><td>account</td><td>текст</td><td>Идентификатор плательщика в системе партнера (например, логин или email)</td></tr><tr><td>paymentId</td><td>число</td><td>Номер платежа в системе UnitPay</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.unitpay.ru/payments/create-payment-easy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
