Feature: Complete order management for pending orders
- Added delete order functionality with identity verification - OrderDetailsMenu now shows conditional buttons based on order/payment state - Retry payment if no payments exist - View payment details if payment pending - Delete order option for all pending orders - Full client SDK implementation for CancelOrderAsync 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
3cc7092967
commit
f440042204
@ -11,4 +11,5 @@ public interface IOrderService
|
||||
Task<ApiResponse<Order>> GetOrderByCustomerIdAsync(Guid customerId, Guid orderId);
|
||||
Task<ApiResponse<CryptoPayment>> CreatePaymentAsync(Guid orderId, int currency);
|
||||
Task<ApiResponse<List<CryptoPayment>>> GetOrderPaymentsAsync(Guid orderId);
|
||||
Task<ApiResponse<bool>> CancelOrderAsync(Guid orderId, string identityReference);
|
||||
}
|
||||
@ -189,4 +189,27 @@ public class OrderService : IOrderService
|
||||
System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ApiResponse<bool>> CancelOrderAsync(Guid orderId, string identityReference)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.PostAsJsonAsync(
|
||||
$"api/orders/{orderId}/cancel",
|
||||
new { IdentityReference = identityReference }
|
||||
);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return ApiResponse<bool>.Success(true, response.StatusCode);
|
||||
}
|
||||
|
||||
return ApiResponse<bool>.Failure("Failed to cancel order", response.StatusCode);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error cancelling order {OrderId}", orderId);
|
||||
return ApiResponse<bool>.Failure($"Error: {ex.Message}", System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,6 +180,10 @@ namespace TeleBot.Handlers
|
||||
await HandleRetryPayment(bot, callbackQuery.Message, session, Guid.Parse(data[1]));
|
||||
break;
|
||||
|
||||
case "delete_order":
|
||||
await HandleDeleteOrder(bot, callbackQuery, session, Guid.Parse(data[1]), callbackQuery.From);
|
||||
break;
|
||||
|
||||
case "reviews":
|
||||
await HandleViewReviews(bot, callbackQuery.Message, session);
|
||||
break;
|
||||
@ -1215,6 +1219,43 @@ namespace TeleBot.Handlers
|
||||
);
|
||||
}
|
||||
|
||||
private async Task HandleDeleteOrder(ITelegramBotClient bot, CallbackQuery callbackQuery, UserSession session, Guid orderId, User telegramUser)
|
||||
{
|
||||
// Build identity reference from telegram user
|
||||
var identityReference = $"telegram:{telegramUser.Id}:{telegramUser.Username ?? ""}";
|
||||
|
||||
var success = await _shopService.CancelOrderAsync(orderId, identityReference);
|
||||
|
||||
if (success)
|
||||
{
|
||||
await bot.EditMessageTextAsync(
|
||||
callbackQuery.Message!.Chat.Id,
|
||||
callbackQuery.Message.MessageId,
|
||||
"✅ *Order Deleted*\n\n" +
|
||||
$"Order #{orderId.ToString().Substring(orderId.ToString().Length - 8).ToUpper()} has been cancelled and removed.",
|
||||
parseMode: Telegram.Bot.Types.Enums.ParseMode.Markdown,
|
||||
replyMarkup: new InlineKeyboardMarkup(new[]
|
||||
{
|
||||
new[]
|
||||
{
|
||||
InlineKeyboardButton.WithCallbackData("⬅️ Back to Orders", "orders"),
|
||||
InlineKeyboardButton.WithCallbackData("🏠 Main Menu", "menu")
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await bot.AnswerCallbackQueryAsync(callbackQuery.Id, "Order deleted successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
await bot.AnswerCallbackQueryAsync(
|
||||
callbackQuery.Id,
|
||||
"Failed to delete order. It may have already been processed.",
|
||||
showAlert: true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleViewPayment(ITelegramBotClient bot, Message message, UserSession session, Guid orderId, User telegramUser)
|
||||
{
|
||||
var order = await _shopService.GetCustomerOrderAsync(
|
||||
|
||||
@ -24,6 +24,7 @@ namespace TeleBot.Services
|
||||
Task<Order?> GetOrderAsync(Guid orderId);
|
||||
Task<Order?> GetCustomerOrderAsync(Guid orderId, long telegramUserId, string telegramUsername, string displayName, string firstName, string lastName);
|
||||
Task<CryptoPayment?> CreatePaymentAsync(Guid orderId, string currency);
|
||||
Task<bool> CancelOrderAsync(Guid orderId, string identityReference);
|
||||
Task<List<CustomerMessage>?> GetPendingMessagesAsync();
|
||||
Task<bool> MarkMessageAsSentAsync(Guid messageId, string? platformMessageId = null);
|
||||
Task<bool> MarkMessageAsFailedAsync(Guid messageId, string reason);
|
||||
@ -358,6 +359,31 @@ namespace TeleBot.Services
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> CancelOrderAsync(Guid orderId, string identityReference)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!await AuthenticateAsync())
|
||||
return false;
|
||||
|
||||
var result = await _client.Orders.CancelOrderAsync(orderId, identityReference);
|
||||
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
_logger.LogInformation("Order {OrderId} cancelled for customer {Identity}", orderId, identityReference);
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.LogWarning("Failed to cancel order {OrderId}: {Error}", orderId, result.ErrorMessage);
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error cancelling order {OrderId}", orderId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<CustomerMessage>?> GetPendingMessagesAsync()
|
||||
{
|
||||
try
|
||||
|
||||
@ -209,12 +209,30 @@ namespace TeleBot.UI
|
||||
{
|
||||
var buttons = new List<InlineKeyboardButton[]>();
|
||||
|
||||
// If order has pending payment, show payment details button
|
||||
if (order.Status == 0 && order.Payments.Any(p => p.Status == 0)) // PendingPayment order with pending payment
|
||||
// Order management based on status and payment state
|
||||
if (order.Status == 0) // Pending Payment
|
||||
{
|
||||
if (!order.Payments.Any())
|
||||
{
|
||||
// No payment created - offer retry
|
||||
buttons.Add(new[]
|
||||
{
|
||||
InlineKeyboardButton.WithCallbackData("🔄 Retry Payment", $"retry_payment:{order.Id}")
|
||||
});
|
||||
}
|
||||
else if (order.Payments.Any(p => p.Status == 0)) // Has pending payment
|
||||
{
|
||||
// Show payment details
|
||||
buttons.Add(new[]
|
||||
{
|
||||
InlineKeyboardButton.WithCallbackData("💳 View Payment Details", $"payment:{order.Id}")
|
||||
});
|
||||
}
|
||||
|
||||
// Allow deleting pending orders
|
||||
buttons.Add(new[]
|
||||
{
|
||||
InlineKeyboardButton.WithCallbackData("💳 View Payment Details", $"payment:{order.Id}")
|
||||
InlineKeyboardButton.WithCallbackData("🗑️ Delete Order", $"delete_order:{order.Id}")
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user