Skip to main content
Legend
February 18, 2020
Question

FAO Ben - Shopping Cart Payment

  • February 18, 2020
  • 2 replies
  • 2356 views

You may be able to throw some light or want to throw some on light on the rather interesting thread/s going on in the Wappler forum about 'shopping carts' - data store, etc

 

Some posters have quite correctly highlighted the issue of sending the 'product price' via the client-side generated js form, as it's been well known for years it is open to manipulation.

 

Other posters have said you should get and check the price from your database BUT that, as far as I know, makes zero difference as you will always end up with a client-side generated form containing prices BEFORE  it gets sent to your payment gateway - same problem - form prices can be easily manipulated.

 

The only secure way I know is to send the data from the payment form to the payment gateway of your choice and then get the form variables back from the payment gateway THEN check the prices in your database. If the prices match then you send the variables back to the payment gateway for processing. If the prices don't match then the variables are not sent back to the payment gateway and the payment is rejected, quite a more complex workflow to consider.

 

Brad seemed to be particularly alarmed by this raised  'security' issue BUT currently his ticket website uses the 'unsecure' process of sending the initial js form data, which anyone can manipulate by looking at the source code or using the browser inspection tools, where the form data can easily be altered.

 

Obviously this posses issues and makes the whole process far more complex. I've seen developers (including myself) try to disguise the process by inserting the payment form on a 'self-sending' page with just a processing message appearing in the browser but its still easy to stop the browser and gain access to the form code, especiallly in cases where there is a time lag contacting the gateway provider.

 

Which brings me to the point. How much of an issue is this. Should the seller not be checking their end that they are only sending goods out which match with the orders coming in? I can see a big issue if the product being sold is a digitally download but if the order needs manual overseeing and distributing how much of an issue is it. I mean if I went to a shop and tried to pass over a fiver for something which cost a tenner and the cashier didnt check I'd provided the correct money..........how is the web different, apart form in a few unique circumstances.

 

Just trying to kick around a few thoughts to be considered on the subject, any thoughts from yourself?

 

If anyone else wants to chime in please do so.

 

 

 

 

This topic has been closed for replies.

2 replies

pziecina
Legend
February 18, 2020

Not really a problem Os.

 

Save the users order in a 'holding' database table. Then once the form is submitted to say paypals ipn, do a comparison of the returned total payment data from paypal with the total cost, (and any other info you wish) using sql transactions. Finally using the same transaction, transfer the clients info, (etc) to the actual orders table, and delete the 'temp' info using the same transaction.

 

MySQL supports transactions, but as transactions are a database engine function, the db engine must be one that supports them, (2 of the most popular engines do have support).

 

This is an ideal use of transactions, simply because, if one sql process fails, they all fail, and a reason for the failure is stored in the db log file, so you can trace the problem, (eg. price miss-match).

 

I know many will not wish to use transactions, as they also require stored procedures, but both are the way forward. Which is why I asked if the team plan on support when the 'planned' database functions are returned to Dw.

osgood_Author
Legend
February 18, 2020

Hi Paula,

 

Well yes, that's my opinion - you need to send the form data to the payment gateway FIRST before its sent back to check locally NOT check it BEFORE its sent to the payment gateway.

 

As far as I can see, whatever you do client-side OR server-side BEFORE the information is sent to the payment gateway is still vulnerable to manipulation.

 

But then Im not really onboard (up-to-date) with all these new API options which have sprung up. Maybe some of them have a more secure way of handing the data so it cant be manipulated BEFORE it gets to the payment gateway.

 

I've just had a quick look at one Stripe option, which uses js but the price is 'exposed' in the script, so its no more safer than just sending variables in a form. Thats just one option though, it has several, as does Paypal.

pziecina
Legend
February 18, 2020

That's why I said to use transactions.

 

No matter what happens transactions are a db function, so the user can manipulate anything they like client side.

Even if they order multiple items, and manipulate multiple costs, one can do a check using transactions on every single item, so any 'cheating' is immidiately exposed.

 

Stored procedures with transactions are how banks, enterprises, etc do it, and with good reason. If any discrepencies are found then the db can remove all data from the db that the user has stored, keeping the db structure clean. Plus if a single sp in a transaction fails, for any reason, then the entire transaction rolls back everything, as if it had never happened.

BenPleysier
Community Expert
Community Expert
February 18, 2020

Hi Os, thank you for sharing this. I was quite amused when I showed an example of a manipulated local storage and the result. I received a barrage (exaggerated) of do's and dont's when it was my intention to illustrate the problem.

 

I totally agree that the seller should be checking at their end. Problem is that the payment has already gone through and it is a hassle to undo this.

 

What I have done is to compare the local storage value with that in the database (https://github.com/Wappler/wCart/blob/master/_checkout.html lines 3-7). If there is a discrepancy, the checkout page does not show; instead there is a warning message (lines 23-30). I have also multiplied the amounts by the value of varCheckoutCheck so that, in the case of a manipulation, the sum payable is 0. If in some underhanded way, they still manage to submit the form, the amount paid does not have to be refunded. In this case, as an added bonus, the server action will redirect them to https://bunchoblokes.org/(which needs attention regarding the SSL certificate - tomorrow) (https://github.com/Wappler/wCart/blob/master/dmxConnect/api/orders/checkout.php line 265).

 

Having fun all the way.

Wappler is the DMXzone-made Dreamweaver replacement and includes the best of their powerful extensions, as well as much more!
osgood_Author
Legend
February 18, 2020

I guess that would be one option - checking the value in local storage against the price in the database and then not displaying the checkout form if there is some mis-match. Never thought of that, no matter how long you think, always miss the bloomin obvious. I'll have a go at that next time I require a cart on a website. 

 

Lots of posts/opinions but a lot don't really make many clear suggestions. If prices can be checked before handing them off to the payment gateway then thats going to be a lot simpler than trying to get information back from a payment gateway provider to check against a local database.