This guide will walk you through building a payment gateway in Laravel that supports Tron (TRX) and JST (TRC20) cryptocurrency payments. You’ll learn how to generate wallet addresses for each payment session, handle transaction notifications via webhooks, and verify transaction statuses before processing orders.
By the end of this tutorial, you’ll have a functional payment system that interacts with blockchain networks through a secure API. The same approach can be adapted for other major cryptocurrencies like Bitcoin, Ethereum, Binance Smart Chain, and Polygon with minor adjustments.
Introduction
Integrating cryptocurrency payments into your Laravel application can streamline transactions and open up global payment opportunities. Using a dedicated blockchain API simplifies complex processes like address generation, transaction monitoring, and fund management.
Core Tools and Concepts
You’ll be using a blockchain API service to handle interactions with the Tron network. This allows you to:
- Generate unique wallet addresses for each transaction.
- Monitor incoming payments in real-time.
- Execute automated actions based on payment status.
👉 Explore real-time payment integration tools
Prerequisites
Before you begin, make sure you have the following:
- A working Laravel installation (version 10 or higher).
- A configured database connection.
- Basic knowledge of Laravel MVC structure, routes, and controllers.
- An account with a blockchain API provider to obtain your API key.
Key Features of the Payment Gateway
The system you’ll build includes:
- A dynamic payment form where users enter the amount and select a currency (TRX or USDT).
- Automatic generation of a unique wallet address for each session.
- A session details page displaying the wallet address, payment status, and amount information.
- A webhook endpoint to receive transaction notifications, verify payments, and update session statuses.
- Optional automatic forwarding of funds to a secure cold wallet.
Step 1: API Configuration
Start by configuring your Laravel application to connect to the blockchain API.
Update Config Files
Add the API settings to your config/app.php file under the return array:
'BlockchainAPI' => [
'api_url' => env('BLOCKCHAIN_API_URL', 'https://api.blockchainapi.io/api/v2'),
'api_key' => env('BLOCKCHAIN_API_KEY'),
'network' => env('BLOCKCHAIN_NETWORK', 'testnet'),
'cold_wallet' => env('COLD_WALLET_ADDRESS'),
],Next, update your .env file with your actual credentials:
BLOCKCHAIN_API_URL=https://api.blockchainapi.io/api/v2
BLOCKCHAIN_API_KEY=your_actual_api_key_here
BLOCKCHAIN_NETWORK=testnet
COLD_WALLET_ADDRESS=your_cold_wallet_address_hereConfiguration Explanation
- api_url: The base endpoint for API requests.
- api_key: Your unique authentication key.
- network: Set to
testnetfor development andmainnetfor production. - cold_wallet: Your secure wallet address for fund storage.
Step 2: Define Application Routes
Define the routes that handle payment sessions and webhooks in routes/web.php:
use App\Http\Controllers\PaymentController;
Route::get('/payment', [PaymentController::class, 'showPaymentPage']);
Route::post('/start-payment-session', [PaymentController::class, 'startPaymentSession']);
Route::get('/payment-session/{id}', [PaymentController::class, 'showPaymentSession'])->name('showPaymentSession');
Route::post('/webhook', [PaymentController::class, 'handleWebhook']);Route Functions
/payment: Displays the payment initiation form./start-payment-session: Processes new payment requests./payment-session/{id}: Shows payment status and details./webhook: Receives blockchain transaction notifications.
Disable CSRF Protection for Webhooks
To allow external services to post to your webhook, disable CSRF protection for that route. In bootstrap/app.php:
return Application::configure(basePath: dirname(__DIR__))
->withRouting(...)
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: ['webhook']);
})
->create();Step 3: Create Models and Migrations
You’ll need two database tables to store wallet information and payment sessions.
Generate Models and Migrations
Run these Artisan commands:
php artisan make:model Wallet -m
php artisan make:model PaymentSession -mDefine Database Schema
In the wallets migration file:
Schema::create('wallets', function (Blueprint $table) {
$table->id();
$table->string('address')->unique();
$table->string('private_key');
$table->timestamps();
});In the payment_sessions migration file:
Schema::create('payment_sessions', function (Blueprint $table) {
$table->id();
$table->string('status')->default('Pending');
$table->foreignId('wallet_id')->constrained()->onDelete('cascade');
$table->decimal('amount', 18, 8)->nullable();
$table->string('currency')->default('TRX');
$table->decimal('received_amount', 18, 8)->nullable();
$table->string('webhook_id')->nullable();
$table->timestamps();
});Run the migrations:
php artisan migrateSet Up Model Relationships
In app/Models/Wallet.php:
protected $fillable = ['address', 'private_key'];
public function paymentSessions()
{
return $this->hasMany(PaymentSession::class);
}In app/Models/PaymentSession.php:
protected $fillable = ['wallet_id', 'status', 'amount', 'currency', 'received_amount', 'webhook_id'];
public function wallet()
{
return $this->belongsTo(Wallet::class);
}Step 4: Build the Payment Controller
The controller handles the core logic: creating sessions, generating wallets, and processing webhooks.
Generate the controller:
php artisan make:controller PaymentControllerController Method Overview
- showPaymentPage(): Renders the payment form view.
- startPaymentSession(): Creates a new wallet and payment session.
- showPaymentSession(): Displays session details to the user.
- handleWebhook(): Processes incoming transaction notifications.
Key Functionality Details
The startPaymentSession method uses the API to generate a new wallet address and sets up a webhook for transaction alerts. The handleWebhook method verifies transactions by checking the blockchain receipt and updates the payment status accordingly. It includes logic to handle overpayments, underpayments, and currency mismatches.
Step 5: Create the Views
Payment Form Page
Create resources/views/payment.blade.php:
<!DOCTYPE html>
<html>
<head>
<title>Start Payment</title>
</head>
<body>
<h1>Start a New Payment Session</h1>
<form action="/start-payment-session" method="POST">
@csrf
<label>Amount: <input type="number" name="amount" step="0.000001" required></label>
<label>Currency:
<select name="currency">
<option value="TRX">TRX</option>
<option value="JST">JST (TRC20)</option>
</select>
</label>
<button type="submit">Start Payment Session</button>
</form>
</body>
</html>Payment Session Status Page
Create resources/views/payment-session.blade.php:
<!DOCTYPE html>
<html>
<head>
<title>Payment Session</title>
</head>
<body>
<h1>Payment Session</h1>
<p>Send {{ $paymentSession->amount }} {{ $paymentSession->currency }} to:</p>
<p><strong>{{ $paymentSession->wallet->address }}</strong></p>
<p>Status: {{ $paymentSession->status }}</p>
<p>Received: {{ $paymentSession->received_amount }} {{ $paymentSession->currency }}</p>
</body>
</html>Step 6: Testing Your Implementation
Start the Development Server
php artisan serveTest the Payment Flow
- Visit
/paymentand submit a payment request. - Copy the generated wallet address.
- If using testnet, send a test transaction to that address.
- The webhook should automatically update the payment session status upon confirmation.
Frequently Asked Questions
What is a webhook in cryptocurrency payments?
A webhook is an HTTP callback that sends real-time notifications from the blockchain to your application when a transaction occurs. This allows your system to automatically update payment statuses without manual checks.
Can I use this for other cryptocurrencies besides Tron?
Yes. The general structure works for any blockchain that provides a similar API. You would need to adjust the API endpoints and parameters for networks like Ethereum or Bitcoin.
How do I handle transaction fees?
Transaction fees are usually deducted from the sent amount. Your application should account for this by allowing a small variance between the expected and received amounts, as shown in the tutorial.
Is it safe to store private keys in the database?
For production use, consider encrypting private keys before storage. Alternatively, use a service that manages private keys for you to enhance security.
What happens if a payment is underpaid or overpaid?
The example code includes a tolerance check (10%). Payments outside this range are marked as 'underpaid' or 'overpaid'. You can then decide to refund, request additional payment, or handle case-by-case.
How can I make the status page update automatically?
For a production application, implement frontend polling or WebSocket connections to periodically check the payment status without requiring page refreshes.
Integrating cryptocurrency payments into your Laravel application is a powerful way to accept global payments efficiently. By leveraging a blockchain API, you automate the most complex parts of the process and provide a seamless experience for your users.