Firstly you would need to generate a temporary order number or something to be able to associate the payment with the real order later
Then also the scenario you would also need to check for is the redirection happens and the payment is made and then the call back does not work - Then you have a payment with no order
In the case where the payment fails you can recreate the cart from the order
and then delete the order
public virtual List<string> AddOrderToCart(Order order, out int count)
{
var addToCartWarnings = new List<string>();
var cart = _shoppingCartService.GetShoppingCart(_workContext.CurrentCustomer, ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id);
foreach (var item in order.OrderItems)
{
var product = item.Product;
//quantity
var quantity = item.Quantity;
//product attributes
var attributes = item.AttributesXml;
//rental attributes
DateTime? rentalStartDate = null;
DateTime? rentalEndDate = null;
if (item.Product.IsRental)
{
rentalStartDate = item.RentalStartDateUtc;
rentalEndDate = item.RentalEndDateUtc;
}
addToCartWarnings.AddRange(_shoppingCartService.AddToCart(_workContext.CurrentCustomer,
product, ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id,
attributes, decimal.Zero,
rentalStartDate, rentalEndDate, quantity, true));
}
cart = _shoppingCartService.GetShoppingCart(_workContext.CurrentCustomer, ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id);
count = cart.Count();
return addToCartWarnings;
}
Then in your payment error routine add
int count;
var order = _orderService.GetOrderById(orderId);
if (order != null)
{
var warnings = AddOrderToCart(order, out count);
if (order.PaymentStatus == PaymentStatus.Pending)
{
if (_orderProcessingService.CanCancelOrder(order))
_orderProcessingService.CancelOrder(order, false);
order = _orderService.GetOrderById(orderId);
if (order != null)
{
if (order.OrderStatus == OrderStatus.Cancelled)
_orderService.DeleteOrder(order);
}
}
redirectUrl = _webHelper.GetStoreLocation() + "cart";
return Redirect(redirectUrl);