We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 40122
    • 330 Posts
    I am working on a project to turn a ModX site into an e-commerce shop. One of the biggest things I am trying to overcome is how to protect data that is in hidden form fields, such as prices.

    As we know something like
    <input type="hidden" name="amount" value="0.60">
    can be easily altered by the clients browser. This is unavoidable.

    To get around this I had an idea and I wanted to run this passed the excellent programmers here:

    1. Products a user adds to their cart are stored in an SQL table. Data stored is something like UserID, ID, Price, Quantity
    2. Upon checkout a script runs through the table and compares the Prices in the users cart (held with the cart_table) with the prices kept with the products database. If a Price does not match and error occurs and the price is adjusted.
    3. The data is then fed to the payment gateway.

    Actually typing this out now it seems to make a lot of sense. But it would still be good to get someone elses opinion on this.

    Thanks!
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      Authorize.net generates a "digital fingerprint" using various values from the submission. You can store this, or make your own, then use their response object to create the fingerprint again and compare it to the original.

      From the Authorize.net documentation:
      The transaction authentication used by the Direct Post Method is a “transaction fingerprint,” or a hash of merchant- and transaction-specific information using the HMAC- MD5 (MD5 RFC 1321 with a 128-bit hash value) hashing algorithm. The HMAC-MD5 is used only for generating the unique transaction fingerprint. The transaction fingerprint must be generated on a per-transaction basis by a server-side script on the merchant’s Web server and inserted into the transaction request.
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 28042 ☆ A M B ☆
        • 24,524 Posts
        Actually, probably closer to your exact requirements, the sample Authorize.net checkout steps don't pass the price in hidden fields at all, it passes the item, and the amount (plus tax and shipping if applicable) is calculated by your script just before sending off the payment request. That's pretty much what you were describing. Of course, with MODX we can use the SESSION or COOKIE to pass the item rather than in hidden fields. I'm still studying it, but I believe that's how SimpleCart handles the checkout process.
          Studying MODX in the desert - http://sottwell.com
          Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
          Join the Slack Community - http://modx.org
          • 25287
          • 81 Posts
          I've been trying to the same thing, and getting stuck on how to have variables persist across snippets.

          Using the hidden field with a post method creates a $_POST['myvariable'] that persists, but it also includes the value in the resource html - and so is open to manipulation.

          What I was hoping to do is run a snippet using a property passed from the chunk, and have the snippet set a variable then open a new resource. Upon opening the new resource would then run another snippet to find the relevant data from a db table and present it via another chunk. In theory I believe the second resource could send the retrieved values to PayPal for the checkout process. All that to avoid the "hidden" but easily manipulated data.

          Maybe there's a simpler way to do that.

          So far I've got this far - this does seem to successfully pass the $IDprint value:

          The form and button on the product page:
          	<td class="buy_button" width="120">
          		<form action="[[!getMYpid? &IDprint=`[[+id]]`]]" method="post" >
          		<input type="image" src="assets/gfx/Add2Cart.png" alt="Click to submit"/>
          		</form>
          	</td>
          


          The getMYpid snippet is what has me baffled - it does not seem possible to create a persistent variable ...
          <?php
          /** 
          *  get the IDprint property passed by the buybutton form
          */ 
          $PrintID = $scriptProperties['IDprint'];
          
          /** 
          *  attempting to create superglobal variable - not working
          */ 
          $_POST['IDprint'] = $PrintID;
          
          /** 
          *  code to open resource 11
          */ 
          $webLink = "[[~11]]";
          return $webLink;


          I can't get it working, but others more adept with php will probably have a solution. meltingdog - this may be of use to you
            • 28042 ☆ A M B ☆
            • 24,524 Posts
            The POST is only created by the browser as a result of submitting a form. You can't create it on the server, or pass it to the browser. It's a one-way only mechanism. And the PHP $_POST and $_REQUEST arrays are merely PHP's method of providing access to it.
              Studying MODX in the desert - http://sottwell.com
              Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
              Join the Slack Community - http://modx.org
              • 3749
              • 24,544 Posts
              If you want to pass data from one page to another without putting it in the form, you have to either put it in the URL (insecure) or set $_SESSION variables.

              A snippet on the form page can set the product ID as a session variable. That way the receiving page can get that value and set the price from it, so the ID and the price are not available for manipulation by the user. If you need to respond to user input to set the price, you can have the form post to its own page and have a snippet on that page set the $_SESSION variables (including a secret key), then forward the user on to another page where the secret key is checked before proceeding.



                Did I help you? Buy me a beer
                Get my Book: MODX:The Official Guide
                MODX info for everyone: http://bobsguides.com/modx.html
                My MODX Extras
                Bob's Guides is now hosted at A2 MODX Hosting
                • 49407
                • 159 Posts
                You shouldn't be relying on form data for accurate pricing in the shopping cart, ever. Use sessions and database strictly to store items for the cart. The cart should be dropped on checkout, page close (via session) or after an expiration period, unless the buyer already has an account.

                The flow should be like this:

                User adds to cart.
                The product id is added to the users cart in the session with a cart id and the user's id. OR. If they are logged in it could be added to their DB cart.
                Whenever the user views their cart the script should calculate the total based on product ID/cart quantity comparisons to the database and display the items strictly using the database.

                You should never ever rely on form fields for pricing or any other secure data.

                Edit: Session data will be available to all snippets. It's stored until the user closes the site in the browser, it's even available across multiple browser tabs.

                Are you building an eCommerce add-on?
                [ed. note: aaronkent last edited this post 11 years, 10 months ago.]
                  • 40122
                  • 330 Posts
                  Quote from: sottwell at Dec 05, 2014, 10:21 PM
                  , the sample Authorize.net checkout steps don't pass the price in hidden fields at all, it passes the item, and the amount (plus tax and shipping if applicable) is calculated by your script just before sending off the payment request. SimpleCart handles the checkout process.

                  Haha, so obvious! Thanks
                    • 40122
                    • 330 Posts
                    Quote from: aaronkent at Dec 07, 2014, 01:42 AM
                    You shouldn't be relying on form data for accurate pricing in the shopping cart, ever. Use sessions and database strictly to store items for the cart. The cart should be dropped on checkout, page close (via session) or after an expiration period, unless the buyer already has an account.

                    The flow should be like this:

                    User adds to cart.
                    The product id is added to the users cart in the session with a cart id and the user's id. OR. If they are logged in it could be added to their DB cart.
                    Whenever the user views their cart the script should calculate the total based on product ID/cart quantity comparisons to the database and display the items strictly using the database.

                    Are you building an eCommerce add-on?

                    Thanks! This makes perfect sense.

                    I wont be making an add-on - I don't think I'm skilled enough for that yet - but I will write up what I've done here if anyones interested.