POST safely to Paypal

How do I make sure that a malicious user does not change the values manually in the following form?


<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> 
    <input type="hidden" name="cmd" value="_cart"> 
    <input type="hidden" name="upload" value="1"> 
    <input type="hidden" name="business" value="seller@designerfotos.com"> 
    <input type="hidden" name="item_name_1" value="Item Name 1"> 
    <input type="hidden" name="amount_1" value="1.00"> 
    <input type="hidden" name="item_name_2" value="Item Name 2"> 
    <input type="hidden" name="amount_2" value="2.00"> 
    <input type="submit" value="PayPal"> 
</form>
 

For what I’ve read Paypal gives the option of saving payment buttons in the PayPal Account. This way, PayPal holds pricing information in the PayPal account. But I’m looking for a solution that does not involve manually creating a button for each product or saving the prices in Paypal.

As far as I understand it, the validation would need to be done on the result of the submission. In this situation, PayPal is processing the submission so they are the only ones that can validate the information. Furthermore, they don’t know what’s possibly valid unless you tell them which goes against your requirement of creating a valid product within PayPal.

I’m sure there’s some kinks in this plan, but it’s a start to something that might work. What if you did this:

  1. The user is presented with a product page which contains a hyperlink or button containing the product ID or SKU. No price or name information. When followed, this hyperlink takes the user to a process page on your own server.

  2. The process page accepts the ID or SKU from the previous page and performs a database query to gather the price, name, description, etc. Using a server side language you send these values to the PayPal processing page via a POST request to simulate the form submission.

This would keep the submission one layer away from the user.

Hi, thanks for the reply.

The problem with that is that I need the customer to send the request from their browser so that when they submit the form they go to the Paypal payments page and log in to their account, write their address or what not…

Well the customer would still be using their browser in the same fashion as before. Essentially the server just creates an additional step in the process to query the database for the correct product values. Once the values are queried the server creates a POST request to PayPal and the customer is right back in the same track.

The user may see a slight delay or refresh with the extra page. If that’s a concern for you it’s possible to query the database with AJAX on the fly to get the correct values from the ID or SKU. I’m not sure how you’d create a POST request with javascript but it might be possible.

In any case, the user would be taken to PayPal and proceed normally to complete their purchase.

Once the values are queried the server creates a POST request to PayPal and the customer is right back in the same track.
[…]
In any case, the user would be taken to PayPal and proceed normally to complete their purchase.

I believe the user won’t be taken to Paypal if I submit the request from my server to Paypal.

Whether the requesting is coming from a form or from another PHP script it’s still coming from your server. If you’re uncomfortable with the script you could always populate a hidden form on the validation page with the fields and automatically submit that to PayPal on page load which would be identical to your existing setup.

I think that is not right, correct me if I’m wrong but,
If you look at the form in the first post of the thread (which I took from Pypal’s “minimum HTML Code needed” to post a request) you will see the action is


<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> 


So, when the user submits this, it doesn’t go through my server correct? The browser posts directly to Paypal at www.paypal.com/cgi-bin/webscr

If you’re uncomfortable with the script you could always populate a hidden form on the validation page with the fields and automatically submit that to PayPal on page load

I think this is not an option. If I create a hidden form that submits on pageload a malicious user could use an intercepting proxy to modify the request, and we are back at the same problem of the user changing the price or what he wishes.

You would still need to send the user with the POST request to PayPal.

Yes, a malicious user could still intercept the POST request and manipulate the values, however it’s more unlikely this way. The only way to completely foolproof the system is to create identical products within PayPal for them to match the values. If they don’t have an API for this, you’ll be doing it manually.

It’s just the nature of sending information from one server to another - encrypted or not.

It’s just the nature of sending information from one server to another - encrypted or not

But that is not sending information from one server to another. That is sending information from the server to the user and then from the user to another server.

And, I can’t believe this is just the standard procedure. There must be some other safer way.

Googling the Internet I found a PHP class that uses “Paypal’s IPN”, searching for that I arrived at the following page https://www.x.com/community/ppx/training

It seems there are a few payment methods that seem to be the answer to what I was looking for. I’ll be reading and will post my findings.

If you’re submitting a form to an external server (PayPal) from your server (and user) then you’re sending data that can be manipulated. The only foolproof way to handle this is to have the receiving server (PayPal) verify the data… which takes me right back to my original comment:

In this situation, PayPal is processing the submission so they are the only ones that can validate the information. Furthermore, they don’t know what’s possibly valid unless you tell them which goes against your requirement of creating a valid product within PayPal.

If you’re submitting a form to an external server (PayPal) from your server (and user) then you’re sending data that can be manipulated

It’s not my server submitting the form to Paypal. The process is:
My server formats and sends hidden form to user -> User clicks buy now -> User’s browser posts hidden form to Paypal (without it going to my sever at all, making it impossible to validate)

But, In the case it was as you say, my server posting the form directly to Paypal server, why do you say that is insecure? How is the user going to manipulate the data my server would supposedly be sending to Paypal?

So the obvious fix to the process is:

server formats and sends hidden form to user -> User clicks buy now -> User’s browser posts hidden form back to your server for validation and then passes it to Paypal.

So the obvious fix to the process is:

server formats and sends hidden form to user -> User clicks buy now -> User’s browser posts hidden form back to your server for validation and then passes it to Paypal.

No. because the user has to post the form directly to paypal’s URL https://www.paypal.com/cgi-bin/webscr so that they can enter there their address info or log in.

The only foolproof way to handle this is to have the receiving server (PayPal) verify the data… which takes me right back to my original comment

Anyway, after some reading about Paypal IPN payment, it seems they figured out a great solution. This is how the safe payment process is with Paypal:

  1. User submits unsecure hidden form directly to https://www.paypal.com/cgi-bin/webscr
  2. User Logs in Paypal account OR user enters address, credit card info, etc in Paypal
  3. Papal’s server submit’s the user request to your server to a page specially habilitated for IPN payments. Here you can query your db…
  4. Your server validates the user’s request, checking for correct prices, etc…
  5. Your server confirms or not to Paypal

This way the prices are in your db

That’s comparing two totally different things. If your PHP script does the validation and then passes control directly without displaying anything then your visitors will not even realise it is there.

I generally just use product codes in the HTML and convert them to a price on the server before calling Paypal. I then use an IPN script to onfirm that they haven’t changed the price once they get into Paypal and to send them an email containing their electronic goods purchase.

Paypal will accept information passed to it via POST, GET, or a socket call so you can easily pass the information you want to paypal regardless of what is entered in the form.