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<Order>> GetOrderByCustomerIdAsync(Guid customerId, Guid orderId);
|
||||||
Task<ApiResponse<CryptoPayment>> CreatePaymentAsync(Guid orderId, int currency);
|
Task<ApiResponse<CryptoPayment>> CreatePaymentAsync(Guid orderId, int currency);
|
||||||
Task<ApiResponse<List<CryptoPayment>>> GetOrderPaymentsAsync(Guid orderId);
|
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);
|
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]));
|
await HandleRetryPayment(bot, callbackQuery.Message, session, Guid.Parse(data[1]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "delete_order":
|
||||||
|
await HandleDeleteOrder(bot, callbackQuery, session, Guid.Parse(data[1]), callbackQuery.From);
|
||||||
|
break;
|
||||||
|
|
||||||
case "reviews":
|
case "reviews":
|
||||||
await HandleViewReviews(bot, callbackQuery.Message, session);
|
await HandleViewReviews(bot, callbackQuery.Message, session);
|
||||||
break;
|
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)
|
private async Task HandleViewPayment(ITelegramBotClient bot, Message message, UserSession session, Guid orderId, User telegramUser)
|
||||||
{
|
{
|
||||||
var order = await _shopService.GetCustomerOrderAsync(
|
var order = await _shopService.GetCustomerOrderAsync(
|
||||||
|
|||||||
@ -24,6 +24,7 @@ namespace TeleBot.Services
|
|||||||
Task<Order?> GetOrderAsync(Guid orderId);
|
Task<Order?> GetOrderAsync(Guid orderId);
|
||||||
Task<Order?> GetCustomerOrderAsync(Guid orderId, long telegramUserId, string telegramUsername, string displayName, string firstName, string lastName);
|
Task<Order?> GetCustomerOrderAsync(Guid orderId, long telegramUserId, string telegramUsername, string displayName, string firstName, string lastName);
|
||||||
Task<CryptoPayment?> CreatePaymentAsync(Guid orderId, string currency);
|
Task<CryptoPayment?> CreatePaymentAsync(Guid orderId, string currency);
|
||||||
|
Task<bool> CancelOrderAsync(Guid orderId, string identityReference);
|
||||||
Task<List<CustomerMessage>?> GetPendingMessagesAsync();
|
Task<List<CustomerMessage>?> GetPendingMessagesAsync();
|
||||||
Task<bool> MarkMessageAsSentAsync(Guid messageId, string? platformMessageId = null);
|
Task<bool> MarkMessageAsSentAsync(Guid messageId, string? platformMessageId = null);
|
||||||
Task<bool> MarkMessageAsFailedAsync(Guid messageId, string reason);
|
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()
|
public async Task<List<CustomerMessage>?> GetPendingMessagesAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@ -209,12 +209,30 @@ namespace TeleBot.UI
|
|||||||
{
|
{
|
||||||
var buttons = new List<InlineKeyboardButton[]>();
|
var buttons = new List<InlineKeyboardButton[]>();
|
||||||
|
|
||||||
// If order has pending payment, show payment details button
|
// Order management based on status and payment state
|
||||||
if (order.Status == 0 && order.Payments.Any(p => p.Status == 0)) // PendingPayment order with pending payment
|
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[]
|
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