Integración PHP completa usando la iexbase/tron-api librería. Cada paso es un bloque de código independiente que puedes copiar en tu proyecto. Funciona con cualquier framework PHP o PHP plano.
Requisitos previos: PHP 7.4+, Composer, ext-gmp y ext-bcmath habilitados, una billetera Tron financiada.
Acerca de firmar en PHP: La API de TronEnergy requiere una firma de billetera usando tronWeb.trx.signMessageV2(). La iexbase/tron-api librería no expone esta primitiva de firma exacta, así que esta guía utiliza un pequeño ayudante Node.js para el paso de firma. Todo lo demás (enviar TRX, llamar a la API, enviar USDT) permanece en PHP. Si tienes una solución de firma PHP pura que produce una firma signMessageV2 válida, puedes reemplazar el ayudante sin cambiar ningún otro paso.
El Flujo
Sin clave API. Sin registro. Tu código envía TRX en cadena a la dirección de pago de TronEnergy, firma un mensaje probando propiedad, luego reclama la delegación. La energía llega en aproximadamente 3 segundos. Luego tu código envía USDT usando la energía delegada.
1
Enviar TRX
Envía 4 o más TRX a la dirección de pago en cadena (mín. 4, máx. 1000).
2
Firmar
Firma tx_hash:delegate_to para probar que eres el remitente.
3
Reclamar
POST /delegate con el hash de transacción y la firma. La energía llega en ~3s.
El precio es lineal: 16,250 Energía por TRX. Orden mínima 4 TRX (65,000 Energía — una transferencia USDT estándar), máximo 1,000 TRX (16.25M Energía). El monto que envías determina exactamente cuánta Energía se delega — sin niveles, sin paquetes. Para una transferencia estándar única, usa $trxAmount = 4. Para una transferencia de billetera nueva, usa 8. Para trabajo en lote, usa más. El código abajo usa una variable $trxAmount para que puedas cambiarla en un solo lugar.
Paso a Paso
1. Instalar
composer require iexbase/tron-api
2. Configurar
require_once 'vendor/autoload.php';
use IEXBase\TronAPI\Tron;
$tron = new Tron();
$tron->setPrivateKey('YOUR_PRIVATE_KEY');
$tron->setAddress('YOUR_WALLET_ADDRESS');
$api = 'https://api.tronnrg.com';
$addr = 'TFqUiCu1JwLHHnBNeaaVKH7Csm4aA3YhZx'; // API payment address
$usdt = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'; // USDT contract
Nunca codifiques credenciales. Carga tu clave privada desde variables de entorno o un gestor de secretos. Nunca hagas commit de secretos en git.
4. Enviar TRX
// Send TRX to the API payment address — pricing is linear.
// 16,250 energy per TRX. Min 4 TRX, max 1,000 TRX.
// $trxAmount = 4 → 65,000 energy (standard USDT transfer)
// $trxAmount = 8 → 130,000 energy (new wallet transfer)
// $trxAmount = 40 → 650,000 energy (10 standard transfers)
// $trxAmount = 1000 → 16,250,000 energy (max)
$trxAmount = 4;
$payment = $tron->sendTrx($addr, $trxAmount);
if (!isset($payment['result']) || !$payment['result']) {
throw new Exception('TRX transfer failed');
}
$txHash = $payment['txid'];
echo "Payment sent: ${txHash}\n";
5. Firmar el Mensaje
La API requiere una firma que pruebe que la misma billetera que envió el TRX está pidiendo la delegación. Lo hacemos con un pequeño helper de Node.js. Guárdalo como sign.js junto a tu archivo PHP:
// Usage: node sign.js <tx_hash> <delegate_to>
// Outputs the signature to stdout. Reads private key from TRON_PRIVATE_KEY env var.
const { TronWeb } = require('tronweb');
const [, , txHash, delegateTo] = process.argv;
const tronWeb = new TronWeb({
fullHost: 'https://api.trongrid.io',
privateKey: process.env.TRON_PRIVATE_KEY,
});
tronWeb.trx.signMessageV2(`${txHash}:${delegateTo}`)
.then(sig => process.stdout.write(sig))
.catch(e => { console.error(e.message); process.exit(1); });
Instala TronWeb en la misma carpeta: npm install tronweb. Luego llámalo desde PHP:
// Both the sender (in $tron) and the signer must be the SAME wallet.
// Make sure TRON_PRIVATE_KEY in your environment matches the wallet that sent the TRX.
$delegateTo = 'TWalletThatNeedsEnergy';
$signature = trim(shell_exec(
sprintf('node sign.js %s %s',
escapeshellarg($txHash),
escapeshellarg($delegateTo)
)
));
if (!$signature) {
throw new Exception('Signing failed. Check that node and tronweb are installed and TRON_PRIVATE_KEY is set.');
}
echo "Signed: " . substr($signature, 0, 20) . "...\n";
6. Reclamar la Delegación
// $txHash, $delegateTo, and $signature are all defined in the previous steps.
$ch = curl_init("${api}/delegate");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'tx_hash' => $txHash,
'delegate_to' => $delegateTo,
'signature' => $signature,
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
echo "Energy: " . $result['energy'] . "\n";
echo "Ref: " . $result['ref'] . "\n";
7. Enviar USDT
// Energy is now delegated. Send USDT.
$contract = $tron->contract($usdt);
$transfer = $contract->transfer($delegateTo, 10 * pow(10, 6));
echo "USDT sent: " . $transfer . "\n";
Manejo de Errores
Envuelve la llamada claim en un pequeño helper de reintentos. El error más común es payment_verification_failed cuando la tx aún no está indexada en cadena — espera unos segundos e intenta de nuevo.
function claimDelegation($api, $txHash, $delegateTo, $signature, $retries = 3) {
for ($i = 0; $i < $retries; $i++) {
$ch = curl_init("${api}/delegate");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'tx_hash' => $txHash,
'delegate_to' => $delegateTo,
'signature' => $signature,
]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!isset($result['error'])) {
return $result; // Success
}
switch ($result['error']) {
case 'payment_verification_failed':
// Most common: tx not yet indexed. Wait and retry.
sleep(3);
continue 2;
case 'hash_already_used':
throw new Exception('This tx hash has already been claimed');
case 'signature_mismatch':
throw new Exception('Signer does not match payment sender. Sign with the same wallet that sent TRX.');
case 'delegation_failed':
// Refund queued automatically if payment was verified
throw new Exception('Delegation failed: ' . $result['message']);
default:
throw new Exception($result['message'] ?? 'Unknown error');
}
}
throw new Exception('Transaction not found after retries');
}
Ejemplo Completo
<?php
require_once 'vendor/autoload.php';
use IEXBase\TronAPI\Tron;
$tron = new Tron();
$tron->setPrivateKey(getenv('TRON_PRIVATE_KEY'));
$tron->setAddress(getenv('TRON_WALLET_ADDRESS'));
$api = 'https://api.tronnrg.com';
$addr = 'TFqUiCu1JwLHHnBNeaaVKH7Csm4aA3YhZx';
try {
$delegateTo = 'TRecipientWallet';
$trxAmount = 4; // min 4, max 1000 — energy = trxAmount × 16,250
// 1. Send TRX (linear pricing: 16,250 energy per TRX)
$payment = $tron->sendTrx($addr, $trxAmount);
$txHash = $payment['txid'];
echo "Payment: ${txHash}\n";
// 2. Sign via Node helper (see Step 5 above)
$signature = trim(shell_exec(
sprintf('node sign.js %s %s',
escapeshellarg($txHash),
escapeshellarg($delegateTo)
)
));
if (!$signature) throw new Exception('Signing failed');
// 3. Claim delegation (with retry)
$result = claimDelegation($api, $txHash, $delegateTo, $signature);
echo "Energy: " . $result['energy'] . "\n";
echo "Ref: " . $result['ref'] . "\n";
// 4. Send USDT (energy is now available)
$contract = $tron->contract('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t');
$transfer = $contract->transfer($delegateTo, 10 * pow(10, 6));
echo "USDT sent: ${transfer}\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}