Start here. This is the direct spoken answer to practice first.
Overview
A button being hidden and an action reference being generated by the framework do not authorize a mutation.
Inside the action I establish the current session, authorize the exact resource and operation, and validate every submitted field on the server. I derive ownership and prices from trusted data rather than hidden inputs. For a mutation that must not repeat, I use an idempotency key or a database uniqueness rule and commit the change in a transaction before invalidating affected views.