Ana içeriğe geç

TRON akıllı sözleşme entegrasyonu

Bu kılavuz, Volet.com ödeme akıllı sözleşmeleri ve TronWeb ile TRON'da emanetçi olmayan kripto ödemelerin nasıl kabul edileceğini açıklar.

Müşteriler cüzdanlarını bağlar, işlemleri onaylar ve bir akıllı sözleşme aracılığıyla doğrudan alıcı cüzdanınıza öder. Fonlar bir Volet.com hesabına yatırılmaz.

Devam etmeden önce ödeme akışına genel bakış için Akıllı sözleşme entegrasyonu sayfasını inceleyin.

Bir bakışta entegrasyon​

  1. Müşterinin cüzdanını bağlayın ve TRON Mainnet kullandığını doğrulayın.
  2. Ödeme sözleşmelerini ve alıcı cüzdanınızı yapılandırın.
  3. Ödemeyi başlatmadan önce arka uçta bir sipariş oluşturun.
  4. Toplam ödeme tutarını hesaplamak için previewPayment() fonksiyonunu çağırın.
  5. Ödemeyi başlatmak için transfer() fonksiyonunu çağırın. USDT için token harcama iznini (allowance) kontrol edin ve gerekirse onay isteyin.
  6. Ödeme işleminin hash'ini (txid) siparişe kaydedin.
  7. Siparişi ödendi olarak işaretlemeden önce işlemi arka uçta solidified blokzincir verileriyle doğrulayın.

Başlamadan önce​

İhtiyacınız olanlar:

  • Müşteri cüzdanı: Tarayıcıda ödeme için TronLink.
  • Kütüphane: TRON cüzdanları ve akıllı sözleşmeleriyle etkileşim için TronWeb.
  • Üye işyeri cüzdanı: Ödemeleri almak için kontrolünüzde olan bir TRON cüzdan adresi.
  • Arka uç ve veritabanı: Sipariş oluşturmak, işlem ayrıntılarını saklamak ve ödemeleri doğrulamak için.
  • Blokzincir erişimi: İşlemleri almak ve doğrulamak için bir TRON düğümü veya TronGrid gibi barındırılan bir hizmet.

Mobil cüzdan bağlantıları için ayrıca bir WalletConnect Project ID ve uyumlu bir TRON cüzdan entegrasyonu gerekir.

Desteklenen ağlar ve varlıklar​

AğDesteklenen varlıklar
TRON MainnetTRX, USDT (TRC-20)

TRX ve USDT ayrı ödeme işlemcisi sözleşmeleri kullanır.

TRX tutarları, TRX'in en küçük birimi olan SUN ile ifade edilir. Bir TRX 1.000.000 SUN'a eşittir.

USDT TRC-20 6 ondalık basamak kullanır. Bir USDT 1.000.000 token temel birimine eşittir.

Aşağıdaki kod örnekleri, entegrasyon yapılandırmasındaki işlemci ve token adreslerini içerir.

Sözleşme adresleri, token ondalık basamakları ve fonksiyon parametreleri için Akıllı sözleşme referansı sayfasına bakın.

Örnekleri üretimde kullanmadan önce dağıtılmış işlemci adreslerini ve sözleşme arayüzünü Volet.com ile teyit edin.

Adım 1. Müşterinin cüzdanını bağlayın​

Müşterinin tarayıcı cüzdanını TronLink ile bağlayın.

<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>

Müşteri TRON Mainnet'e bağlanmalıdır.

Ödeme göndermeden önce etkin ağı doğrulayın. Cüzdanlar özel düğümler kullanabildiği için ağı yalnızca RPC uç noktasının URL'sine göre belirlemeyin.

Uygulamanız ayrıca cüzdandaki hesap ve ağ değişikliklerini algılamalı ve bir işlem başlatmadan önce bağlantıyı yeniden doğrulamalıdır.

Adım 2. Ödeme sözleşmelerini yapılandırın​

Ödeme işlemcisinin ABI'sini ve token fonksiyonlarını uygulamanıza ekleyin.

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;

Ödeme işlemcisi iki ana fonksiyon sunar:

  • previewPayment(amount, buyerPaysCommission) işlem komisyonunu ve müşterinin ödemesi gereken toplam tutarı hesaplar.
  • transfer(seller, amount, buyerPaysCommission, optionalCommissionWallet) ödemeyi gerçekleştirir ve fonları sözleşmenin komisyon ayarlarına göre dağıtır.

amount parametresi varlığın en küçük birimlerini kullanır: TRX için SUN, USDT için token temel birimleri.

buyerPaysCommission parametresi işlem komisyonunu kimin karşılayacağını belirler:

  • true: Komisyon müşterinin ödemesine eklenir.
  • false: Komisyon üye işyerinin alacağı tutardan düşülür.

İş ortağı komisyon cüzdanı yoksa optionalCommissionWallet için TRON_ZERO kullanın.

Toplam ödeme tutarını her zaman previewPayment() fonksiyonundan alın. İşlem komisyonunu elle hesaplamayın.

Örnekteki TRON_FEE_LIMIT SUN cinsindendir ve beklenen işlem ücretini değil, 500 TRX tutarındaki azami ücret limitini ifade eder. Üretimde kullanmadan önce gereken Energy miktarını tahmin edin ve uygun ücret limitini belirleyin.

Parametrelerin eksiksiz tanımları için Akıllı sözleşme referansı sayfasına bakın.

Adım 3. TRX kabul edin​

Yerel TRX ödemeleri tek bir cüzdan işlemi gerektirir.

İşlemle gönderilecek SUN miktarını tam olarak hesaplamak için previewPayment() kullanın.

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
});
}

İşlemin callValue değeri, previewPayment() tarafından döndürülen totalPay değerine eşit olmalıdır.

Müşterinin blokzincir kaynaklarını ve işlem ücretlerini karşılayacak kadar TRX'i de olmalıdır.

Fonksiyon, ödeme işleminin hash'ini (txid) döndürür. Bu değeri mevcut siparişe kaydedin ve siparişi teslim etmeden önce ödemeyi doğrulayın.

Adım 4. USDT kabul edin​

USDT TRC-20 ödemeleri bir token sözleşmesi kullanır ve ek bir onay işlemi gerektirebilir.

Ödeme yapmadan önce uygulamanız şunları yapmalıdır:

  1. Müşterinin USDT bakiyesini balanceOf() ile kontrol etmek.
  2. İşlemcinin harcama iznini allowance() ile kontrol etmek.
  3. İzin yetersizse approve() ile onay istemek.
  4. Onayın doğrulanmasını beklemek.
  5. Ödemeyi gerçekleştirmek için transfer() fonksiyonunu çağırmak.
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
};
}

USDT onay gereksinimleri​

Mevcut izne bağlı olarak bir USDT ödemesi şunları gerektirebilir:

Mevcut izinGereken işlemler
YeterliYalnızca ödeme
YetersizOnay + ödeme

Onay gerekiyorsa fonksiyon, onay işleminin hash'iyle birlikte approval_pending döndürür.

Ödeme fonksiyonunu yeniden çağırmadan önce onayın doğrulanmasını bekleyin. İzin yeterli olduğunda fonksiyon ödemeyi gönderir ve ödeme işleminin hash'iyle birlikte payment_pending döndürür.

Önemli:

  • approve() işlemi bir ödeme değildir.
  • Müşteri USDT ile ödese bile Energy ve Bandwidth maliyetlerini karşılayacak kadar TRX'e ihtiyaç duyar.
  • USDT tutarları token temel birimlerinde tam sayı olarak ifade edilmelidir. Math.round(parseFloat(amount) * 1e6) gibi kayan noktalı hesaplamalardan kaçının.
  • Onay işlemlerini son ödeme işleminden ayrı olarak takip edin.

Adım 5. Ödeme işlemini kaydedin​

Arka ucunuz, müşteri ödeme göndermeden önce bir sipariş oluşturmalıdır.

Her sipariş şu beklenen değerleri içermelidir:

  • Sipariş kimliği
  • Blokzincir ağı
  • Varlık ve tutar
  • Üye işyerinin alıcı cüzdanı (seller)
  • Onaylı ödeme işlemcisi sözleşmesi
  • Ödeme sayfanız gerektiriyorsa alıcının cüzdanı
  • İşlem komisyonu ayarı (buyerPaysCommission)

Müşteri ödemeyi gönderdikten sonra:

  1. Cüzdanın döndürdüğü ödeme işlemi hash'ini (txid) alın.
  2. Hash'i arka ucunuza gönderin.
  3. Sipariş kimliği ve blokzincir ağıyla birlikte saklayın.
  4. Sunucu tarafında ödeme doğrulamasını başlatın.

Her ödeme işlemi en fazla bir siparişle ilişkilendirilmelidir. Bunu veritabanınızda benzersiz bir (network, txid) kısıtlamasıyla zorunlu kılın.

Akıllı sözleşmenin transfer() fonksiyonu sipariş kimliği kabul etmez. Sipariş ile ödeme işlemi arasındaki ilişki uygulamanızda tutulmalıdır.

Müşteri ödemeyi yeniden denerse hâlâ beklemede olabilecek işlem kayıtlarının üzerine yazmak yerine ödeme denemelerini ayrı tutun.

Adım 6. Ödemeyi doğrulayın​

Siparişi tamamlamadan önce ödeme doğrulaması zorunludur.

Döndürülen bir işlem hash'i yalnızca işlemin gönderildiğini gösterir. Üye işyerinin doğru ödemeyi aldığını kanıtlamaz.

Arka ucunuz bağımsız olarak şunları yapmalıdır:

  1. İşlemi ve yürütme makbuzunu blokzincirden almak.
  2. Başarılı yürütmeyi solidified bir TRON makbuzuyla doğrulamak.
  3. İşlemin beklenen ödeme işlemcisini kullandığını doğrulamak.
  4. Varlığı, üye işyeri cüzdanını, tutarı ve sözleşme çağrısını siparişle karşılaştırmak.
  5. Üye işyerinin beklenen fonları aldığını doğrulamak.
  6. İşlemin daha önce başka bir sipariş için kullanılmadığından emin olmak.
  7. Siparişi ödendi olarak işaretlemek ve yalnızca bir kez teslim etmek.

Solidified işlem verileri için TRON SolidityNode uç noktasını kullanın:

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

receipt.result === 'SUCCESS' olduğunu kontrol edin, ardından işlem gövdesini ve gerçek ödeme ayrıntılarını siparişle karşılaştırın.

Başarılı bir makbuz tek başına yeterli değildir. Bir işlem, doğru üye işyerine veya doğru tutarı ödemeden de başarıyla yürütülebilir.

Blokzincir hizmeti geçici olarak kullanılamıyorsa veya işlem henüz solidified değilse siparişi beklemede tutun ve doğrulamayı yeniden deneyin.

Arka uç uygulamasının tamamı, TRON onay gereksinimleri ve üretim kontrol listesi için Ödeme doğrulama ve sipariş takibi sayfasını izleyin.

TRON confirmation semantics sayfasını da inceleyebilirsiniz.

İsteğe bağlı: Mobil cüzdanları destekleyin​

Mobil cüzdanları WalletConnect ile desteklemek için TronWeb ile birlikte @tronweb3/walletconnect-tron gibi uyumlu bir TRON cüzdan entegrasyonu kullanın.

Bunun için bir WalletConnect Project ID ve TRON işlemleri oluşturabilen, mobil cüzdanlardan imza isteyebilen ve imzalı işlemleri yayınlayabilen bir entegrasyon gerekir.

Aşağıda açıklanan tarayıcı örneği TronLink'i destekler. Mobil WalletConnect akışını içermez.

Entegrasyon örneği​

example-tron.html örneği şunları gösterir:

  • TronLink'i bağlama.
  • previewPayment() ile ödeme tutarlarını hesaplama.
  • TRX ve USDT TRC-20 ödemeleri gönderme.
  • İşlem hash'lerini gösterme ve işlem durumunu takip etme.

Kodu incelemek ve uyarlamak için örneği tarayıcınızda açabilir veya HTML dosyasını indirebilirsiniz:

TronLink gibi tarayıcı cüzdan uzantıları, doğrudan diskten açılan sayfalarla (file://) düzgün çalışmayabilir. İndirdiğiniz dosyayı bunun yerine yerel bir web sunucusu üzerinden açın. Örneğin dosyanın bulunduğu klasörde npx serve komutunu çalıştırın ve gösterilen localhost adresini açın.

Örneği deneyin​

  1. Canlı örneği açın veya indirdiğiniz dosyayı TronLink yüklü bir tarayıcıda yerel sunucu üzerinden açın.
  2. TronLink'te Mainnet seçin, ardından Connect TronLink düğmesine tıklayın. Cüzdan başka bir ağa bağlıysa demo sizi uyarır.
  3. Ödeme yöntemini seçin: TRX veya USDT TRC-20.
  4. Alıcı TRON cüzdanını Seller address alanına girin.
  5. Ödeme tutarını girin ve işlem komisyonunu kimin ödeyeceğini seçin.
  6. İşlem komisyonunu ve toplam ödeme tutarını görmek için Preview düğmesine tıklayın. Ardından Pay düğmesine tıklayın ve işlemi TronLink'te onaylayın. USDT ödemeleri önce ayrı bir token onayı gerektirebilir.
  7. Sipariş ve işlem hash'i Orders tablosunda görünür. Demo işlem durumunu en fazla 5 dakika boyunca kontrol eder.

Ödemeden önce:

  • İki farklı cüzdan kullanın. Satıcı adresi, ödeme yapan cüzdandan farklı olmalıdır. Aksi takdirde sözleşme ödemeyi SellerIsBuyer hatasıyla reddeder.
  • İşlemler gerçek fon kullanır. Örnekte 1 TRX önceden doldurulmuştur. Onaylamadan önce ödeme tutarını, işlem komisyonunu ve TRON ağ kaynağı maliyetlerini (Energy ve Bandwidth) kontrol edin.

Demo sınırlamaları: Bu örnek işlem geçmişini tarayıcının localStorage alanında saklar ve üretime hazır bir ödeme sayfası değildir. En son işlem makbuzunu getTransactionInfo() ile kontrol eder; bu, TRON'da işlemin solidified olduğunu garanti etmez. 5 dakikalık takip süresi yalnızca bir demo sınırıdır, ödeme onayı için son tarih değildir. Müşteri siparişlerini kabul etmeden önce ödeme doğrulama sürecinin tamamını uygulayın.