Shopping cart and stock management - php

I am currently building an ecommerce site with PHP/MySQL. Recently, I have been working on the Shopping Cart integration. The client wanted to ensure that stock was available to potential buyers, so I created a stock management system. The shopping cart works as follows:
Client adds a quantity of an item to
his cart.
Item quantity is reserved from
available stock in the database.
No one else can purchase reserved
stock.
Stock remains reserved until client
processes order - where stock is then
removed from database.
If client abandons his cart, stock remains reserved.
If another client wishes to buy an item, but only available stock is reserved by another client, then the client can steal the reserved stock if it has been inactive for 20 minutes.
My question is, what are best practices for this kind of scenario? Am I doing this correctly? The main thing is that the client does not want to sell stock that he does not have.
I am looking to have a discussion on how to improve the functionality, or what others are doing to accomplish this.

An alternative approach may be not to reserve a stock upon putting it in the shopping cart. Perform a check each time a page is reloaded, should the item be no more available, display a message like "The item you wish to buy has just been sold out. It will be available shortly". And you remove the product from the shopping cart.
Now, you absolutely have to reserve the shopping cart contents right before you initiate the payment operation, then either remove it from the stock or remove the reserve depending on the success/failure of the payment. You do it better in one code run, so that the reserve lasts as briefly as possible.
ProcessOrder ()
{
bool reserved = ReserveShoppingCartContents ();
if (reserved)
{
bool paymentStatus = ProcessPayment ();
if (paymentStatus)
RemoveShoppingCartContentsFromStock ();
else
ReleaseShoppingCartReserve ();
}
else
{
RefreshShoppingCartContents (); // Remove positions or adjust quantities
MessageBox ("Could not reserve your shopping cart contents. Please check out your selection");
}
}
The briefer your reserve lasts, the higher the chance your item will be actually sold. You minimize the possibility of a conflict: CustomerA begins with the shopping cart, the item gets reserved, CustomerB comes, sees the item is not on stock and goes away, CustomerA decides he doesn't like the price and cancels the operation. You had two potential customers but couldn't sell to either.

i do a check for the stock on every reload of the pages during the checkout proccess and redirect them to the cart page with an error message if during the process the items have been sold out.
The stock is reduced only on order confirmed
Also i restore the stock if the order is canceled.

Related

In Woo I need real stock levels to decrease when order is created and don't decrease until order cancel

I need a product stock to decrease immediately on order creation and it should not increase unless the order is cancelled (it should also not decrease a second time upon payment successful or any other switch).
My problem is I want to use my storefront to invoice and collect local service work. I am using a pay later invoice gateway that drops orders into processing & woo does not decrease stock in this status so the quantities I just sold are still listed as available in my product/catalog pages. However, I found that when a customer goes to add these intangible stock quantities they receive a message like unable to add to cart insufficient stock even though the catalog pages show its available.
I cannot figure out what function this would serve since the quantity is already spoken for in a payment pending order why is it showing in product/catalog pages. I showered every post I could find across 3 search engines trying to find a similar situation with an answer but haven't had much luck.
I found this:
function reduce_stock_processing($order_id) {
wc_reduce_stock_levels($order_id);
}
In a post with similar issues and tried to implement but it had no effect that I could see.
I then found this:
add_action( 'woocommerce_valid_order_statuses_for_payment', function( $statuses, $order ) {
$statuses[] = 'on-hold';
return $statuses;
}, 10, 2 );
But it allowed me to drop orders into an on-hold status where woo does pull stock and it allowed for payment to be made from that status. I thought this is great finally, but when I started another round of testing I found that if I created an order and purchased all the remaining stock of a certain product it would A: pull the stock from inventory correctly leaving product stock at zero, then B: when I sent an email invoice to customer with payable link.
It tells them that the order cannot be paid for since item is out of stock. Frustrating, because it handles orders with abundant stock well; after order completed I'm left with appropriate stock levels.
It seems that woo needs to have extra stock on hand to allow customers to pay.... or at least that is how it seems to me.
Any ideas on how I can achieve my goal? Thanks in advance.
Update-
So I changed the first code to this:
function reduce_stock_pending($order_id) {
wc_reduce_stock_levels($order_id);
}
add_action('woocommerce_order_status_pending', 'reduce_stock_pending');
and at first I thought it didn't work because the stock levels didn't change upon creating an order and having it drop straight to pending payment status, but after toggling the status to on-hold it reduced stock and when I toggle it back to pending status the stock remains reduced and with payment successful it does not further reduce stock so that seems at least workable considering I'm the moderator I'll know what to do.... but is there a better solution that would allow me to create an order and drop it straight into pending and have it reduce stock right away without having to toggle status back and forth.
-More Info
Order notes:
everything located above image only pertains to payment
So it seems to be rapidly increasing & then reducing stock on status change to pending. Again any help would be appreciated.

Php cart: how to store product information in cart

I want to make implement Cart funcionality in Laravel. I chose this plugin. But here and in many others cart packages I see that cart row stores not a product id but full information (product name, options, price). But what if the product title or product price was changed? Then the user still sees the old title (price) and it will cause some inconvienences to him. What I do not understand, why most cart packages store full information in cart row.
So what is the right way to store cart data: full info or by keys (product_id, option_id, ...)?
There is a preferred way to store cart information, and its the latter that you mentioned.
The reason for this is to not only increase the security of your shopping cart, but to also ensure that, as you rightly pointed out, customers are getting the right price, even after a change.
Typically what you want to do is store the product ID, any customisation options as well as a cart ID. Depending on the amount of products and the traffic you're receiving it may be unnecessary to work out the basket price each time a new page is loaded, and so typically you only work out a new price when a new product is added, taken away or modified; in addition to when the customer gets to the checkout area.
This serves several purposes,
the first is that is ensure that when the cart is directly changed by
a customer action, you can show an updated price.
The second is that you cut down the amount of calculations you have to do by a large amount by only changing the prices in the basket when something acts upon it.
You can ensure that customers cannot cheat the system by modifying the price, then going on to pay a different amount because you stored the price in the session.
I can't give you a more concrete answer because you've been fairly light on the specifics, but I hope this indicates the direction you should be heading in.

Adding cart error to prevent going into the checkout

i have been working trying to create an edit order system where when an order is bellow a given state the customer can edit the order
now i have everything working by adding a reorder like link which does the exact same as reorder but creates a session which identifies that your editing an order, in order to do this for out of stock products i had to turn backorders on
however i have found a glitch, if a customer was to add 5 hats to the cart and logs off, if when they come back the item's stock qty is now 0 they can still go into the cart, naturally this is because of the backorders being enabled.
i have made a CartController to pick up adding/updates to the shopping cart and manually check if the stock is less than what's in the cart, however if the customer had the item when there was ample stock, leave and returns when it's now out of stock, they bypass these checks
one suggestion that was made by a college was that we shorten the lifetime of the cart session for registered customers, while we could do this, there is more of a problem during a sale
originally, before backorders was turned on, if this same situation occurred the "Proceed to checkout" button would be missing and you would get an error message
now i've tried fixing up a new IndexController and using $this->_getSession()->addError('Some products in your cart have gone out of stock'); but i'm not getting the same results
so how do i create an error message that will prevent the customer from going into the checkout until they have fixed up their cart
I would suggest you to make a dedicated page let's call it edit_cart. When you are redirecting to checkout, check all products and validate their qty in magento. Push them to edit_cart and let them delete out of stock products from cart. After this redirect them to checkout.

PHP:update a stock with values in the cart

I am currently working on an eCommerce website, but i need some advice regarding the stock management.
I want the shopping cart to work as follow:
CostumerA add a productO to cart with a quantity of '1'.
CostumerB tries to add the same product to their cart but with no success.
CostumerA logs out or their session expires.
CostumerB tries to add productO again and is allowed to do so since the product hasn't been added to CustomerA's cart ...
i came up with 2 solutions but neither is reliable from my point of view:
add a field 'champ' to Table product that initially have value of product.quantity but change with cart movements.
add table Cart and update it with cart movements.
as u can see both solution require lot of work.Is there a better way to implement my shopping cart.
I think a better way might be to only update if the user checks out and check stock on the product listing pages.
The downside being the following scenario:
user A adds an item to their cart
user B adds the same item to their cart
user A checks out and the item is now out of stock
user B checks out, but item is out of stock
You'll need to check stock at every point in this process and inform your users what's going on.
Tying up inventory by having a user placing it in their cart is a bad idea. If user A adds all of the available stock of one item to their cart, no one else can buy it until they either log out, or you log them out with some sort of timeout.

shopping cart price change

Say i have a Laptop for 600.00. Say i change it to $650.00. How do shopping carts handle that? Like do they store the price in the cart or the item? How do they make sure they get the price they wanted but not bill the customer the new change without asking them? Or do most store them in both?
I was thinking maybe i could store it in both.
So if the current price is over the cart price for a item, don't remove it/bill them from their cart. Then after, tell them what was billed/email a receipt for the items that didn't change that was billed(say they had more then one item) and remove it from the cart. For the items that did change, say something like "Items left in cart due to price change, please check if you still want to buy the items at the new price." So leave the items that changed in the cart but update the price in the cart.
Thats my idea on how to do it. I don't think the language should matter. Guess this is more of a logical type question. Do most shopping carts do it this way or is there a better way?
Simple shopping carts are just arrays of products that are maintained through sessions and cookies. You can do anything you want. Just make sure users can't do anything they want such as change prices through the url. But most of all make it very, very, very easy for the user to checkout.
Most developers will create an array with product objects so if any changes are made to a product shopping carts will reflect this change. However, if you change your prices then obvious you will have a problem if a user clicks on on price but then you change it and the uses doesn't see this change until after they paid or become confused why the price went up mid shopping experience.
In terms of maintaining the line item if you have users sign in before they can add things to a cart then you don't need to worry about creating a cookie/session to store the array of the line items until they do checkout and the line items are saved with their information for later reference.
In this case what you will want to do is create a line item which is associated to the object so you can get all the products information but at the same time store the price in that actual LineItem model so if you do update your price it will not affect shoppers mid buying experience.
And if you want users to pay higher prices because you change your mind and want to use the line item model you can just do what is sated in the last paragraph and check the price right before a user decides to checkout. If it is different then let them no that this product is now x amount to purchase and don't forget to apologize.
The short answer, it all depends on how it was coded.
I assume the transaction that you are talking about is in process. If the price changes after the user completes the transaction, then it would be considered a "Bad Thing" in the terms of customer service, and may potentially be illegal in the eyes of your payments processor.
I like your idea of comparing the price in the cart vs the newest price. However if the user can change the value of the price of an item in the request to view the cart, it could cause many problems with what they actually get charged. For example, if the user changed the price of the laptop to $1200, and in your code you reduced the value in their cart by the difference, they could get that laptop for $0, which would be a "Bad Thing".
$1200 - User Input
$600 - Actual Price
-$600 - Adjustment against price
$0 - price customer is charged?
Another example would be if you make the price of the item a value that the user can edit, and they are a malicious user, they could potentially change the price to -$600.00, which again would be a "Bad Thing".
The more secure way to do it would be to store the item ID of the item in the cart in the link to view the cart, then retrieve/update the price of the item in the cart every time the properties (total, etc) of the cart are requested. That way if a malicious user tried the plus or minus trick, they would just get a message that the price has been updated to the "current price".
The OWASP site has some open source security tools that can help test your code against situations where the user tries to high jack a shopping cart. Their address is http://www.owasp.org
If the cart simply contains a reference to the item (such as the id/primary key), you don't need to store the price in two places at all. You simply load the objects from the cart when you need them, and prices will automatically reflect the change. In most cases, the changes will be infrequent enough that it is not a big deal from a user perspective.

Categories