Verify TRON Transactions via API
Payment systems, exchanges, and dApps must confirm TRON transactions programmatically before crediting users. A broadcast txid is not enough — you need execution receipt, success/failure status, and for tokens, decoded Transfer events.
This guide covers confirmation loops with TronWeb and TronGrid REST.
Transaction lifecycle
- Broadcast — Signed tx enters mempool
- Included in block — ~3 seconds typical
- Receipt available —
getTransactionInfopopulated - Solidified — Block considered final (configurable wait)
Failed transactions still consume fees and return FAILED receipt.
Get transaction by ID (TronWeb)
async function waitForTx(txid, maxAttempts = 30, delayMs = 2000) {
for (let i = 0; i < maxAttempts; i++) {
const info = await tronWeb.trx.getTransactionInfo(txid);
if (info && Object.keys(info).length > 0) {
return info;
}
await new Promise((r) => setTimeout(r, delayMs));
}
throw new Error('Transaction info not found — timeout');
}
async function isTxSuccess(txid) {
const info = await waitForTx(txid);
return info.receipt?.result === 'SUCCESS';
}
TronGrid REST
GET /v1/transactions/{txid}
GET /wallet/gettransactioninfobyid?value={txid}
Add TRON-PRO-API-KEY header per TronGrid guide.
Validate USDT transfer details
Do not trust client-supplied amounts alone. Parse logs:
const USDT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';
function parseUsdtTransferFromInfo(txInfo) {
const logs = txInfo.log || [];
for (const log of logs) {
if (tronWeb.address.fromHex(log.address) !== USDT) continue;
// Transfer(address,address,uint256) topic0 = 0xddf252ad...
// Decode topics[1] from, topics[2] to, data value
// Use tronWeb.utils.abi.decodeLog or ethers ABI decoder
}
}
Confirm:
- Token contract = official USDT
to= your deposit addressvalue= expected amount (6 decimals)
Pending and missing transactions
| Situation | Meaning |
|---|---|
| getTransactionInfo empty | Not mined yet — keep polling |
| FAILED receipt | Revert, OUT_OF_ENERGY, etc. |
| Tx not found | Wrong txid or never broadcast |
User guide: pending transactions.
Block solidification
For high-value deposits:
const block = await tronWeb.trx.getBlockByNumber(info.blockNumber); // Optionally wait N more blocks via getCurrentBlock()
TRON finality is fast; many merchants use single SUCCESS.
Matching business records
Idempotent credit flow:
- User submits txid
- Server verifies SUCCESS + parse Transfer
- Check txid not already credited in database
- Credit user balance
- Store block number, timestamp, raw log
Failed transaction diagnostics
Read resMessage / contract result hex for revert reason. Common:
OUT_OF_ENERGY- Insufficient token balance
- Contract paused
Troubleshooting: transaction failed.
Webhook integration pattern
Poll gettransactioninfobyid every 3 seconds until blockNumber > 0 or timeout (5 minutes). On SUCCESS, emit internal webhook. On REVERT or timeout, mark payment failed and alert operations team.
Handling REVERT and false positives
getTransactionInfo returns receipt.result = REVERT for failed execution — do not credit payments. Some indexers briefly return empty before confirmation — distinguish null receipt (pending) from REVERT (failed). Implement timeout after 5–10 minutes and human review queue for ambiguous cases.
Related guides
FAQ
How many confirmations does TRON need?
TRON uses solidified blocks quickly — most apps treat one SUCCESS receipt as final. High-value apps may wait for additional block solidification.
What is the difference between getTransaction and getTransactionInfo?
getTransaction returns broadcast data; getTransactionInfo includes receipt, fees, Energy used, and contract result after execution.
Can a tx show SUCCESS but wrong amount?
Always parse event logs — verify amount and recipient match order.
How long to poll?
Usually under 10 seconds. Timeout after 60–120s and ask user for TronScan link.
TronScan vs API?
Same chain data. API for automation; TronScan guide for manual debug.
Thanks — your feedback helps us improve the docs.