# Payment Handler

A payment handler is the URL of your server where Unitpay sends server-side GET requests regarding the payment process. These requests allow you to:

* Verify an order before payment.
* Confirm that an order exists and can be paid for.
* Automatically issue products, provide services, or credit balances after successful payment completion.
* Receive notifications about payment errors.

{% hint style="info" %}
Important: if the handler URL is not specified, callback requests are not sent, and the payment is considered successful automatically.
{% endhint %}

<figure><img src="https://244174165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M9Y_k8Gr-WxeECFRelw-887967055%2Fuploads%2Fn48eVfdHoXdLk2PDPT4E%2Fimage.png?alt=media&#x26;token=cac54691-7c7f-44dc-a38a-26b73b9a2917" alt=""><figcaption></figcaption></figure>

## Requirements for the handler URL

The partner may specify any technically valid handler URL. The handler domain does not have to match the domain of the project website.

#### What is considered a valid URL

The handler URL will be saved if:

* the `http` or `https` protocol is used;
* a valid domain is specified.

**Examples of valid URLs**

* `https://example.com/payment-handler`
* `https://api.example.com/unitpay/callback`
* `http://merchant-service.net/pay`
* `https://xn--e1afmkfd.xn--p1ai/handler`

**Examples of invalid URLs**

* `ftp://example.com/callback` — unsupported protocol
* `https://127.0.0.1/callback` — IP address instead of a domain
* `https://user:password@example.com/callback` — embedded authentication data

### How it works

The typical flow is:

1. The customer starts the payment.
2. Unitpay may send `check` to verify the order before charging.
3. After a successful charge, Unitpay sends `pay`.
4. If an error occurs at any stage, `error` may be sent.
5. For preauthorized payments, `preauth` may be sent first.

{% hint style="success" %}
Important: with preauth, the funds are only blocked. You should deliver the product, provide the service, or credit the balance only after a successful charge.
{% endhint %}

{% hint style="warning" %}
Important: error does not always mean the final status. In some cases, pay may arrive later after error.
{% endhint %}

### What you need to implement on your side

Your handler must:

* accept GET requests from Unitpay;
* verify the sender's IP address;
* verify the `signature`;
* validate `orderSum` and `orderCurrency` against the order data;
* at the `check` stage, only verify the order;
* at the `pay` stage, deliver the product, provide the service, or credit the balance;
* correctly handle repeated requests;
* return JSON in the required format.

{% hint style="warning" %}
Important: unitpayId is the unique payment identifier in Unitpay. If a request with the same unitpayId is received again, do not process the payment a second time: do not deliver the product again, do not provide the service again, and do not credit the balance again.
{% endhint %}

### Methods

#### **`CHECK`**

A request to verify the order before payment.

At this stage, you need to make sure that:

* the order exists;
* the amount and currency match;
* the order can be paid;
* the service can be provided after successful payment.

{% hint style="warning" %}
Important: at the check stage, you must not deliver the product, provide the service, or credit the balance.
{% endhint %}

{% hint style="info" %}
By default, the CHECK request is disabled for a new project. To use it, enable this option in the project settings.
{% endhint %}

<figure><img src="https://244174165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M9Y_k8Gr-WxeECFRelw-887967055%2Fuploads%2F6ecry2sAzbw8XymgUct2%2Fimage.png?alt=media&#x26;token=2c2bb624-ebe9-4d19-9e6f-062acfab66d1" alt=""><figcaption></figcaption></figure>

#### **`PAY`**

A notification of a successful charge.

This is the stage at which you must:

* deliver the product;
* provide the service;
* credit the balance;
* save the payment processing result.

If your server returns an error at this stage, the payment will receive the **"Not completed"** status. After the issue is fixed, the payment can be retried from the statistics interface.

{% hint style="info" %}
Important: funds are credited to the partner's balance regardless of the handler response.
{% endhint %}

{% hint style="warning" %}
Important: pay processing must be idempotent. A repeated request must not result in duplicate product delivery or duplicate crediting.
{% endhint %}

#### **`PREAUTH`**

A notification for preauthorized payments. This means the funds were successfully blocked but have not yet been finally charged.

{% hint style="success" %}
Important: do not deliver the product or provide the service when receiving `preauth`. This must only be done after a successful charge.
{% endhint %}

#### **`ERROR`**

A notification about an error at one of the payment stages.

If the error is caused by an empty or invalid response from the partner's server, the `error` request may not be sent.

{% hint style="warning" %}
Important: `error` is not always the final status. Sometimes pay may arrive after it.
{% endhint %}

### Request format

Unitpay sends a GET request to your handler URL.

Example:

```json
GET https://your_handler_url

method               = check
params[account]      = userId
params[date]         = 2025-10-01 12:32:00
params[paymentType]  = card
params[projectId]    = 123456
params[payerSum]     = 10.00
params[payerCurrency]= USD
params[signature]    = 9bdf52a4830779a1383ac24f1b3ed054
params[orderSum]     = 10.00
params[orderCurrency]= USD
params[unitpayId]    = 1234567890
params[test]         = 0
```

### Параметры запроса

|                    | **Value** | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **method**         | line      | <p>check — request to check the subscriber's status<br>pay — notification of debiting<br>error — error notification</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **unitpayId**      | number    | Internal payment number in UnitPay                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **projectId**      | number    | Project ID in UnitPay                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| **account**        | line      | Subscriber ID in the partner's system                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| **payerSum**       | number    | Amount debited from the subscriber's account                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **payerCurrency**  | line      | Currency of debiting from the subscriber's account according to ISO 4217 standard (USD, EUR, USD)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| **profit**         | number    | Your income from this payment, rubles                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| **phone**          | number    | Payer's phone number (transmitted only for mobile payments)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **paymentType**    | line      | [Payment system code](https://help.unitpay.ru/en/book-of-reference/payment-system-codes)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| **orderSum**       | number    | Order amount. **Make sure to check the received value against the original order amount**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **orderCurrency**  | line      | Order currency according to ISO 4217 (USD, RUB, BYN, EUR, USD). **Make sure to check the received value with the original order currency**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| **operator**       | line      | [Operator alphabetic code](https://help.unitpay.ru/en/book-of-reference/operator-codes)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **date**           | line      | Payment date in the YYYY-mm-dd HH:ii:ss format (for example, 2012-10-01 12:32:00)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| **errorMessage**   | line      | Error details (only for the error method)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **test**           | number    | Sign of test mode: if a request is made using the test request mechanism, the value will equal to 1. For real payments, the value is always 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **3ds**            | number    | Sign of 3-DS for card transaction, the flag is present for PAY notifications                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **subscriptionId** | number    | Subscription ID, it returns after successful payment of the setup fee under the subscription. It is present for PAY notifications                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| **signature**      | line      | <p>Digital signature. It is generated as sha256(method + "{up}" + params + "{up}" + secretKey),<br>where <strong>sha256</strong> is the encryption method;<br><strong>"{up}"</strong> is the parameter separator in the hash function;<br><strong>method</strong> is the request type (check, pay, error);<br><strong>params</strong> are the values of the parameter from the params arra, combined with the "{up}" separator. All parameters must be pre-sorted by key; the signature parameter do not participate in merging;<br><strong>secretKey</strong> is the project secret key (available in your personal account);</p><p>Example of computing the signature for the request <a href="http://partnerurl/?method=check%20&#x26;%20params%5bb%5d=bob&#x26;params%5bc%5d=sam&#x26;params%5ba%5d=tod"><strong><http://partnerUrl?method=check> & params\[b]=bob & params\[c]=sam & params\[a]=tod</strong></a> and secret key <strong>"a1b1c1d1"</strong></p><p><strong>sha256</strong>("check{up}tod{up}bob{up}sam{up}a1b1c1d1")</p> |

#### Successful response

If the request is processed successfully, return:

### Успешный ответ

Если запрос обработан успешно, верните:

```json
{
    "result": {
        "message": "Request processed successfully"
    }
}
```

| **message** | string | Text status of request execution |
| ----------- | ------ | -------------------------------- |

#### Error response

If the request cannot be processed, return:

```json
{
    "error": {
        "message": "Error description"
    }
}
```

<table data-header-hidden><thead><tr><th width="200.44441731770831">Парамтер</th><th width="186.3333740234375">Значение</th><th>Описание</th></tr></thead><tbody><tr><td><strong>message</strong></td><td>string</td><td>Information describing the payment processing error.<br>When using the payment form, the text from the <code>message</code> parameter will be shown to the payer.</td></tr></tbody></table>

#### Common integration mistakes

Most often, problems occur because:

* `signature` is not verified;
* IP addresses are not verified;
* `orderSum` and `orderCurrency` are not validated;
* the product is delivered at the `check` stage instead of the `pay` stage;
* the server returns invalid JSON.
