views:

250

answers:

6

I have a purchase page and I don't want the user to be able to refresh the page and resubmit the form once they get to the 'order complete' page because it automatically sets them up in our system via database values and charges their card via paypal (only want these to happen ONCE)... I have seen some sites that say 'Don't hit refresh or you will get charged twice!' but that is pretty lame to leave it open to possibility, what's a good way to only allow it to be submitted once or prevent them from refreshing, etc?

PS: I saw a few similar questions: http://stackoverflow.com/questions/1646812/php-stop-a-form-from-being-accidentally-reprocessed-when-back-is-pressed and http://stackoverflow.com/questions/665399/how-do-i-stop-the-back-and-refresh-buttons-from-resubmitting-my-form but found no satisfactory answer... an ASP.NET MVC specific answer would be ideal too if there is a mechanism for this.

EDIT: Once they click submit it POSTS to my controller and then the controller does some magic and then returns a view with an order complete message, but if I click refresh on my browser it does the whole 'do you want to resend this form?' that is bad...

A: 

While serving up the order confirmation page you can set a token that you also store in the DB/Cache. At the first instance of order confirmation, check for this token's existence and clear the token. If implemented with thread safety, you will not be able to submit the order twice.

This is just one of the many approaches possible.

Sands
A: 

Give each visitor's form a unique ID when the page is first loaded. Note the ID when the form is submitted. Once a form has been submitted with that ID, don't allow any further requests using it. If they click refresh, the same ID will be sent.

Macha
A: 

Off the top of my head, generate a System.Guid in a hidden field on the GET request of the page and associate it with your checkout/payment. Simply check for it and display a message saying 'Payment already processed.' or such.

Wim Hollebrandse
+10  A: 

The standard solution to this is the POST/REDIRECT/GET pattern. This pattern can be implemented using pretty much any web development platform. You would typically:

  • Validate submission after POST
  • if it fails re-render the original entry form with validation errors displayed
  • if it succeeds, REDIRECT to a confirmation page, or page where you re-display the input - this is the GET part
  • since the last action was a GET, if the user refreshes at this point, there is no form re-submission to occur.
RedFilter
Which, in ASP.Net MVC, is executed by simply doing a "return RedirectToAction()".
womp
A: 

Simply do a redirect from the page that does all the nasty stuff to the "Thank you for your order" page. Having done that, the user can hit refresh as many times as he likes.

klausbyskov
A: 

Kazi Manzur Rashid wrote about this (together with other asp.net mvc best-practices). He suggests using two filters to handle data transfer between the POST and the follwing GET using TempData.

Nasser