Zum Hauptinhalt springen

TRON-Smart-Contract-Integration

Diese Anleitung erklärt, wie Sie Non-Custodial-Krypto-Zahlungen auf TRON mit den Zahlungs-Smart-Contracts von Volet.com und TronWeb annehmen.

Kunden verbinden ihre Wallets, bestätigen Transaktionen und zahlen über einen Smart Contract direkt auf Ihr Empfangs-Wallet. Die Gelder werden keinem Volet.com-Konto gutgeschrieben.

Bevor Sie fortfahren, lesen Sie den Überblick über den Zahlungsablauf unter Smart-Contract-Integration.

Integration im Überblick​

  1. Wallet des Kunden verbinden und bestätigen, dass es TRON Mainnet verwendet.
  2. Zahlungs-Contracts und Ihr Empfangs-Wallet konfigurieren.
  3. Vor der Zahlung eine Bestellung im Backend erstellen.
  4. previewPayment() aufrufen, um den Gesamtbetrag der Zahlung zu berechnen.
  5. transfer() aufrufen, um die Zahlung auszulösen. Bei USDT die Allowance des Tokens prüfen und bei Bedarf eine Freigabe anfordern.
  6. Den Hash der Zahlungstransaktion (txid) bei der Bestellung speichern.
  7. Die Transaktion im Backend anhand solidified Blockchain-Daten prüfen, bevor die Bestellung als bezahlt markiert wird.

Bevor Sie beginnen​

Sie benötigen:

  • Wallet des Kunden: TronLink für Zahlungen im Browser.
  • Bibliothek: TronWeb für die Interaktion mit TRON-Wallets und Smart Contracts.
  • Händler-Wallet: eine TRON-Wallet-Adresse unter Ihrer Kontrolle, um Zahlungen zu empfangen.
  • Backend und Datenbank: um Bestellungen zu erstellen, Transaktionsdaten zu speichern und Zahlungen zu prüfen.
  • Blockchain-Zugang: einen TRON-Node oder gehosteten Dienst wie TronGrid, um Transaktionen abzurufen und zu prüfen.

Für die Verbindung mobiler Wallets benötigen Sie außerdem eine WalletConnect Project ID und eine kompatible TRON-Wallet-Integration.

Unterstützte Netzwerke und Assets​

NetzwerkUnterstützte Assets
TRON MainnetTRX, USDT (TRC-20)

TRX und USDT verwenden getrennte Prozessor-Contracts.

TRX-Beträge werden in SUN angegeben, der kleinsten Einheit von TRX. Ein TRX entspricht 1.000.000 SUN.

USDT TRC-20 verwendet 6 Decimals. Ein USDT entspricht 1.000.000 Token-Basiseinheiten.

Die Codebeispiele unten enthalten die Prozessor- und Token-Adressen aus der Integrationskonfiguration.

Contract-Adressen, Token-Decimals und Funktionsparameter finden Sie in der Smart-Contract-Referenz.

Bestätigen Sie die Adressen der bereitgestellten Prozessoren und die Contract-Schnittstelle mit Volet.com, bevor Sie die Beispiele produktiv einsetzen.

Schritt 1. Wallet des Kunden verbinden​

Verbinden Sie das Browser-Wallet des Kunden über TronLink.

<button id="connect-tron">Connect TronLink</button>

<script>
let tronWeb;

document.getElementById('connect-tron').addEventListener('click', async () => {
if (!window.tronLink || !window.tronWeb) {
alert('Install and unlock TronLink.');
return;
}

const result = await window.tronLink.request({
method: 'tron_requestAccounts'
});

if (result?.code !== 200) {
throw new Error('Wallet connection rejected');
}

tronWeb = window.tronWeb;

document.getElementById('connect-tron').textContent =
tronWeb.defaultAddress.base58;
});
</script>

Der Kunde muss sich mit TRON Mainnet verbinden.

Prüfen Sie das aktive Netzwerk, bevor Sie eine Zahlung senden. Bestimmen Sie das Netzwerk nicht allein anhand der URL des RPC-Endpunkts, da Wallets eigene Nodes verwenden können.

Ihre Anwendung sollte außerdem Konto- und Netzwerkwechsel im Wallet erkennen und die Verbindung vor jeder Transaktion erneut validieren.

Schritt 2. Zahlungs-Contracts konfigurieren​

Fügen Sie Ihrer Anwendung die ABI des Zahlungsprozessors und die Token-Funktionen hinzu.

const PROCESSOR_ABI = [
{
name: 'previewPayment',
type: 'function',
stateMutability: 'view',
inputs: [
{ name: 'amount', type: 'uint256' },
{ name: 'buyerPaysCommission', type: 'bool' },
],
outputs: [
{ name: 'commission', type: 'uint256' },
{ name: 'totalPay', type: 'uint256' },
],
},
{
name: 'transfer',
type: 'function',
stateMutability: 'payable',
inputs: [
{ name: 'seller', type: 'address' },
{ name: 'amount', type: 'uint256' },
{ name: 'buyerPaysCommission', type: 'bool' },
{ name: 'optionalCommissionWallet', type: 'address' },
],
outputs: [],
},
];

const TOKEN_ABI = [
{
name: 'balanceOf',
type: 'function',
stateMutability: 'view',
inputs: [{ name: 'account', type: 'address' }],
outputs: [{ type: 'uint256' }],
},
{
name: 'allowance',
type: 'function',
stateMutability: 'view',
inputs: [
{ name: 'owner', type: 'address' },
{ name: 'spender', type: 'address' },
],
outputs: [{ type: 'uint256' }],
},
{
name: 'approve',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'spender', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
outputs: [{ type: 'bool' }],
},
];

const TRON_PROCESSOR_TRX = 'TSK9sgBTjvZa6x2yW1bXNWqvQ57WsVUQ3W';
const TRON_PROCESSOR_USDT = 'TDuE6VueULx5oivQd4MsYr9DEhNMgXNfTm';
const TRON_USDT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';
const TRON_ZERO = 'T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb';

const TRON_FEE_LIMIT = 500_000_000;

Der Zahlungsprozessor bietet zwei Hauptfunktionen:

  • previewPayment(amount, buyerPaysCommission) berechnet die Bearbeitungsgebühr und den Gesamtbetrag, den der Kunde zahlen muss.
  • transfer(seller, amount, buyerPaysCommission, optionalCommissionWallet) führt die Zahlung aus und verteilt die Gelder gemäß den Gebühreneinstellungen des Contracts.

Der Parameter amount wird in den kleinsten Einheiten des Assets angegeben: in SUN für TRX oder in Token-Basiseinheiten für USDT.

Der Parameter buyerPaysCommission legt fest, wer die Bearbeitungsgebühr trägt:

  • true: Die Gebühr wird zur Zahlung des Kunden addiert.
  • false: Die Gebühr wird vom Betrag abgezogen, den der Händler erhält.

Verwenden Sie TRON_ZERO für optionalCommissionWallet, wenn kein Provisions-Wallet eines Partners vorgesehen ist.

Übernehmen Sie den Gesamtbetrag der Zahlung immer aus previewPayment(). Berechnen Sie die Bearbeitungsgebühr nicht selbst.

TRON_FEE_LIMIT im Beispiel ist in SUN angegeben und steht für ein maximales Gebührenlimit von 500 TRX, nicht für die erwartete Transaktionsgebühr. Schätzen Sie vor dem Produktiveinsatz die benötigte Energy und legen Sie ein passendes Gebührenlimit fest.

Vollständige Parameterdefinitionen finden Sie in der Smart-Contract-Referenz.

Schritt 3. TRX annehmen​

Zahlungen in nativem TRX erfordern eine einzige Wallet-Transaktion.

Berechnen Sie mit previewPayment() den genauen SUN-Betrag, der mit der Transaktion gesendet werden muss.

async function payTrx(tronWeb, seller, humanAmount, buyerPaysCommission = true) {
if (!tronWeb.isAddress(seller)) {
throw new Error('Invalid TRON seller address');
}

const processor = tronWeb.contract(
PROCESSOR_ABI,
TRON_PROCESSOR_TRX
);

const amount = tronWeb.toSun(humanAmount).toString();

const preview = await processor.previewPayment(
amount,
buyerPaysCommission
).call();

return processor.transfer(
seller,
amount,
buyerPaysCommission,
TRON_ZERO
).send({
callValue: preview.totalPay.toString(),
feeLimit: TRON_FEE_LIMIT
});
}

Der callValue der Transaktion muss dem totalPay entsprechen, den previewPayment() zurückgibt.

Der Kunde braucht außerdem genug TRX für Blockchain-Ressourcen und Transaktionsgebühren.

Die Funktion gibt den Hash der Zahlungstransaktion (txid) zurück. Speichern Sie ihn bei der bestehenden Bestellung und prüfen Sie die Zahlung, bevor Sie die Bestellung ausführen.

Schritt 4. USDT annehmen​

USDT-TRC-20-Zahlungen laufen über einen Token-Contract und können eine zusätzliche Freigabetransaktion erfordern.

Vor einer Zahlung muss Ihre Anwendung:

  1. Das USDT-Guthaben des Kunden mit balanceOf() prüfen.
  2. Die Allowance des Prozessors mit allowance() prüfen.
  3. Bei unzureichender Allowance eine Freigabe mit approve() anfordern.
  4. Die Bestätigung der Freigabe abwarten.
  5. transfer() aufrufen, um die Zahlung auszuführen.
async function payTronUsdt(tronWeb, seller, amountBaseUnits, buyerPaysCommission = true) {
if (!tronWeb.isAddress(seller)) {
throw new Error('Invalid TRON seller address');
}

if (!/^\d+$/.test(amountBaseUnits) || BigInt(amountBaseUnits) <= 0n) {
throw new Error('USDT amount must be a positive integer in base units');
}

const processor = tronWeb.contract(
PROCESSOR_ABI,
TRON_PROCESSOR_USDT
);

const token = tronWeb.contract(
TOKEN_ABI,
TRON_USDT
);

const owner = tronWeb.defaultAddress.base58;

const preview = await processor.previewPayment(
amountBaseUnits,
buyerPaysCommission
).call();

const total = BigInt(preview.totalPay.toString());

const balance = BigInt(
(await token.balanceOf(owner).call()).toString()
);

if (balance < total) {
throw new Error('Insufficient USDT');
}

const allowance = BigInt(
(await token.allowance(owner, TRON_PROCESSOR_USDT).call()).toString()
);

if (allowance < total) {
const approvalTxid = await token.approve(
TRON_PROCESSOR_USDT,
total.toString()
).send({ feeLimit: TRON_FEE_LIMIT });

return {
state: 'approval_pending',
approvalTxid
};
}

const paymentTxid = await processor.transfer(
seller,
amountBaseUnits,
buyerPaysCommission,
TRON_ZERO
).send({ feeLimit: TRON_FEE_LIMIT });

return {
state: 'payment_pending',
paymentTxid
};
}

Anforderungen an die USDT-Freigabe​

Je nach bestehender Allowance kann eine USDT-Zahlung Folgendes erfordern:

Bestehende AllowanceErforderliche Transaktionen
AusreichendNur die Zahlung
UnzureichendFreigabe + Zahlung

Ist eine Freigabe erforderlich, gibt die Funktion approval_pending mit dem Hash der Freigabetransaktion zurück.

Warten Sie die Bestätigung der Freigabe ab, bevor Sie die Zahlungsfunktion erneut aufrufen. Sobald die Allowance ausreicht, sendet die Funktion die Zahlung und gibt payment_pending mit dem Hash der Zahlungstransaktion zurück.

Wichtig:

  • Eine approve()-Transaktion ist keine Zahlung.
  • Der Kunde braucht genug TRX für Energy- und Bandwidth-Kosten, auch wenn er in USDT zahlt.
  • USDT-Beträge müssen als ganze Zahlen in Token-Basiseinheiten angegeben werden. Vermeiden Sie Gleitkommaberechnungen wie Math.round(parseFloat(amount) * 1e6).
  • Verfolgen Sie Freigabetransaktionen getrennt von der abschließenden Zahlungstransaktion.

Schritt 5. Zahlungstransaktion speichern​

Ihr Backend muss eine Bestellung erstellen, bevor der Kunde eine Zahlung sendet.

Jede Bestellung sollte die erwarteten Werte enthalten für:

  • Bestell-ID
  • Blockchain-Netzwerk
  • Asset und Betrag
  • Empfangs-Wallet des Händlers (seller)
  • Freigegebenen Prozessor-Contract
  • Wallet des Käufers, falls Ihr Checkout es verlangt
  • Einstellung der Bearbeitungsgebühr (buyerPaysCommission)

Nachdem der Kunde die Zahlung gesendet hat:

  1. Den vom Wallet zurückgegebenen Hash der Zahlungstransaktion (txid) übernehmen.
  2. Den Hash an Ihr Backend senden.
  3. Ihn zusammen mit Bestell-ID und Blockchain-Netzwerk speichern.
  4. Die serverseitige Zahlungsprüfung starten.

Jede Zahlungstransaktion darf höchstens einer Bestellung zugeordnet sein. Setzen Sie das mit einer eindeutigen Einschränkung (network, txid) in Ihrer Datenbank durch.

Die Funktion transfer() des Smart Contracts akzeptiert keine Bestell-ID. Die Verknüpfung zwischen Bestellung und Zahlungstransaktion muss Ihre Anwendung herstellen.

Wiederholt ein Kunde eine Zahlung, legen Sie getrennte Zahlungsversuche an, statt Transaktionsdatensätze zu überschreiben, die möglicherweise noch ausstehen.

Schritt 6. Zahlung prüfen​

Vor dem Abschluss einer Bestellung ist eine Zahlungsprüfung erforderlich.

Ein zurückgegebener Transaktions-Hash zeigt nur, dass eine Transaktion gesendet wurde. Er belegt nicht, dass der Händler die richtige Zahlung erhalten hat.

Ihr Backend muss unabhängig:

  1. Transaktion und Ausführungs-Receipt von der Blockchain abrufen.
  2. Die erfolgreiche Ausführung anhand eines solidified TRON-Receipts bestätigen.
  3. Prüfen, ob die Transaktion den erwarteten Zahlungsprozessor verwendet hat.
  4. Asset, Händler-Wallet, Betrag und Contract-Aufruf mit der Bestellung abgleichen.
  5. Bestätigen, dass der Händler die erwarteten Gelder erhalten hat.
  6. Sicherstellen, dass die Transaktion nicht bereits für eine andere Bestellung verwendet wurde.
  7. Die Bestellung als bezahlt markieren und nur einmal ausführen.

Für solidified Transaktionsdaten verwenden Sie den SolidityNode-Endpunkt von TRON:

POST https://api.trongrid.io/walletsolidity/gettransactioninfobyid

Prüfen Sie, ob receipt.result === 'SUCCESS' gilt, und gleichen Sie dann Transaktionsinhalt und tatsächliche Zahlungsdetails mit der Bestellung ab.

Ein erfolgreiches Receipt allein reicht nicht aus. Eine Transaktion kann erfolgreich ausgeführt worden sein, ohne den richtigen Händler oder den richtigen Betrag zu bezahlen.

Ist der Blockchain-Dienst vorübergehend nicht erreichbar oder die Transaktion noch nicht solidified, lassen Sie die Bestellung ausstehend und wiederholen die Prüfung.

Folgen Sie Zahlungsprüfung und Bestellverfolgung für die vollständige Backend-Implementierung, die Bestätigungsanforderungen auf TRON und die Checkliste für den Produktivbetrieb.

Siehe auch TRON confirmation semantics.

Optional: mobile Wallets unterstützen​

Um mobile Wallets über WalletConnect zu unterstützen, verwenden Sie eine kompatible TRON-Wallet-Integration wie @tronweb3/walletconnect-tron zusammen mit TronWeb.

Dafür benötigen Sie eine WalletConnect Project ID und eine Integration, die TRON-Transaktionen erstellen, Signaturen bei mobilen Wallets anfordern und signierte Transaktionen ins Netzwerk senden kann.

Das unten beschriebene Browser-Beispiel unterstützt TronLink. Den Ablauf für mobile Wallets über WalletConnect setzt es nicht um.

Integrationsbeispiel​

Das Beispiel example-tron.html zeigt:

  • Verbindung von TronLink.
  • Berechnung der Zahlungsbeträge mit previewPayment().
  • Senden von Zahlungen in TRX und USDT TRC-20.
  • Anzeige von Transaktions-Hashes und Verfolgung des Transaktionsstatus.

Sie können das Beispiel im Browser öffnen oder die HTML-Datei herunterladen, um den Code zu studieren und anzupassen:

Browser-Wallet-Erweiterungen wie TronLink funktionieren mit direkt von der Festplatte geöffneten Seiten (file://) möglicherweise nicht korrekt. Stellen Sie die heruntergeladene Datei stattdessen über einen lokalen Webserver bereit. Führen Sie zum Beispiel npx serve im Ordner mit der Datei aus und öffnen Sie die angezeigte localhost-URL.

Beispiel ausprobieren​

  1. Öffnen Sie das Live-Beispiel oder stellen Sie die heruntergeladene Datei lokal bereit – in einem Browser mit installiertem TronLink.
  2. Wählen Sie in TronLink Mainnet und klicken Sie dann auf Connect TronLink. Die Demo warnt Sie, wenn das Wallet mit einem anderen Netzwerk verbunden ist.
  3. Wählen Sie die Zahlungsmethode: TRX oder USDT TRC-20.
  4. Geben Sie das TRON-Empfangs-Wallet unter Seller address ein.
  5. Geben Sie den Zahlungsbetrag ein und legen Sie fest, wer die Bearbeitungsgebühr zahlt.
  6. Klicken Sie auf Preview, um Bearbeitungsgebühr und Gesamtbetrag der Zahlung zu sehen. Klicken Sie dann auf Pay und bestätigen Sie die Transaktion in TronLink. Für USDT-Zahlungen kann vorher eine separate Token-Freigabe nötig sein.
  7. Bestellung und Transaktions-Hash erscheinen in der Tabelle Orders. Die Demo prüft den Transaktionsstatus bis zu 5 Minuten lang.

Bevor Sie zahlen:

  • Verwenden Sie zwei verschiedene Wallets. Die Verkäuferadresse muss sich vom zahlenden Wallet unterscheiden. Andernfalls lehnt der Contract die Zahlung mit SellerIsBuyer ab.
  • Transaktionen bewegen echtes Geld. Das Beispiel ist mit 1 TRX vorausgefüllt. Prüfen Sie Zahlungsbetrag, Bearbeitungsgebühr und die Kosten für TRON-Netzwerkressourcen (Energy und Bandwidth), bevor Sie bestätigen.

Grenzen der Demo: Dieses Beispiel speichert den Transaktionsverlauf im localStorage des Browsers und ist kein produktiver Checkout. Es prüft das neueste Transaktions-Receipt mit getTransactionInfo(), was keine Solidifizierung auf TRON belegt. Das Zeitfenster von 5 Minuten ist nur eine Grenze der Demo, keine Frist für die Zahlungsbestätigung. Setzen Sie den vollständigen Prozess der Zahlungsprüfung um, bevor Sie Kundenbestellungen annehmen.