> For the complete documentation index, see [llms.txt](https://ton-play-1.gitbook.io/ton-play-1/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ton-play-1.gitbook.io/ton-play-1/payment-solution/webhook.md).

# Webhook

Webhook is a complete URL on the merchant’s side, which can receive POST requests and is publicly available. For example, `https://webhook.site/30206e12-5da4-4805-a6d3-cbf77e60fa08`

After a successful operation, the payment service will send to the merchant's webhook address next payload:

<details>

<summary>Pay-in</summary>

<pre class="language-json"><code class="lang-json">{ 
    "orderId": String, 
<strong>    "customer": String?, 
</strong><strong>    "amount": Numeric, 
</strong><strong>    "hash": String 
</strong><strong>}
</strong></code></pre>

`orderId` - external order id&#x20;

`customer` - (optional) user's TON wallet address who made payment

`amount` - payment amount in nanoton&#x20;

`hash` - payload signature

</details>

<details>

<summary>Payout</summary>

```json
{ 
    "targets": Int, 
    "amount": Numeric, 
    "successful": Boolean,
    "hash": String,
    "orderId": String
}
```

`targets` - number of payout targets

`amount` - total amount of all outgoing payments

`hash` - payload signature

`orderId` - external order id (if it was presented)

</details>

### Payload signature validation

We use a signature for each event to prevent malicious requests on your webhook endpoints.&#x20;

You can verify that this event was sent by the original TPAY service and the integrity of the data received by comparing the received *hash* parameter with the hexadecimal representation of the [HMAC-SHA-256](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) signature of the **data-check-string** with the [SHA256](https://en.wikipedia.org/wiki/SHA-2) hash of the merchant's **`paymentKey`** used as a secret key.

**Data-check-string** is a concatenation of all received fields, sorted in alphabetical order in the format `key=<value>` with a [line feed](https://en.wikipedia.org/wiki/Newline) character ('\n', 0x0A) used as a separator – e.g.,

&#x20;`'amount=<amount>\ncustomer=<customer>\norderId=<orderId>'`.

The full check might look like this:

```
data_check_string = ...
secret_key = SHA256(<payment_key>)
if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash) 
{
  // request is valid
}
```

*Note: you can use* [*this page*](https://gist.github.com/anonymous/6516521b1fb3b464534fbc30ea3573c2) *with Telegram auth validation as an example of a multi-language implementation of this logic.*
