0

This project makes the customer first create an order and them has to pay for said order via Braintree, However the issue that I am getting is that a customer can create an order and them close the application. This will cause the order to still exist however the customer did not have to pay for their order. If any one knows of a work around for this their help would be thanked. (The orders and payments work. Its just this bug that I'm worried about)

Orders Controller

    [HttpPost]
    [ValidateAntiForgeryToken]

    public async Task<ActionResult> FirstClassCreate(FormCollection values)
    {

        var order = new Order();
        TryUpdateModel(order);
        var customer = db.Users.FirstOrDefault(x => x.Email == User.Identity.Name);
        var cart = ShoppingCart.GetCart(this.HttpContext);



        try
        {

Sets the order attributes

            order.DeliveryDate = DateTime.Now.AddDays(1);

            order.DeliveryMethod = "First Class";
            order.FirstName = customer.FirstName;
            order.LastName = customer.LastName;
            order.PostalCode = customer.PostalCode;
            order.State = customer.State;
            order.City = customer.City;
            order.Email = customer.Email;
            order.Country = customer.Country;
            order.Phone = customer.PhoneNumber;
            order.Address = customer.Address;

            order.Username = customer.Email;
            order.OrderDate = DateTime.Now;
            var currentUserId = User.Identity.GetUserId();
            order.Total = cart.GetFirstClass();

            if (order.SaveInfo && !order.Username.Equals("guest@guest.com"))
            {

                var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
                var store = new UserStore<ApplicationUser>(new ApplicationDbContext());
                var ctx = store.Context;
                var currentUser = manager.FindById(User.Identity.GetUserId());



                //Save this back
                //http://stackoverflow.com/questions/20444022/updating-user-data-asp-net-identity
                //var result = await UserManager.UpdateAsync(currentUser);
                await ctx.SaveChangesAsync();

                await storeDB.SaveChangesAsync();
            }

Saves the order to the database

            //Save Order
            storeDB.Orders.Add(order);
            await storeDB.SaveChangesAsync();
            //Process the order
            cart = ShoppingCart.GetCart(this.HttpContext);
            order.Total = cart.GetFirstClass();

            order = cart.CreateOrder(order);


            return RedirectToAction("FirstClass", "Checkouts");



        }
        catch
        {
            //Invalid - redisplay with errors
            return View(order);
        }
    }

Checkouts controller

    public ActionResult CreateFirstClass(FormCollection collection)
    {
        var gateway = config.GetGateway();
        Decimal amount;

        //Need to get the amount

        try
        {
            amount = Convert.ToDecimal(Request["amount"]);
        }
        catch (FormatException e)
        {
            TempData["Flash"] = "Error: 81503: Amount is an invalid format.";
            return RedirectToAction("New");
        }

        string nonceFromTheClient = collection["payment_method_nonce"];

        var cart = ShoppingCart.GetCart(this.HttpContext);

        //if (id == null)
        //{
        //    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        //}
        //order =  Orders.FindAsync(id);

Gets the necessary payment methods

        var request = new TransactionRequest
        {
            Amount = cart.GetFirstClass(),
            PaymentMethodNonce = nonceFromTheClient,
            Options = new TransactionOptionsRequest
            {
                SubmitForSettlement = true
            }
        };
        cart.EmptyCart();

        Result<Transaction> result = gateway.Transaction.Sale(request);



        if (result.IsSuccess())
        {
            Transaction transaction = result.Target;
            return RedirectToAction("Show", new { id = transaction.Id });
        }
        else if (result.Transaction != null)
        {
            return RedirectToAction("Show", new { id = result.Transaction.Id });
        }
        else
        {
            string errorMessages = "";
            foreach (ValidationError error in result.Errors.DeepAll())
            {
                errorMessages += "Error: " + (int)error.Code + " - " + error.Message + "\n";
            }
            TempData["Flash"] = errorMessages;
            return RedirectToAction("New");
        }

    }

#

  • 1
    This doesn't feel like a code issue so much as a general process issue. Basically, you'll need something in the database to indicate that an order has been paid for, and you don't fulfill the order until it *has* been paid for. Any orders that haven't been paid for 24 hours (or similar) after creation can be deleted... – Jon Skeet May 25 '17 at 10:50
  • Um. When you get payment, update the record? Don't act on records that haven't been paid? – spender May 25 '17 at 10:51
  • Add something to your application backend (or make a separate script) that checks the database for orders that haven't been paid for (I assume there is some way for you to know that, if not definitely add it either way) and deletes them. – stelioslogothetis May 25 '17 at 10:52

0 Answers0