Fix: Multiple TeleBot UI improvements

1. Remove /help from main menu
   - Removed " Help" button from main menu
   - Help still available via /help command

2. Fix support refresh clearing messages
   - Changed from editing message to sending new message
   - Preserves message history when refreshing
   - Shows "No new messages" if no updates instead of clearing
   - Better error handling with user-friendly alerts

3. Add retry payment button for failed payments
   - New "🔄 Retry Payment" button when payment creation fails
   - Shows order ID (friendly reference) in error message
   - PaymentFailedMenu: Retry, View Basket, Main Menu options
   - HandleRetryPayment: Re-shows currency selection
   - Preserves order and allows payment retry without recreating order

Technical Changes:
- MenuBuilder: Added PaymentFailedMenu method
- CallbackHandler: Added retry_payment case and HandleRetryPayment method
- HandlePayment: Updated error messages to use PaymentFailedMenu
- HandleRefreshConversation: Sends new message instead of editing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
SysAdmin 2025-10-06 03:48:04 +01:00
parent 99bb083bd6
commit 17cb9c7721
2 changed files with 106 additions and 8 deletions

View File

@ -176,6 +176,10 @@ namespace TeleBot.Handlers
await HandleViewPayment(bot, callbackQuery.Message, session, Guid.Parse(data[1]), callbackQuery.From);
break;
case "retry_payment":
await HandleRetryPayment(bot, callbackQuery.Message, session, Guid.Parse(data[1]));
break;
case "reviews":
await HandleViewReviews(bot, callbackQuery.Message, session);
break;
@ -990,9 +994,10 @@ namespace TeleBot.Handlers
$"This might be due to:\n" +
$"• Payment gateway temporarily unavailable\n" +
$"• Network connectivity issues\n\n" +
$"Your cart has been restored. Please try again.",
$"Order ID: {orderId}\n" +
$"You can retry payment creation or your cart has been restored.",
Telegram.Bot.Types.Enums.ParseMode.Markdown,
_menuBuilder.CartMenu(session.Cart)
_menuBuilder.PaymentFailedMenu(orderId, session.Cart)
);
return;
}
@ -1030,9 +1035,10 @@ namespace TeleBot.Handlers
$"❌ *Payment System Error*\n\n" +
$"Sorry, there was a technical issue creating your {currency} payment.\n\n" +
$"Our payment system may be undergoing maintenance.\n" +
$"Your cart has been restored. Please try again later.",
$"Order ID: {orderId}\n" +
$"You can retry payment or your cart has been restored.",
Telegram.Bot.Types.Enums.ParseMode.Markdown,
_menuBuilder.CartMenu(session.Cart)
_menuBuilder.PaymentFailedMenu(orderId, session.Cart)
);
return;
}
@ -1176,6 +1182,25 @@ namespace TeleBot.Handlers
session.State = SessionState.ViewingOrder;
}
private async Task HandleRetryPayment(ITelegramBotClient bot, Message message, UserSession session, Guid orderId)
{
// Store order ID for payment retry
session.TempData["current_order_id"] = orderId;
// Show payment currency selection again
var currencies = await _shopService.GetAvailableCurrenciesAsync();
await bot.EditMessageTextAsync(
message.Chat.Id,
message.MessageId,
$"💰 *Select Payment Method*\n\n" +
$"Order ID: {orderId.ToString().Substring(orderId.ToString().Length - 8).ToUpper()}\n\n" +
$"Choose your preferred cryptocurrency:",
parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
replyMarkup: MenuBuilder.PaymentCurrencyMenu(currencies, orderId)
);
}
private async Task HandleViewPayment(ITelegramBotClient bot, Message message, UserSession session, Guid orderId, User telegramUser)
{
var order = await _shopService.GetCustomerOrderAsync(
@ -1334,8 +1359,56 @@ namespace TeleBot.Handlers
private async Task HandleRefreshConversation(ITelegramBotClient bot, CallbackQuery callbackQuery, UserSession session)
{
await ShowCustomerConversationInCallback(bot, callbackQuery, session);
await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Messages refreshed");
try
{
var user = callbackQuery.From;
// Get conversation history for this customer
var messages = await _shopService.GetCustomerConversationAsync(
user.Id,
user.Username ?? "",
$"{user.FirstName} {user.LastName}".Trim(),
user.FirstName ?? "",
user.LastName ?? ""
);
var conversationText = "💬 *Your Messages*\n\n";
if (messages?.Any() == true)
{
conversationText += "Recent conversation:\n\n";
foreach (var msg in messages.OrderBy(m => m.CreatedAt).TakeLast(8)) // Show last 8 messages
{
var isFromBusiness = msg.Direction == 0; // AdminToCustomer
var sender = isFromBusiness ? "🏪 Shop" : "👤 You";
var time = msg.CreatedAt.ToString("MMM dd, HH:mm");
conversationText += $"*{sender}* _{time}_\n{msg.Content}\n\n";
}
conversationText += "_Type your message or use buttons below._";
// Send new message instead of editing to preserve history
await bot.SendTextMessageAsync(
callbackQuery.Message!.Chat.Id,
conversationText,
parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
replyMarkup: MenuBuilder.ConversationMenu()
);
await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Messages refreshed");
}
else
{
await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "No new messages", showAlert: false);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error refreshing conversation");
await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Error refreshing messages", showAlert: true);
}
}
private async Task HandleExitChat(ITelegramBotClient bot, CallbackQuery callbackQuery, UserSession session)

View File

@ -24,8 +24,7 @@ namespace TeleBot.UI
new[] { InlineKeyboardButton.WithCallbackData("🛒 View Basket", "cart") },
new[] { InlineKeyboardButton.WithCallbackData("📦 My Orders", "orders") },
new[] { InlineKeyboardButton.WithCallbackData("⭐ Reviews", "reviews") },
new[] { InlineKeyboardButton.WithCallbackData("💬 Support", "support") },
new[] { InlineKeyboardButton.WithCallbackData("❓ Help", "help") }
new[] { InlineKeyboardButton.WithCallbackData("💬 Support", "support") }
});
}
@ -228,6 +227,32 @@ namespace TeleBot.UI
return new InlineKeyboardMarkup(buttons);
}
public InlineKeyboardMarkup PaymentFailedMenu(Guid orderId, ShoppingCart cart)
{
var buttons = new List<InlineKeyboardButton[]>
{
new[]
{
InlineKeyboardButton.WithCallbackData("🔄 Retry Payment", $"retry_payment:{orderId}")
}
};
if (!cart.IsEmpty())
{
buttons.Add(new[]
{
InlineKeyboardButton.WithCallbackData("🛒 View Basket", "cart")
});
}
buttons.Add(new[]
{
InlineKeyboardButton.WithCallbackData("🏠 Main Menu", "menu")
});
return new InlineKeyboardMarkup(buttons);
}
public InlineKeyboardMarkup CartMenu(ShoppingCart cart)
{
var buttons = new List<InlineKeyboardButton[]>();