When rendering any new form, also hash the user's IP (or X-FORWARDED-FOR IP in case of proxying), their User Agent and a timestamp. Make this part of the form submission (hidden value). If you see two of this same value, you've got a button-pressed-twice situation, so reject it with an error.
When rendering any new form, also hash the user's IP (or X-FORWARDED-FOR IP in case of proxying), their User Agent and a timestamp. Make this part of the form submission (hidden value). If you see two of this same value, you've got a button-pressed-twice situation, so reject it with an error.