Documentation Index Fetch the complete documentation index at: https://mintlify.com/peLuis123/crypto-shop-backend/llms.txt
Use this file to discover all available pages before exploring further.
This guide explains how to process cryptocurrency payments using TRON (TRX) and handle transaction confirmations.
Payment Flow Overview
Initiate Payment
Send TRX from user’s wallet to merchant address using the Pay Order endpoint.
Transaction Broadcast
Transaction is broadcast to TRON network and a transaction hash is returned.
Pending Confirmation
Order status remains “pending” while waiting for blockchain confirmations.
Blockchain Confirmation
Transaction listener monitors the blockchain and confirms after 21 confirmations.
Order Completed
Order status updates to “completed” and product stock is reduced. User receives real-time notification.
Pay for an Order
Send TRX payment for a pending order.
Endpoint
Requires authentication. The order must belong to the authenticated user and have “pending” status.
URL Parameters
id : The MongoDB ObjectId of the order
Request
No request body required. The payment details are retrieved from the order.
Response
200 Success
400 Insufficient Balance
400 Invalid Status
404 Order Not Found
403 Unauthorized
{
"success" : true ,
"message" : "Payment sent. Waiting for blockchain confirmation." ,
"order" : {
"_id" : "507f1f77bcf86cd799439013" ,
"orderId" : "#TRX-1001" ,
"userId" : "507f1f77bcf86cd799439010" ,
"products" : [
{
"productId" : "507f1f77bcf86cd799439011" ,
"name" : "Wireless Headphones" ,
"price" : 29.99 ,
"quantity" : 2 ,
"color" : "Black"
}
],
"subtotal" : 59.98 ,
"networkFee" : -0.01 ,
"total" : 59.97 ,
"status" : "pending" ,
"transactionHash" : "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0" ,
"walletAddress" : "TYwXGhKhqPTbLvRPFdvZnXqcqN4kVy7ABC" ,
"merchantAddress" : "TXYZMerchantAddressHere123456789" ,
"createdAt" : "2024-01-20T14:30:00.000Z" ,
"updatedAt" : "2024-01-20T14:32:00.000Z"
},
"transaction" : {
"hash" : "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0" ,
"from" : "TYwXGhKhqPTbLvRPFdvZnXqcqN4kVy7ABC" ,
"to" : "TXYZMerchantAddressHere123456789" ,
"amount" : 59.97 ,
"status" : "pending"
}
}
Implementation Example
const orderId = '507f1f77bcf86cd799439013' ;
const response = await fetch (
`http://localhost:3000/api/orders/ ${ orderId } /pay` ,
{
method: 'POST' ,
credentials: 'include'
}
);
const data = await response . json ();
if ( data . success ) {
console . log ( 'Payment sent!' );
console . log ( 'Transaction hash:' , data . transaction . hash );
console . log ( 'Status:' , data . transaction . status );
// Now wait for real-time confirmation via Socket.io
} else {
console . error ( 'Payment failed:' , data . error );
}
Payment Processing Logic
From src/api/orders/payOrder.js:41, the payment process:
// Check user balance
const balance = await getBalance ( user . wallet . address );
if ( balance < Math . abs ( order . total )) {
return res . status ( 400 ). json ({
error: 'Insufficient balance' ,
code: 'INSUFFICIENT_BALANCE' ,
userBalance: balance ,
requiredAmount: Math . abs ( order . total )
});
}
// Send TRX transaction
const tx = await sendTRX (
user . wallet . privateKey ,
order . merchantAddress ,
Math . abs ( order . total )
);
const txHash = tx . txid || tx . txID || tx . transaction ?. txID ;
// Create transaction record
const transaction = new Transaction ({
userId ,
orderId: order . _id ,
type: 'purchase' ,
amount: Math . abs ( order . total ),
currency: 'TRX' ,
network: 'TRC-20' ,
transactionHash: txHash ,
fromAddress: order . walletAddress ,
toAddress: order . merchantAddress ,
status: 'pending' ,
confirmations: 0
});
await transaction . save ();
order . transactionHash = txHash ;
await order . save ();
Transaction Confirmation Process
The system automatically monitors pending transactions using a background service.
Configuration
From src/services/transactionListener.js:16:
const CONFIRMATIONS_REQUIRED = 21 ;
const CHECK_INTERVAL = 15000 ; // 15 seconds
Transaction Listener
The transaction listener runs continuously and checks pending transactions every 15 seconds:
Transaction Listener Flow
export const syncPendingTransactions = async () => {
// Find all pending transactions
const pendingTransactions = await Transaction . find ({
status: 'pending' ,
transactionHash: { $ne: null }
});
console . log ( `[Listener] Found ${ pendingTransactions . length } pending transactions` );
for ( const transaction of pendingTransactions ) {
// Check transaction status on blockchain
const status = await getTransactionStatus ( transaction . transactionHash );
if ( status && status . confirmed ) {
console . log ( `[Listener] Transaction confirmed: ${ transaction . transactionHash } ` );
// Update transaction status
transaction . status = 'confirmed' ;
transaction . confirmations = CONFIRMATIONS_REQUIRED ;
transaction . updatedAt = Date . now ();
await transaction . save ();
// Update order status
if ( transaction . orderId ) {
const order = await Order . findById ( transaction . orderId );
if ( order && transaction . type === 'purchase' && order . status === 'pending' ) {
order . status = 'completed' ;
order . updatedAt = Date . now ();
await order . save ();
// Reduce product stock
for ( const item of order . products ) {
await Product . findByIdAndUpdate (
item . productId ,
{ $inc: { stock: - item . quantity } }
);
}
// Emit real-time notification
emitTransactionConfirmed (
transaction . userId . toString (),
transaction . orderId . toString (),
transaction . transactionHash
);
}
}
}
}
};
What Happens on Confirmation
When a transaction is confirmed (from src/services/transactionListener.js:49):
Transaction Status Updated
Transaction status changes from pending to confirmed with 21 confirmations.
Order Status Updated
Order status changes from pending to completed.
Product Stock Reduced
Stock is decreased for each product in the order using $inc operator.
Real-time Notification Sent
Checking Transaction Status
From src/services/transactionListener.js:19, you can check a transaction status:
export const getTransactionStatus = async ( txHash ) => {
try {
const tx = await tronWeb . trx . getTransactionInfo ( txHash );
if ( ! tx || ! tx . blockNumber ) {
return null ;
}
return {
confirmed: true ,
confirmations: 21
};
} catch ( error ) {
return null ;
}
};
Payment Error Handling
class PaymentService {
async payOrder ( orderId ) {
try {
const response = await fetch (
`http://localhost:3000/api/orders/ ${ orderId } /pay` ,
{
method: 'POST' ,
credentials: 'include'
}
);
if ( ! response . ok ) {
const error = await response . json ();
if ( error . code === 'INSUFFICIENT_BALANCE' ) {
throw new Error (
`Insufficient balance. You have ${ error . userBalance } TRX but need ${ error . requiredAmount } TRX`
);
}
throw new Error ( error . error || 'Payment failed' );
}
const data = await response . json ();
console . log ( 'Payment successful!' );
console . log ( 'Transaction hash:' , data . transaction . hash );
console . log ( 'Please wait for blockchain confirmation...' );
return data ;
} catch ( error ) {
console . error ( 'Payment error:' , error . message );
throw error ;
}
}
}
Transaction States
Transaction has been broadcast to the blockchain but not yet confirmed.
Order status: pending
Confirmations: 0
Stock: Not yet reduced
User action: Wait for confirmation
Transaction has received 21 confirmations on the blockchain.
Order status: completed
Confirmations: 21
Stock: Reduced
User action: Order complete
Transaction failed or was rejected by the blockchain.
Order status: failed
Confirmations: 0
Stock: Not reduced
User action: Retry or create new order
Payment Security
Important security considerations:
User wallet private keys are stored encrypted in the database
Transactions are signed server-side using the user’s private key
Balance is verified before processing payment
Order ownership is verified before payment
Only pending orders can be paid
Transaction hash is stored for verification and auditing
Monitoring Payments
The transaction listener automatically starts when the server boots:
// Transaction listener checks every 15 seconds
startTransactionListener ();
You can monitor the logs to see transaction confirmations:
[Listener] Found 3 pending transactions
[Listener] Transaction confirmed: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0
[Socket] User 507f1f77bcf86cd799439010 notified of confirmation
Next Steps
Real-time Notifications Set up Socket.io to receive instant payment confirmations
Admin Dashboard Monitor all transactions and sales from the admin panel