SUGGESTION: Create Order AFTER Payment Complete

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 years ago
Hello,

Having used Nop for quite some time, I know that there are regular conversations on the forums regarding the way that Nop creates an Order.

Summary:
Currently when a Customer clicks the Final button on the Confirm screen (this may be taking them off to a third-party payment provider such as WorldPay/PayPal) Nop creates an Order for that Customer. That in itself is fine - I like the fact that Nop creates an order at this stage because if the user does not go on to Pay, I can see what the dropout rate is. The problem that I, and most others that have raised it, have is that also at this point Nop allocates Stock to this order i.e. If I order Product A it now minuses 1 from the Stock Qty. At this stage Nop also sends the order confirmation email both to the customer and store owner. So there are a couple of fundamental problems here.

1) If Product A had a Stock Quantity of 1 at the time when the order was placed it is now Zero, and out-of-stock. If the Customer does not complete the order i.e. they don't complete payment, this Product has gone out of stock and no-one else can buy it. On one product that's not a massive issue, but on a site that sells thousands of products per week this is almost unmanageable. Let's also think about malicious attacks on our site, it is POSSIBLE (and possible it frankly all it needs to be to be a major risk) to write a script that will add every product to a customers cart, and go to checkout. This COULD set every product on our entire website out-of-stock!

2) The second issue is a usability. When else have you shopped online and received a order confirmation email before you have even paid - I can't honestly say I ever have, and I buy almost everything online!

As I understand it from reading Nop's responses to this frequently asked question, the reason that Nop works in this one (or one of the Major reasons) is to ensure that when the order is created the item is still in stock. If the order was created AFTER payment was complete then there is a slim possibility that someone else would have completed their order and rendered the product out-of-stock. Fair point, but I believe the risk of this happening is slim (unless you are the likes of Amazon) and if so the system has been engineered in a way that is terribly confusing and risky just to avoid the possibility of a slim occurence taking place.

I would like to make the following suggestions:

1) The first, and preferable solution is to create the order when the Customer clicks the Confirm button on the Checkout Confirm page, but to set the Status to something like "Awaiting Payment". When Payment has been completed (indicated by a Callback from a third party payment gateway), or when the Administrator clicks the "Mark as Paid" button on the order, the system checks that the products the customer just ordered are still in-stock, and if so updates the stock levels at this time - it should also change the Payment status to "Paid". If during doing so Nop discovers that one of the products ordered is out of stock, it raises an exception and changes the Order Status to "Unable to allocate stock" (or something along these lines). If an Order is marked as "Unable to allocate stock", the administrators options would be to :

      - Add more stock and then click a "Try again" button within the order
      - Refund and cancel the order.

This is exactly the process that takes place every day in high street shops. If I reserve an item and go into store to pick it up and for whatever reason it is no longer in stock, they refund me.

This seems like an absolutely perfect solution - to me anyway??? ;-)

2) Nop implement the logic in Point 1 alongside the current logic and make it optional based on a setting. i.e. the developer can choose whether they want the system to work as it currently does, or whether they want it to work as suggested in point 1. This enables the Nop team to still state they have a product that doesn't allow orders to be placed for out-of-stock items, whilst keeping the rest of us happy with a solution that reflects how we and our clients want to work.

Again, if you have any other suggestions please do submit them, but most importantly IF YOU BELIEVE THIS IS BENEFICIAL TO NOPCOMMERCE, PLEASE VOTE.

Thanks guys

Nop Team - please comment.

Al
11 years ago
Hi,

Thanks for suggestion. There were a lot of discussions about it on these forums. The work items (still proposed) are already created (here and here)
11 years ago
Thanks Andrei,

I see they are proposed, but these conversations have been active on the forums for some years now. Do you have any firm plans to change the way this works - it really is quite problematic the way it currently works.

Thanks
Al
11 years ago
How about "reservering" an item? When a user adds a product to the shopping cart start a countdown timer for that item, for example 30 minutes. If the client completes the order within the time set everything is ok, if not release the item to the stock again (effectively remove item from shoppingcart) . You might even show the timer to the user, add to the cart a line saying something like "This item has been reservered for you for 30 minutes" where the 30 minutes starts to count down, this creates a sense of urgency for the client which may increase conversion.
11 years ago
higgsy wrote:
Do you have any firm plans to change the way this works

No, in the near time. Please see this forum post of mine. Maybe, allowing a store owner to choose a preferred way of handling order placement can help (this work item), but it's also not planned to be done in the near time (too many core changes will be required)
11 years ago
Hi Andrei,

Thanks for the response.

I dont want to come across like I am trying to put pressure on, and I understand that there is a lot of the Nop Core that will need to change, but I'm sure it is one of the most requested features, and one of the things that new developers to Nop find most confusing and annoying.

Would it not be possible to dedicate one entire release to such an upgrade i.e. 3.0 dedicated purely to this? If it's a lot of work, why don't you ask a select group of the community to help? A group of developers, agreeing a strategy and plan with yourself could create a solution for this in no-time....

Just my thoughts - it's an open source project after all..

Regards,
Al
11 years ago
Hi Alastair,

I'm personally sure that the current implementation is better and this is how it should work. A lot of e-commerce systems (and even payment gateways) work this way. I've already described reasons in one of my posts why I'm thinking so.

But it would be great if somebody create a fork on codeplex and contribute the changes (plz find more info here). Of course, only if it'll be implement as described in work item 10795.
8 years ago
There is a workaround solution for these wells know disease. Let’s discuss the problems first

1) In case of payment redirect method, Cart gets cleared if payment failed by any reason.
2) If Product A had a Stock Quantity of 1 at the time when the order was placed it is now Zero, and out-of-stock. If the Customer does not complete the order i.e. they don't complete payment, this Product has gone out of stock and no-one else can buy it. On one product that's not a massive issue, but on a site that sells thousands of products per week this is almost unmanageable. Let's also think about malicious attacks on our site, it is POSSIBLE (and possible it frankly all it needs to be to be a major risk) to write a script that will add every product to a customers cart, and go to checkout. This COULD set every product on our entire website out-of-stock!

3) The second issue is usability. When else have you shopped online and received a order confirmation email before you have even paid - I can't honestly say I ever have, and I buy almost everything online!  
I have made below changes to overcome above discussed problems.

Solution

1)  First we need to disable default controller cache by using
[OutputCache(Duration = 1)]
attribute on top of CheckOutController.cs file. Default cache is not allowed to call the controller action on browser back.  Now our confirm(CheckOutController.cs) get action should be call no browser back. We have to put payment method check to restrict this behaviour only for redirect payment methods. In this check, we have to delete last customer order using DeleteOrder method and redirect to ReOrder controller action. ReOrder controller action will add deleted order items again to cart and customer will redirect to cart again. Our confirm action code should like
if (_httpContext.Session[CommonData.IsLastOrderUnpaid] != null && Convert.ToBoolean(_httpContext.Session[CommonData.IsLastOrderUnpaid]))
{
                var lastOrder = _orderService.SearchOrders(storeId: _storeContext.CurrentStore.Id,
                customerId: _workContext.CurrentCustomer.Id, pageSize: 1)
                .FirstOrDefault();
                 if (lastOrder.PaymentMethodSystemName.ToLower().Equals("payments.payucard")
                        || lastOrder.PaymentMethodSystemName.ToLower().Equals("payments.payu"))
                    {
                        if((lastOrder.PaymentMethodSystemName.ToLower().Equals("payments.payucard")
                        || lastOrder.PaymentMethodSystemName.ToLower().Equals("payments.payu")) && lastOrder.PaymentStatus==PaymentStatus.Pending
                            && _orderProcessingService.CanCancelOrder(lastOrder))
                        {
                            _httpContext.Session[CommonData.LastCustomerOrderPlaced] = null;
                            _orderProcessingService.DeleteOrder(lastOrder);
                            _httpContext.Session[CommonData.IsCustomerPaymentFailed] = true;
                            Response.Cache.SetCacheability(HttpCacheability.NoCache);
                            Response.Cache.SetExpires(DateTime.Now);
                            return RedirectToAction("ReOrder", "Order", new { orderId = lastOrder.Id });
                        }
                 }
}


2)  Reward point, Inventory and recurring payment will manage through 1) solution because we are deleting pending orders.
3)  You can move send mail notification code from PlaceOrder to MarkeOrderAsPaid method in OrderProcessing service. Also you can put payment method check instead of move complete code.

Cons

1) Your OrderdId will not be consistence because we are deleting the pending order.
2) every time code need to migrate in new NOP release.

Please correct me if above change might create any serious issue in current NOP flow. I am using NOP 3.30.
8 years ago
a.m. wrote:
Hi Alastair,

A lot of e-commerce systems (and even payment gateways) work this way.


Just out of curiosity, could you give some examples? I don't know of any?

But if I do a quick run-through of the top solutions I don't believe any of these create orders before payment;


Magento
Amazon
Shopify
BigCommerce
Volusion
Yahoo
OSCommerce
demandware

Is that incorrect?
7 years ago
Anything on this? I was shocked to see when I canceled the PayPal payment and I got the email for order placed. I understand I can disable this email and the difference between order placed and order confirmed email.

But the biggest shock was my inventory went from 1 to 0. So it means even if a customer cancels the payment with no intention to buy again it's out of stock for other customers as well.

Any fix for this?
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.