Log in

API Documentation
  • Main
  • Getting API keysRequest format
  • Payments
    Getting started Creating an invoice Creating a Static wallet Generate a QR-code Block static wallet Refund payments on blocked address Payment information Resend webhook Testing webhook List of services Payment history Webhook Payment statuses AML links
    Payouts
    Getting started Calculation of the withdrawal amount Creating a payout Payout information Refund Payout history Payout statuses Webhook List of services Transfer to personal wallet Transfer to business wallet
  • Host to host(white label)
  • SDK
    PHP GO PYTHON NODEJS
  • CMS Modules
  • Discount Payment
    List of discounts Set discount to payment method
  • Exchange rates listBalanceReference

Main

/

Host to host (white label)

Copy page
FAQAPIContacts

Ⓒ 2026 Heleket

Privacy policy

Terms of use

AML

FAQAPIContacts

Host-to-Host (H2H) integration for Heleket merchants

This guide describes accepting crypto payments through direct server-to-server interaction with the Heleket API. Unlike the ready-made payment page, your backend creates invoices, receives payment details, and handles payment status notifications. You can render the payment form on your side or use the URL returned in the API response.

1. What you need before starting

You need two values from your account to accept payments:

ValueWhere to get
Merchant IDMerchant UUID. Go to Business → Merchants → Merchant settings.
Payment API keyGenerated in the merchant settings after moderation.

Where to get

Merchant UUID. Go to Business → Merchants → Merchant settings.

Where to get

Generated in the merchant settings after moderation.

How to get the payment API key

  1. Go to Business → Merchants → Create merchant and enter a name.
  2. Submit an application, enter the website URL, and confirm the domain.
  3. Wait until the merchant is approved.
  4. Copy the payment API key and Merchant ID from Settings.

The payout API key is issued separately in Settings → API, requires two-factor authentication, and is not needed to accept payments.

Base endpoint for all requests:

https://api.heleket.com/
Copy

All API requests use POST with JSON and must be signed.

2. Request authentication and signature

Each request is authenticated with two HTTP headers:

HeaderValue
merchantYour Merchant ID (UUID).
signRequest body signature.
Content-Typeapplication/json

Value

Your Merchant ID (UUID).

Value

Request body signature.

Value

application/json

The signature is an MD5 hash of the base64-encoded JSON request body concatenated with your API key.

$body = json_encode($data);
$sign = md5(base64_encode($body) . $API_KEY);
Copy

For requests without body parameters, calculate the signature from an empty string:

$sign = md5(base64_encode('') . $API_KEY);
Copy

Important: slash escaping. PHP escapes / in JSON (\/) by default, while many other languages do not. The signature is calculated from the same string sent in the request body, so the string used for signing and the request body must be byte-for-byte identical. In non-PHP stacks, escape slashes manually; otherwise, the signature will not match (the same issue occurs when verifying webhooks; see section 5).

Signed request example

curl https://api.heleket.com/v1/payment \
  -X POST \
  -H 'merchant: 8b03432e-385b-4670-8d06-064591096795' \
  -H 'sign: fe99035f86fa436181717b302b95bacff1' \
  -H 'Content-Type: application/json' \
  -d '{"amount":"15","currency":"USD","order_id":"1"}'
Copy

3. H2H flow

  1. The customer places an order with you → you save the order_id on your side
  2. Your server → POST /v1/payment → Heleket returns the uuid, address, amount, and url
  3. You show the customer the payment details / address / QR code (or the url link)
  4. The customer pays on the blockchain
  5. Heleket → POST to your url_callback (webhook) whenever the status changes
  6. You verify the webhook signature → update the order
  7. (Fallback) periodically poll POST /v1/payment/info by order_id

Do not rely only on the webhook: always keep a fallback through /v1/payment/info (section 6) in case the callback is not delivered.

4. Creating a payment

Endpoint:

POST
https://api.heleket.com/v1/payment
Copy

Main request parameters

ParameterTypeRequiredDescription
amountstringyesAmount to pay. Use a period as the decimal separator, for example, 10.28.
currencystringyesInvoice currency code (fiat or cryptocurrency), for example, USD, USDT, or BTC.
order_idstringyesYour order identifier. It may contain only letters, digits, _ and -. It must be unique.
networkstringnoBlockchain network code, for example, tron, bsc, or eth.
to_currencystringnoTarget cryptocurrency for amount conversion (always a cryptocurrency code, not fiat).
url_callbackstringnoURL to which Heleket sends status webhooks. It is effectively required for H2H.
url_returnstringnoWhere to return the customer from the payment form before payment.
url_successstringnoWhere to return the customer after successful payment.
lifetimeintegernoInvoice lifetime in seconds (300–43200; 3600 by default).
subtractintegernoPercentage of the fee to pass on to the customer (0–100).
accuracy_payment_percentnumericnoAllowed underpayment percentage (0–5): the invoice is marked as paid when the underpayment is within this limit.
is_payment_multiplebooleannoAllow the remaining balance to be paid. The default is true.
additional_datastringnoAn arbitrary string for your use (not visible to the customer), up to 255 characters.
currenciesarraynoAllowlist of currencies and networks available for payment.
except_currenciesarraynoBlocklist of currencies and networks.
discount_percentintegernoDiscount (positive) or surcharge (negative), from -99 to 100.
is_refreshbooleannoRefresh an expired invoice with the same order_id (new address and expiration time).

Type

string

Required

yes

Description

Amount to pay. Use a period as the decimal separator, for example, 10.28.

Type

string

Required

yes

Description

Invoice currency code (fiat or cryptocurrency), for example, USD, USDT, or BTC.

Type

string

Required

yes

Description

Your order identifier. It may contain only letters, digits, _ and -. It must be unique.

Type

string

Required

no

Description

Blockchain network code, for example, tron, bsc, or eth.

Type

string

Required

no

Description

Target cryptocurrency for amount conversion (always a cryptocurrency code, not fiat).

Type

string

Required

no

Description

URL to which Heleket sends status webhooks. It is effectively required for H2H.

Type

string

Required

no

Description

Where to return the customer from the payment form before payment.

Type

string

Required

no

Description

Where to return the customer after successful payment.

Type

integer

Required

no

Description

Invoice lifetime in seconds (300–43200; 3600 by default).

Type

integer

Required

no

Description

Percentage of the fee to pass on to the customer (0–100).

Type

numeric

Required

no

Description

Allowed underpayment percentage (0–5): the invoice is marked as paid when the underpayment is within this limit.

Type

boolean

Required

no

Description

Allow the remaining balance to be paid. The default is true.

Type

string

Required

no

Description

An arbitrary string for your use (not visible to the customer), up to 255 characters.

Type

array

Required

no

Description

Allowlist of currencies and networks available for payment.

Type

array

Required

no

Description

Blocklist of currencies and networks.

Type

integer

Required

no

Description

Discount (positive) or surcharge (negative), from -99 to 100.

Type

boolean

Required

no

Description

Refresh an expired invoice with the same order_id (new address and expiration time).

About order_id: if an invoice with this order_id already exists, a new one will not be created—the existing payment details will be returned. This provides idempotency: repeating a request for the same order is safe.

When the wallet address is returned immediately. The address field is populated on creation only when the payment currency is unambiguous: the cryptocurrency and network are specified (to_currency + network), or the cryptocurrency has only one network (for example, BTC). Otherwise, the customer selects the currency and network on the payment page, and the address appears later.

Request body examples

Minimal invoice for 15 USD (the customer selects the cryptocurrency and network):

{ "amount": "15", "currency": "USD", "order_id": "1" }
Copy

Invoice for 20 USDT on the TRON network—the address is returned immediately:

{ "amount": "20", "currency": "USDT", "order_id": "1", "network": "tron" }
Copy

Invoice for 25 USD payable only in USDT on any network:

{ "amount": "25", "currency": "USD", "order_id": "1", "to_currency": "USDT" }
Copy

Response example

{
1  "state": 0,
2  "result": {
3    "uuid": "1ec87133-b22d-4643-988f-cac29a6ac85d",
4    "order_id": "3",
5    "amount": "20000.00",
6    "payment_amount": null,
7    "payer_amount": "254.92",
8    "payer_currency": "USDT",
9    "currency": "RUB",
10    "merchant_amount": "249.82816502",
11    "network": "bsc",
12    "address": "0x2b...",
13    "txid": null,
14    "payment_status": "check",
15    "url": "https://pay.heleket.com/pay/1ec87133-b22d-4643-988f-cac29a6ac85d",
16    "expired_at": 1753202502,
17    "is_final": false,
18    "commission": "5.09853397",
19    "address_qr_code": "data:image/png;base64 ..."
20  }
21}
Copy

Key response fields

FieldPurpose
uuidInvoice UUID in Heleket. Store it with the order.
addressPayment wallet address. It may be null until the currency is selected.
payer_amountAmount to pay in payer_currency, including a discount or surcharge.
payer_currencyPayment currency. Null means that the customer has not selected it yet.
merchant_amountAmount credited to your balance after fees.
payment_statusCurrent status (see section 7).
urlLink to the Heleket payment page if you do not render the form yourself.
address_qr_codeBase64-encoded QR code of the payment address.
expired_atInvoice expiration Unix timestamp.
is_finalWhether the invoice is finalized and can no longer be paid.

Purpose

Invoice UUID in Heleket. Store it with the order.

Purpose

Payment wallet address. It may be null until the currency is selected.

Purpose

Amount to pay in payer_currency, including a discount or surcharge.

Purpose

Payment currency. Null means that the customer has not selected it yet.

Purpose

Amount credited to your balance after fees.

Purpose

Current status (see section 7).

Purpose

Link to the Heleket payment page if you do not render the form yourself.

Purpose

Base64-encoded QR code of the payment address.

Purpose

Invoice expiration Unix timestamp.

Purpose

Whether the invoice is finalized and can no longer be paid.

state: 0 means success. For validation errors, state: 1 (section 8).

5. Webhook payment status notifications

Heleket sends a POST webhook whenever the invoice status changes.

Main webhook fields

FieldDescription
typeType: payment or wallet.
uuidPayment UUID.
order_idYour order identifier, used to find the order.
amountInvoice amount.
payment_amountAmount actually paid by the customer.
payment_amount_usdAmount actually paid in USD.
merchant_amountAmount credited to the balance after the fee.
commissionHeleket fee.
is_finalWhether the invoice is finalized.
statusPayment status (see section 7).
fromPayer wallet address.
networkPayment network.
currencyInvoice currency.
payer_currencyCurrency actually used for payment.
txidBlockchain transaction hash (may be absent for P2P or manual closing).
signWebhook signature used for verification.

Description

Type: payment or wallet.

Description

Payment UUID.

Description

Your order identifier, used to find the order.

Description

Invoice amount.

Description

Amount actually paid by the customer.

Description

Amount actually paid in USD.

Description

Amount credited to the balance after the fee.

Description

Heleket fee.

Description

Whether the invoice is finalized.

Description

Payment status (see section 7).

Description

Payer wallet address.

Description

Payment network.

Description

Invoice currency.

Description

Currency actually used for payment.

Description

Blockchain transaction hash (may be absent for P2P or manual closing).

Description

Webhook signature used for verification.

Webhook payload example

{
1  "type": "payment",
2  "uuid": "62f88b36-a9d5-4fa6-aa26-e040c3dbf26d",
3  "order_id": "97a75bf8eda5cca41ba9d2e104840fcd",
4  "amount": "3.00000000",
5  "payment_amount": "3.00000000",
6  "merchant_amount": "2.94000000",
7  "commission": "0.06000000",
8  "is_final": true,
9  "status": "paid",
10  "from": "THgEWubVc8tPKXLJ4VZ5zbiiAK7AgqSeGH",
11  "network": "tron",
12  "currency": "TRX",
13  "payer_currency": "TRX",
14  "txid": "6f0d9c8374db57cac0d806251473de754f361c83a03cd805f74aa9da3193486b",
15  "sign": "a76c0d77f3e8e1a419b138af04ab600a"
16}
Copy

Required webhook verification

Because you deliver a product or credit a user’s balance based on a webhook, you must ensure that the request came from Heleket. Verify it using both methods:

  1. Allow callback requests only from the Heleket IP address: 31.133.220.8.
  2. Signature verification. The signature is calculated using the same algorithm as for requests, but is verified as follows:
// 1. Read the raw request body
1$data = json_decode(file_get_contents('php://input'), true);
2
3// 2. Extract and remove the signature from the array
4$sign = $data['sign'];
5unset($data['sign']);
6
7// 3. Calculate the hash from the body (without sign) plus your payment API key
8$hash = md5(base64_encode(json_encode($data, JSON_UNESCAPED_UNICODE)) . $apiPaymentKey);
9
10// 4. Compare
11if (!hash_equals($hash, $sign)) {
12    // invalid signature — reject
13    http_response_code(400);
14    exit;
15}
Copy

The same slash issue described in section 2 applies: when encoding JSON outside PHP, escape / manually (JSON.stringify(data).replace(/\//g, "\\/") in JS); otherwise, the signature will not match.

Webhook processing recommendations

  • Idempotency. The same status may be delivered more than once (including through manual resending). Use order_id + status and do not deliver the product twice.
  • React to final statuses (paid, paid_over), not intermediate ones.
  • Return HTTP 200 only after the webhook is processed successfully.
  • Compare payment_amount and merchant_amount with the expected order amount.

6. Status polling as a webhook fallback

Endpoint:

POST
https://api.heleket.com/v1/payment/info
Copy

Pass uuid or order_id (if both are passed, order_id takes priority).

curl https://api.heleket.com/v1/payment/info \
  -X POST \
  -H 'merchant: 8b03432e-385b-4670-8d06-064591096795' \
  -H 'sign: <body signature>' \
  -H 'Content-Type: application/json' \
  -d '{"order_id":"1"}'
Copy

The response contains the same payment object with its current payment_status and is_final values. Use this method for periodic reconciliation of “stuck” orders, not as the primary mechanism (webhooks are faster and require fewer requests).

7. Payment statuses

StatusFinalMeaning
checknoWaiting for the transaction to appear on the blockchain.
processnoThe payment is being processed.
confirm_checknoThe transaction is visible; waiting for the required number of network confirmations.
wrong_amount_waitingnoUnderpayment with the option to pay the remaining balance.
paidyesThe exact required amount was paid. Deliver the product.
paid_overyesMore than the required amount was paid. Deliver the product.
wrong_amountyesThe customer paid less than required.
failyesPayment error.
cancelyesThe payment was cancelled; the customer did not pay.
system_failyesSystem error.
lockedyesFunds are locked under the AML program.
refund_processnoThe refund is being processed.
refund_paidyesThe refund was completed.
refund_failyesRefund error.

Final

no

Meaning

Waiting for the transaction to appear on the blockchain.

Final

no

Meaning

The payment is being processed.

Final

no

Meaning

The transaction is visible; waiting for the required number of network confirmations.

Final

no

Meaning

Underpayment with the option to pay the remaining balance.

Final

yes

Meaning

The exact required amount was paid. Deliver the product.

Final

yes

Meaning

More than the required amount was paid. Deliver the product.

Final

yes

Meaning

The customer paid less than required.

Final

yes

Meaning

Payment error.

Final

yes

Meaning

The payment was cancelled; the customer did not pay.

Final

yes

Meaning

System error.

Final

yes

Meaning

Funds are locked under the AML program.

Final

no

Meaning

The refund is being processed.

Final

yes

Meaning

The refund was completed.

Final

yes

Meaning

Refund error.

Treat paid and paid_over as successful payments. confirm_check may also appear in webhooks as an intermediate status.

8. Error handling

Validation errors — HTTP 422, state: 1:

{ "state": 1, "errors": { "amount": ["validation.required"] } }
Copy

Common messages (state: 1, message field):

MessageReason
The network was not foundAn unsupported network code was provided.
The currency was not foundAn unsupported currency code was provided.
Not found service to_currencyNo payment service is available for to_currency.
Minimum amount 0.5 USDTThe amount is below the minimum for the currency.
Maximum amount 10000000 USDTThe amount exceeds the maximum for the currency.
Wallet not foundNo active merchant wallet is available for the payment currency.
You are forbiddenPayments are blocked. Contact support.
Gateway error / Server errorA temporary technical issue occurred and the payment is unavailable.

Reason

An unsupported network code was provided.

Reason

An unsupported currency code was provided.

Reason

No payment service is available for to_currency.

Reason

The amount is below the minimum for the currency.

Reason

The amount exceeds the maximum for the currency.

Reason

No active merchant wallet is available for the payment currency.

Reason

Payments are blocked. Contact support.

Reason

A temporary technical issue occurred and the payment is unavailable.

Internal error — HTTP 500:

{ "message": "Server error, #1", "code": 500, "error": null }
Copy

Treat Gateway error, Server error, and HTTP 500 as temporary and retry with exponential backoff.

9. Integration checklist

  • The merchant is approved, and the Merchant ID and payment API key are available.
  • Request signing is implemented, including forward-slash escaping.
  • Invoice creation uses POST /v1/payment with a unique order_id and url_callback.
  • The webhook endpoint is available over HTTPS and accepts POST requests.
  • Webhook requests are checked by IP address and signature.
  • Webhook processing is idempotent.
  • The product or service is delivered only for paid and paid_over after amount verification.
  • Fallback polling through POST /v1/payment/info is implemented.
  • uuid, order_id, txid, and statuses are logged.
  • API keys are stored in secrets, not in the codebase.

See the related documentation for currency and network codes, refunds, static wallets, and payouts.