Skip to content

Webhook

The webhook notifies your backend, via a signed POST, whenever a TRP transaction changes status — so you don’t have to keep polling for the status.

There are two levels, which can be combined.

Set a URL that receives notifications for all of your transactions. Only the partner owner can configure it.

The easiest way is the Webhook screen in the console (side menu): paste the URL, generate the secret, and enable it — no code. For automation, the same endpoints are available via the API (authenticate with the console session token):

Terminal window
curl -X PUT https://api.tonramp.io/v1/partner/webhook \
-H "Authorization: Bearer <session-token>" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-store.com/webhooks/tonramp"}'

Response — the secret is shown only once (store it securely; it’s what you use to validate the signature):

{ "webhook_url": "https://your-store.com/webhooks/tonramp", "webhook_enabled": true, "secret": "<signing-secret>" }

GET /v1/partner/webhook retrieves the current configuration (without the secret); DELETE /v1/partner/webhook disables it.

For a callback specific to a single transaction, send callback_url in the POST /v1/wallet/trp/generate. It takes priority over the account webhook for that tx_id. The URL does not go in the payload — it is stored on the server.

Terminal window
curl -X POST https://api.tonramp.io/v1/wallet/trp/generate \
-H "Authorization: Bearer tonr_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"wallet": "UQBJ6gU8gh_jRrzYDlfw9cpCwHaSn2mrK4O-1h8CDENehGYJ",
"merchant": "store123",
"amount": 100.00,
"currency": "USDT",
"tx_id": "order-001",
"callback_url": "https://your-store.com/webhooks/order-001"
}'

After configuring, fire a test webhook to verify that your endpoint receives the POST and validates the signature — without depending on a real transaction.

  • In the console: Webhook screen → Test webhook button. Shows, in real time, the HTTP status your endpoint returned.
  • Via API: POST /v1/partner/webhook/test (owner only, console session token).
Terminal window
curl -X POST https://api.tonramp.io/v1/partner/webhook/test \
-H "Authorization: Bearer <session-token>"

The response carries the delivery result — the HTTP status your endpoint returned:

{ "delivered": true, "status_code": 200, "url": "https://your-store.com/webhooks/tonramp", "error": null }

The body sent is a sample signed with event: "trp.webhook.test" and test: true — it does not correspond to any real order.

The POST is sent on these status changes:

statusmeaning
paidPIX received, processing the USDT delivery
completedUSDT delivered, transaction concluded
errorprocessing failure
expiredexpired without payment
cancelledcancelled

Content-Type: application/json:

{
"event": "trp.transaction.status",
"tx_id": "order-001",
"order_id": "topup_order-00_a1b2",
"status": "completed",
"amount_usdt": 100.0,
"amount_brl": 567.63,
"partner_id": 7,
"attempt": 1
}
  • tx_id — the tx_id from the TRP payload (field 05), to match with your order.
  • status — see the events table above.
  • attempt — the delivery attempt number (increments on retries).

Each request carries the headers:

X-TonRamp-Signature: sha256=<hmac_sha256(secret, raw_body)>
X-TonRamp-Event: trp.transaction.status

Compute the HMAC-SHA256 of the raw body received (do not reserialize the JSON) with your secret and compare in constant time.

import hmac
import hashlib
def verify(secret: str, body: bytes, header: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)

Respond 2xx to confirm receipt. On error, timeout, or status >= 300, the delivery is retried with backoff (up to 5 attempts). Since there may be a retry, handle the notification idempotently (for example, by deduplicating on tx_id + status).