11 KiB
TurboTrades - Steam Trade Workflow Documentation
Overview
This document explains the complete workflow for selling items through Steam trade offers with real-time WebSocket updates and verification codes.
Architecture
User (Frontend) <--WebSocket--> Backend <--> Steam Bot Manager <--> Steam API
|
v
Database
(Trades, Users, Transactions)
Complete Trade Flow
1. User Initiates Sale (Frontend)
File: frontend/src/views/SellPage.vue
- User logs in and navigates to
/sell - Frontend fetches user's Steam inventory via
/api/inventory/steam - Items are displayed with market prices (pre-fetched from database)
- User selects items to sell
- User clicks "Sell Selected Items"
- Frontend makes POST request to
/api/inventory/sellwith:{ "tradeUrl": "user's Steam trade URL", "items": [ { "assetid": "123456789", "appid": 730, "contextid": "2", "name": "AK-47 | Redline (Field-Tested)", "price": 25.50, "image": "url", "wear": "ft", "rarity": "classified" } ] }
2. Backend Creates Trade Offer
File: routes/inventory.js - POST /api/inventory/sell
- Validates user authentication and trade URL
- Calculates total value of items
- Calls
botManager.createTradeOffer()with:- User's trade URL
- Items to receive (assetid, appid, contextid)
- User ID (for WebSocket notifications)
- Bot manager selects best available bot (least busy)
- Bot manager generates 6-character verification code
- Bot creates Steam trade offer with verification code in message
3. Trade Offer Created
File: services/steamBot.js - SteamBotInstance.createTradeOffer()
-
Bot sends trade offer to Steam
-
Bot confirms trade offer with 2FA (identity_secret)
-
Trade record saved to database with status:
pending -
WebSocket notifications sent to user:
WebSocket Events Sent:
trade_creating- Trade is being createdtrade_sent- Trade offer sent to Steamtrade_confirmed- Trade confirmed with 2FAtrade_created- Complete trade details
-
Response sent to frontend with:
{ "success": true, "trade": { "tradeId": "db_record_id", "offerId": "steam_offer_id", "verificationCode": "A3X9K2", "itemCount": 3, "totalValue": 75.50, "status": "pending", "botId": "bot1" } }
4. User Views Verification Code
File: frontend/src/views/SellPage.vue
- Toast notification shows verification code (doesn't auto-dismiss)
- User receives WebSocket message with trade details
- User opens Steam client/mobile app
- User sees trade offer from TurboTrades bot
5. User Verifies and Accepts Trade
Steam Side:
- User checks trade offer message for verification code
- User compares code in Steam with code shown on website
- If codes match, user accepts trade
- If codes don't match, user declines (security protection)
6. Bot Detects Trade Acceptance
File: services/steamBot.js - _handleOfferStateChange()
When Steam trade state changes to Accepted (state 3):
- Bot emits
tradeAcceptedevent - Event includes offer details and trade data
7. Backend Processes Completed Trade
File: index.js - Trade event listener
botManager.on('tradeAccepted', async (offer, tradeData) => {
// 1. Find trade record in database
// 2. Find user record
// 3. Credit user balance with trade value
// 4. Update trade status to 'completed'
// 5. Create transaction record (type: 'sale')
// 6. Send WebSocket notifications
});
WebSocket Events Sent:
trade_accepted- Trade was accepted on Steamtrade_completed- Balance credited successfullybalance_update- User's new balance
8. User Receives Funds
- User balance updated in database
- Transaction record created for audit trail
- WebSocket notifications update frontend in real-time
- Toast notification shows credited amount
- User can spend balance on marketplace
WebSocket Events Reference
Events Sent to User During Trade
| Event | Trigger | Data |
|---|---|---|
trade_creating |
Bot starting to create offer | verificationCode, itemCount, botId |
trade_sent |
Offer sent to Steam | offerId, verificationCode, status |
trade_confirmed |
Offer confirmed with 2FA | offerId, verificationCode |
trade_created |
Complete - offer ready | tradeId, offerId, verificationCode, totalValue |
trade_accepted |
User accepted on Steam | offerId, verificationCode, itemCount |
trade_completed |
Balance credited | tradeId, amount, newBalance |
balance_update |
Balance changed | balance, change, reason |
trade_declined |
User declined on Steam | offerId, tradeId |
trade_expired |
Offer expired (15 days) | offerId, tradeId |
trade_canceled |
User/bot canceled | offerId, tradeId |
trade_error |
Error occurred | error, verificationCode |
WebSocket Message Format
{
"type": "trade_completed",
"data": {
"tradeId": "507f1f77bcf86cd799439011",
"offerId": "5847362918",
"amount": 75.50,
"newBalance": 125.75,
"itemCount": 3,
"timestamp": 1704067200000
}
}
Database Models
Trade Model
File: models/Trade.js
{
offerId: String, // Steam trade offer ID
botId: String, // Bot that created the offer
user: ObjectId, // User reference
items: [{ // Items in trade
assetid: String,
name: String,
price: Number,
image: String
}],
totalValue: Number, // Total value of items
verificationCode: String, // 6-char code
status: String, // pending, completed, declined, expired, cancelled
type: String, // sell, buy
createdAt: Date,
completedAt: Date
}
Transaction Model
File: models/Transaction.js
{
user: ObjectId,
type: String, // sale, deposit, withdrawal, purchase
amount: Number,
description: String,
status: String, // completed, pending, failed
metadata: {
tradeId: ObjectId,
offerId: String,
botId: String,
verificationCode: String
}
}
Security Features
Verification Codes
- Purpose: Prevent phishing and fake trade offers
- Format: 6 alphanumeric characters (no ambiguous chars: O, 0, I, l, 1)
- Display: Shown on website and in Steam trade message
- Validation: User must verify codes match before accepting
Trade URL Privacy
- Trade URLs stored encrypted in database
- Only sent to bot manager, never exposed to frontend
- Required for creating trade offers
Bot Security
- Each bot uses separate Steam account
- Proxies supported for IP distribution
- 2FA required (shared_secret, identity_secret)
- Rate limiting on trade creation
- Health monitoring and auto-failover
API Endpoints
POST /api/inventory/sell
Create a new trade offer to sell items.
Request:
{
"tradeUrl": "https://steamcommunity.com/tradeoffer/new/?partner=XXX&token=YYY",
"items": [
{
"assetid": "123456789",
"appid": 730,
"contextid": "2",
"name": "Item Name",
"price": 10.50
}
]
}
Response:
{
"success": true,
"trade": {
"tradeId": "db_id",
"offerId": "steam_id",
"verificationCode": "A3X9K2",
"itemCount": 1,
"totalValue": 10.50,
"status": "pending"
}
}
GET /api/inventory/trades
Get user's trade history.
Response:
{
"success": true,
"trades": [
{
"_id": "507f1f77bcf86cd799439011",
"offerId": "5847362918",
"status": "completed",
"totalValue": 75.50,
"createdAt": "2024-01-01T00:00:00Z"
}
]
}
GET /api/inventory/trade/:tradeId
Get specific trade details.
POST /api/inventory/trade/:tradeId/cancel
Cancel a pending trade offer.
Bot Configuration
Config File Format
File: config/steam-bots.json
[
{
"username": "turbotrades_bot1",
"password": "your_password",
"sharedSecret": "your_shared_secret",
"identitySecret": "your_identity_secret",
"steamApiKey": "your_steam_api_key",
"proxy": {
"type": "socks5",
"host": "proxy.example.com",
"port": 1080,
"username": "proxy_user",
"password": "proxy_pass"
}
}
]
Environment Variables
# Auto-start bots on server startup
STEAM_BOT_AUTO_START=true
# Steam API key for inventory fetching
STEAM_APIS_KEY=your_api_key
Error Handling
Trade Creation Errors
| Error | Cause | Solution |
|---|---|---|
No bots available |
All bots offline/busy | Wait or add more bots |
Trade URL is required |
User hasn't set trade URL | Redirect to profile settings |
Bot not ready |
Bot not logged in | Check bot status, restart if needed |
Invalid trade URL |
Malformed URL | User must update trade URL |
Trade State Errors
- Declined: User declined offer - notify user, can retry
- Expired: 15 days passed - notify user, items returned to user
- Canceled: Bot/user canceled - update status, no funds credited
- Invalid: Steam error - log error, notify admin
Monitoring & Logging
Bot Health Checks
botManager.getAllBotsHealth();
// Returns health status for all bots
Trade Statistics
botManager.getStats();
// Returns total trades, active trades, errors, etc.
Database Indexes
Trade.offerId- Fast lookup by Steam offer IDTrade.user+Trade.status- User's pending tradesTransaction.user+Transaction.createdAt- Transaction history
Testing
Test Sell Flow
- Set up test bot with Steam account
- Configure bot credentials in
config/steam-bots.json - Start backend with
STEAM_BOT_AUTO_START=true - Set trade URL in profile
- Navigate to
/sellpage - Select items and click sell
- Check verification code matches
- Accept trade in Steam
- Verify balance credited
Mock Testing (No Real Trades)
For development without real Steam bots:
- Comment out bot initialization
- Create mock trade records directly
- Test WebSocket notifications
- Test UI with fake verification codes
Troubleshooting
Trade Not Creating
- Check bot status:
GET /api/admin/bots/health - Verify Steam API key is valid
- Check bot login credentials
- Review bot error logs
- Ensure identity_secret is correct
Trade Created But Not Accepted
- Verify user has mobile authenticator
- Check if items are still tradable
- Verify verification codes match
- Check Steam trade restrictions (7-day holds)
Balance Not Credited
- Check trade status in database
- Review server logs for
tradeAcceptedevent - Verify transaction was created
- Check for any database errors
Future Enhancements
- Queue system (Bull/Redis) for high-volume trades
- Trade status page with live updates
- Mobile notifications when trade is ready
- Automatic retry on trade failure
- Multi-region bot distribution
- Trade escrow handling for new devices
- Price history tracking per trade
- CSV export of trade history
- Admin dashboard for trade monitoring