import telebot
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
import qrcode
import io
import uuid
bot_token = '7234242900:AAE7O45X8iUaCOa5hPlOJxX3VYyL_x6BP44'
bot = telebot.TeleBot(bot_token)
# In-memory data storage (for demonstration purposes)
users = {
6783978461: {
"username": "@ROBAT968",
"account_balance": 50.00,
"listed_value": 0.00,
"referrals": 2,
"referred_by": None,
"referral_link": "https://t.me/YourBotUsername?start=6783978461",
"ltc_address": None,
"card_history": [],
"telegram_id": 6783978461, # Add telegram_id to user data
},
1234567890: {
"username": "@UserTwo",
"account_balance": 10.00,
"listed_value": 0.00,
"referrals": 5,
"referred_by": 6783978461,
"ltc_address": None,
"card_history": [],
"telegram_id": 1234567890, # Add telegram_id to user data
}
}
card_listings = []
# Store Purchase information (Card ID and Purchase ID)
purchase_history = []
admins = [6783978461] # List of admin user IDs
# Function to create a new user profile
def create_user_profile(user_id, username, referred_by=None):
users[user_id] = {
"username": username,
"account_balance": 0.00,
"listed_value": 0.00,
"referrals": 0,
"referred_by": referred_by,
"referral_link": f"t.me/PrepaidGCStockbot?start={user_id}",
"ltc_address": None,
"card_history": [],
"telegram_id": user_id, # Add telegram_id to user data
}
# Reward the referrer if referred_by is valid
if referred_by and referred_by in users:
users[referred_by]['account_balance'] += 00.01 # Reward amount
users[referred_by]['referrals'] += 1
# Main Menu
def main_menu(user_id):
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("⚙️Vendor Dashboard⚙️", callback_data="vendor_dashboard"))
# Removed FAQ button
markup.add(InlineKeyboardButton("✔️Checker", callback_data="checker"))
markup.add(InlineKeyboardButton("💳Listings", callback_data="listings"),
InlineKeyboardButton("👤Profile", callback_data="profile"))
if user_id in admins:
markup.add(InlineKeyboardButton("Admin Panel", callback_data="admin_panel"))
return markup
# Vendor Dashboard
def vendor_dashboard(user_id):
user_data = users.get(user_id, {})
listed_value = sum(item['price'] for item in card_listings if item['user_id'] == user_id)
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("⤴️List Cards💳", callback_data="list_cards"))
markup.add(InlineKeyboardButton("🔗Manage Listings🔗", callback_data="manage_user_listings"))
markup.add(InlineKeyboardButton("🌍Main Menu", callback_data="main_menu"))
dashboard_text = (
f"🔅 PrepaidGCStock — Vendor Dashboard\n\n"
f"User: {user_data.get('username', 'Unknown')}\n"
f"Account Balance: US${user_data.get('account_balance', 0.00):.2f}\n"
f"Listed Value: US${listed_value:.2f}\n\n"
f"Use the buttons below to view and manage your vendor account."
)
return dashboard_text, markup
# Manage User Listings
def manage_user_listings(user_id):
markup = InlineKeyboardMarkup()
user_listings = [listing for listing in card_listings if listing['user_id'] == user_id]
for listing in user_listings:
markup.add(InlineKeyboardButton(f"Card ID: {listing['card_id']} - Price: ${listing['price']}", callback_data=f"edit_user_listing_{listing['card_id']}"))
markup.add(InlineKeyboardButton("Back to Vendor Dashboard", callback_data="vendor_dashboard"))
return markup
# Admin Panel Menu
def admin_panel_menu():
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("Manage Users", callback_data="manage_users"))
markup.add(InlineKeyboardButton("Manage Card Listings", callback_data="manage_all_listings"))
markup.add(InlineKeyboardButton("Set Deposit Addresses", callback_data="set_deposit_addresses"))
markup.add(InlineKeyboardButton("Main Menu", callback_data="main_menu"))
return markup
# Admin Manage Users Menu
def admin_manage_users_menu():
markup = InlineKeyboardMarkup()
for user_id, user_info in users.items():
markup.add(InlineKeyboardButton(f"{user_info['username']} - Balance: ${user_info['account_balance']:.2f}", callback_data=f"manage_user_{user_id}"))
markup.add(InlineKeyboardButton("Back to Admin Panel", callback_data="admin_panel"))
return markup
# Admin Manage User Options
def admin_manage_user_options(user_id):
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("Increase Balance", callback_data=f"increase_balance_{user_id}"),
InlineKeyboardButton("Decrease Balance", callback_data=f"decrease_balance_{user_id}"))
markup.add(InlineKeyboardButton("Manage Listings", callback_data=f"admin_manage_listings_{user_id}"))
markup.add(InlineKeyboardButton("Back to Users List", callback_data="manage_users"))
return markup
# Admin Manage Listings for a Specific User
def admin_manage_user_listings(user_id):
markup = InlineKeyboardMarkup()
user_listings = [listing for listing in card_listings if listing['user_id'] == user_id]
for listing in user_listings:
markup.add(InlineKeyboardButton(f"Card ID: {listing['card_id']} - Price: ${listing['price']}", callback_data=f"admin_edit_listing_{listing['card_id']}"))
markup.add(InlineKeyboardButton("Back to User Management", callback_data=f"manage_user_{user_id}"))
return markup
# Admin Manage All Listings
def admin_manage_all_listings():
markup = InlineKeyboardMarkup()
for listing in card_listings:
markup.add(InlineKeyboardButton(f"Card ID: {listing['card_id']} - Price: ${listing['price']}", callback_data=f"admin_edit_listing_{listing['card_id']}"))
markup.add(InlineKeyboardButton("Back to Admin Panel", callback_data="admin_panel"))
return markup
# Handle Increase/Decrease User Balance
def handle_balance_change(call, change_type, user_id):
try:
msg = bot.send_message(call.message.chat.id, f"Enter amount to {change_type} for {users[user_id]['username']}:")
bot.register_next_step_handler(msg, process_balance_change, change_type, user_id)
except Exception as e:
bot.send_message(call.message.chat.id, f"Error: {str(e)}")
def process_balance_change(message, change_type, user_id):
try:
amount = float(message.text.strip())
if change_type == "increase":
users[user_id]['account_balance'] += amount
elif change_type == "decrease":
users[user_id]['account_balance'] -= amount
bot.send_message(message.chat.id, f"{users[user_id]['username']}'s balance has been {change_type}d by ${amount:.2f}. New balance: ${users[user_id]['account_balance']:.2f}.")
except ValueError:
bot.send_message(message.chat.id, "Invalid amount. Please enter a numeric value.")
except Exception as e:
bot.send_message(message.chat.id, f"Error: {str(e)}")
# Handle Admin Edit Listing
@bot.callback_query_handler(func=lambda call: call.data.startswith("admin_edit_listing_"))
def admin_edit_listing(call):
listing_id = call.data.split('_')[3] # Correctly extract the listing ID
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("Change Price", callback_data=f"change_price_{listing_id}"),
InlineKeyboardButton("Delete Listing", callback_data=f"delete_listing_{listing_id}"))
markup.add(InlineKeyboardButton("Back to Listings", callback_data="manage_all_listings"))
bot.send_message(call.message.chat.id, f"You selected listing ID {listing_id} for editing.", reply_markup=markup)
# Handle Card Listing by User
def list_cards(call):
user_id = call.from_user.id
msg = bot.send_message(user_id, "Please enter the card details in the format: cc:mm:yy:cvv:balance (e.g., '1234567890123456:01:24:123:100'):")
bot.register_next_step_handler(msg, save_card_details, user_id)
# Save Card Details (Step 2: Save card details and ask for price)
def save_card_details(message, user_id):
try:
card_cc, card_mm, card_yy, card_cvv, card_balance = message.text.split(':')
card_cc = card_cc.strip()
card_mm = card_mm.strip()
card_yy = card_yy.strip()
card_cvv = card_cvv.strip()
card_balance = card_balance.strip() # Assuming balance is a string
# Ask for the price of the card
msg = bot.send_message(user_id, "Please enter the price for this card:")
bot.register_next_step_handler(msg, save_card_price, user_id, card_cc, card_mm, card_yy, card_cvv, card_balance)
except ValueError:
msg = bot.send_message(user_id, "Invalid format. Please enter the card details in the format: cc:mm:yy:cvv:balance")
bot.register_next_step_handler(msg, save_card_details, user_id)
# Save Card Price (Step 3: Save the card price and ask for photo)
def save_card_price(message, user_id, card_cc, card_mm, card_yy, card_cvv, card_balance):
try:
card_price = float(message.text.strip())
# Generate a unique Card ID
card_id = str(uuid.uuid4())
card = {"card_id": card_id, # Add Card ID
"name": f"{card_cc} :{card_mm}:{card_yy}:{card_cvv}:{card_balance}",
"price": card_price,
"status": "available",
"user_id": user_id}
# Ensure the user exists before updating listed_value
if user_id in users:
users[user_id]['listed_value'] += card_price
card_listings.append(card)
msg = bot.send_message(user_id, "Card listed successfully. Now, please upload a photo of the card.")
bot.register_next_step_handler(msg, save_card_photo, card)
else:
bot.send_message(message.chat.id, "Error: User not found.")
except ValueError:
msg = bot.send_message(user_id, "Invalid price. Please enter a numeric value for the price.")
bot.register_next_step_handler(msg, save_card_price, user_id, card_cc, card_mm, card_yy, card_cvv, card_balance)
# Purchase Confirmation
def confirm_purchase(call, listing_id):
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("Confirm", callback_data=f"confirm_purchase_{listing_id}"),
InlineKeyboardButton("Cancel", callback_data="cancel_purchase"))
bot.send_message(call.message.chat.id, f"Are you sure you want to purchase this card?", reply_markup=markup)
# Save Card Photo (Step 4: Save card photo)
def save_card_photo(message, card):
if message.content_type == 'photo':
photo = message.photo[-1].file_id # Get the highest resolution photo
card["photo"] = photo
bot.send_message(message.chat.id, f"Card '{card['name']}' listed with a photo successfully.")
else:
bot.send_message(message.chat.id, "No photo uploaded. Listing the card without a photo.")
# Handle Card Purchase
@bot.callback_query_handler(func=lambda call: call.data.startswith("purchase_"))
def purchase_card(call):
listing_id = call.data.split('_')[1] # Keep it as a string
user_id = call.from_user.id
# Check if the listing is available
for card in card_listings:
if card['card_id'] == listing_id and card['status'] == "available":
confirm_purchase(call, listing_id)
return
bot.send_message(call.message.chat.id, "Card not available or already sold.")
# Handle Purchase Confirmation
@bot.callback_query_handler(func=lambda call: call.data.startswith("confirm_purchase_"))
def confirm_purchase_handler(call):
listing_id = call.data.split('_')[2] # Keep it as a string
user_id = call.from_user.id
# Find the card and process the purchase
for card in card_listings:
if card['card_id'] == listing_id and card['status'] == "available":
if users[user_id]['account_balance'] >= card['price']:
# Deduct balance from buyer
users[user_id]['account_balance'] -= card['price']
# Mark the card as sold
card['status'] = "sold"
card['user_id'] = user_id
# Generate a unique Purchase ID
purchase_id = str(uuid.uuid4())
# Store purchase information
purchase_history.append({"purchase_id": purchase_id, "card_id": card['card_id']})
# Add to user's card history
users[user_id]["card_history"].append(
{"card_id": card['card_id'], "purchase_id": purchase_id, "price": card['price'], "name": card['name']})
bot.send_message(call.message.chat.id, f"Purchase successful! You bought card '{card['name']}' for ${card['price']:.2f}.\n\nCard ID: {card['card_id']}\nPurchase ID: {purchase_id}")
# Send the full card details
bot.send_message(call.message.chat.id, f"Here are the full card details:\n{card['name']}")
else:
bot.send_message(call.message.chat.id, "Insufficient balance to purchase this card.")
return
bot.send_message(call.message.chat.id, "Card not available or already sold.")
# Handle Purchase Cancellation
@bot.callback_query_handler(func=lambda call: call.data == "cancel_purchase")
def cancel_purchase(call):
bot.send_message(call.message.chat.id, "Purchase cancelled.")
# Display available card listings
def card_purchase_menu():
markup = InlineKeyboardMarkup()
for listing in card_listings:
status_icon = "🟢" if listing["status"] == "available" else "🔴"
masked_card_number = listing["name"].split(':')[0][:6] # Extract first 6 digits
card_balance = listing["name"].split(':')[4] # Extract card balance (now at index 4)
markup.add(InlineKeyboardButton(f'{status_icon} {masked_card_number}... - Balance: {card_balance} - ${listing["price"]}', callback_data=f'purchase_{listing["card_id"]}'))
markup.add(InlineKeyboardButton("🌍Main Menu", callback_data="main_menu"))
return markup
# Display user profile
def display_profile(user_id):
user = users.get(user_id)
if user:
profile_text = (f"🔅 PrepaidGCStock — User Profile\n\n"
f"User Info:\n"
f"Username: @{user['username']}\n"
f"User ID: {user['telegram_id']}\n" # Added Telegram ID
f"Account Balance: US${user['account_balance']:.2f}\n"
f"Listed Value: US${user['listed_value']:.2f}\n"
f"Referrals: {user['referrals']}\n"
f"Referral Link: {user['referral_link']}\n\n"
f"Crypto Deposit Address:\n"
f"LTC: {user['ltc_address'] or 'Not set'}")
else:
profile_text = "Profile not found."
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("💰Deposit", callback_data="deposit_menu"))
markup.add(InlineKeyboardButton("💸Withdraw", callback_data="withdraw_menu")) # Added Withdraw button
markup.add(InlineKeyboardButton("💳Card History", callback_data="card_history")) # Added Card History button
markup.add(InlineKeyboardButton("🌍Main Menu", callback_data="main_menu")) # Added Main Menu button
return profile_text, markup
# Generate and Send QR Code for LTC Address
def send_qr_code(chat_id, address):
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(address)
qr.make(fit=True)
img = qr.make_image(fill='black', back_color='white')
# Convert the image to a byte stream to send it via Telegram
bio = io.BytesIO()
bio.name = 'qr.png'
img.save(bio, 'PNG')
bio.seek(0)
bot.send_photo(chat_id, photo=bio)
# Deposit Menu
def deposit_menu(user_id):
markup = InlineKeyboardMarkup()
user = users.get(user_id)
if user:
markup.add(InlineKeyboardButton(f"Deposit ŁLTC", callback_data="deposit_ltc"))
markup.add(InlineKeyboardButton("Back to Profile", callback_data="profile"))
else:
markup.add(InlineKeyboardButton("Back to Main Menu", callback_data="main_menu"))
return markup
# Handle Admin Setting Deposit Addresses
def set_deposit_addresses(user_id):
markup = InlineKeyboardMarkup()
for user_id, user_info in users.items():
markup.add(InlineKeyboardButton(f"{user_info['username']}", callback_data=f"set_deposit_{user_id}"))
markup.add(InlineKeyboardButton("Back to Admin Panel", callback_data="admin_panel"))
return markup
# Process Deposit Address Setting
def process_set_deposit_address(message, user_id, crypto_type):
if crypto_type == "ltc":
users[user_id]['ltc_address'] = message.text.strip()
bot.send_message(message.chat.id, f"LTC address for {users[user_id]['username']} set to: {message.text.strip()}")
bot.send_message(message.chat.id, "Deposit address has been updated.")
# Withdraw Menu (Placeholder - you'll need to implement the actual withdrawal logic)
def withdraw_menu(user_id):
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("Withdraw LTC", callback_data="withdraw_ltc"))
markup.add(InlineKeyboardButton("Back to Profile", callback_data="profile"))
return markup
# Handle Withdraw Request (Placeholder - you'll need to implement the actual withdrawal logic)
@bot.callback_query_handler(func=lambda call: call.data == "withdraw_ltc")
def handle_withdraw_ltc(call):
user_id = call.from_user.id
msg = bot.send_message(call.message.chat.id, "Please enter the LTC address to withdraw to:")
bot.register_next_step_handler(msg, process_withdraw_ltc, user_id)
def process_withdraw_ltc(message, user_id):
# Implement your actual withdrawal logic here
# ...
# Example:
withdraw_address = message.text.strip()
withdraw_amount = 10.00 # Replace with user input or calculation
if users[user_id]['account_balance'] >= withdraw_amount:
users[user_id]['account_balance'] -= withdraw_amount
bot.send_message(message.chat.id, f"Withdrawal of ${withdraw_amount:.2f} to {withdraw_address} initiated.")
else:
bot.send_message(message.chat.id, "Insufficient balance.")
@bot.callback_query_handler(func=lambda call: True)
def callback_query(call):
user_id = call.from_user.id
if call.data == "main_menu":
bot.edit_message_text("🔅 PrepaidGCStock — Main Menu \n\nWelcome Back to PrepaidGCStock — The one place to buy and sell GiftCard.!\n\nHave questions? You can join our FAQ channel @PrepaidGiftCardFAQ and learn on how to use bot and buy giftcards on our secure platform.\n\n📕Channel: @PrepaidGiftCardFAQ\n🆘 Support :@Pstockbot_support\n\n To get started, use one of the options below!", call.message.chat.id, call.message.message_id, reply_markup=main_menu(user_id))
elif call.data == "vendor_dashboard":
dashboard_text, markup = vendor_dashboard(user_id)
bot.edit_message_text(dashboard_text, call.message.chat.id, call.message.message_id, reply_markup=markup)
elif call.data == "manage_user_listings":
markup = manage_user_listings(user_id)
bot.edit_message_text("🔅 PrepaidGCStock — Manage Listings", call.message.chat.id, call.message.message_id, reply_markup=markup)
elif call.data.startswith("edit_user_listing_"):
listing_id = call.data.split('_')[3]
bot.send_message(call.message.chat.id, f"You selected listing ID {listing_id} for editing.")
elif call.data == "list_cards":
list_cards(call) # Trigger the listing flow
elif call.data == "listings":
bot.edit_message_text("🔅 PrepaidGCStock — Available Listings\n\n\n🟢means= Available In Stock\n🔴means= Sold Out", call.message.chat.id, call.message.message_id, reply_markup=card_purchase_menu())
elif call.data == "admin_panel":
bot.edit_message_text("🔅 PrepaidGCStock — Admin Panel", call.message.chat.id, call.message.message_id, reply_markup=admin_panel_menu())
elif call.data == "manage_users":
bot.edit_message_text("🔅 PrepaidGCStock — Manage Users", call.message.chat.id, call.message.message_id, reply_markup=admin_manage_users_menu())
elif call.data.startswith("manage_user_"):
user_id_to_manage = int(call.data.split('_')[2])
bot.edit_message_text(f"🔅 PrepaidGCStock — Manage User: {users[user_id_to_manage]['username']}", call.message.chat.id, call.message.message_id, reply_markup=admin_manage_user_options(user_id_to_manage))
elif call.data.startswith("increase_balance_"):
user_id_to_edit = int(call.data.split('_')[2])
handle_balance_change(call, "increase", user_id_to_edit)
elif call.data.startswith("decrease_balance_"):
user_id_to_edit = int(call.data.split('_')[2])
handle_balance_change(call, "decrease", user_id_to_edit)
elif call.data.startswith("admin_manage_listings_"):
user_id_to_manage = int(call.data.split('_')[3])
markup = admin_manage_user_listings(user_id_to_manage)
bot.edit_message_text(f"🔅 PrepaidGCStock — Manage Listings for {users[user_id_to_manage]['username']}", call.message.chat.id, call.message.message_id, reply_markup=markup)
elif call.data == "manage_all_listings":
markup = admin_manage_all_listings()
bot.edit_message_text("🔅 PrepaidGCStock — Manage All Listings", call.message.chat.id, call.message.message_id, reply_markup=markup)
elif call.data == "profile":
profile_text, markup = display_profile(user_id)
bot.send_message(call.message.chat.id, profile_text, reply_markup=markup)
elif call.data == "deposit_menu":
markup = deposit_menu(user_id)
bot.send_message(call.message.chat.id, "Select the cryptocurrency to deposit:", reply_markup=markup)
elif call.data == "deposit_ltc":
ltc_address = users[user_id]['ltc_address'] or "Address not set. Please contact support."
if ltc_address != "Address not set. Please contact support.":
send_qr_code(call.message.chat.id, ltc_address)
bot.send_message(call.message.chat.id, f"Please send LTC to the following address:\n\n{ltc_address}")
elif call.data == "set_deposit_addresses":
markup = set_deposit_addresses(user_id)
bot.send_message(call.message.chat.id, "Select a user to set deposit addresses:", reply_markup=markup)
elif call.data.startswith("set_deposit_"):
user_id_to_set = int(call.data.split('_')[2])
msg = bot.send_message(call.message.chat.id, "Enter the LTC address:")
bot.register_next_step_handler(msg, process_set_deposit_address, user_id_to_set, "ltc")
elif call.data.startswith("change_price_"):
listing_id = call.data.split('_')[2]
msg = bot.send_message(call.message.chat.id, "Enter the new price for the listing:")
bot.register_next_step_handler(msg, process_change_price, listing_id)
elif call.data.startswith("delete_listing_"):
listing_id = call.data.split('_')[3]
card_listings[:] = [listing for listing in card_listings if listing["card_id"] != listing_id]
bot.send_message(call.message.chat.id, f"Listing ID {listing_id} has been deleted.")
elif call.data == "withdraw_menu": # Handle withdraw menu
markup = withdraw_menu(user_id)
bot.send_message(call.message.chat.id, "Select a withdrawal option:", reply_markup=markup)
elif call.data == "withdraw_ltc":
handle_withdraw_ltc(call)
elif call.data == "card_history":
user = users.get(user_id)
if user:
card_history = user['card_history']
if card_history:
history_text = "Your Card Purchase History:\n\n"
for item in card_history:
history_text += f"Card ID: {item['card_id']}\nPurchase ID: {item['purchase_id']}\nPrice: ${item['price']:.2f}\nCard: {item['name']}\n\n"
bot.send_message(call.message.chat.id, history_text)
else:
bot.send_message(call.message.chat.id, "You have no card purchase history yet.")
else:
bot.send_message(call.message.chat.id, "Profile not found.")
def process_change_price(message, listing_id):
try:
new_price = float(message.text.strip())
for listing in card_listings:
if listing["card_id"] == listing_id:
listing["price"] = new_price
bot.send_message(message.chat.id, f"Listing ID {listing_id} price has been updated to ${new_price:.2f}.")
break
except ValueError:
bot.send_message(message.chat.id, "Invalid price. Please enter a numeric value.")
@bot.message_handler(commands=['start'])
def start(message):
user_id = message.from_user.id
# Check if the user has a profile; if not, create one
if user_id not in users:
referred_by = None
if len(message.text.split()) > 1:
referred_by = int(message.text.split()[1])
create_user_profile(user_id, message.from_user.username or "Unknown", referred_by)
bot.send_message(message.chat.id, "🔅 PrepaidGCStock — Main Menu \n\nWelcome Back to PrepaidGCStock — The one place to buy and sell GiftCard.!\n\nHave questions? You can join our FAQ channel @PrepaidGiftCardFAQ and learn on how to use bot and buy giftcards on our secure platform.\n\n📕Channel: @PrepaidGiftCardFAQ\n🆘 Support :@Pstockbot_support\n\n To get started, use one of the options below!", reply_markup=main_menu(user_id))
# Polling
bot.polling()