I have already seen a few questions like this. But I wanted to get an overall opinion on some of these questions, combined!
I understand how IPN works and how you can listen to make sure it comes from paypal.
My main wonder is if I am going to dynamically generate paypal buttons using the code:
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="me#mybusiness.com">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="item_name" value="Teddy Bear">
<input type="hidden" name="amount" value="12.99">
<input type="image" src="http://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif" border="0" `enter code here`name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
From the paypal developer site: https://www.paypal.com/cgi-bin/webscr?cmd=_pdn_xclick_techview_outside
Is it safe to use this? I was reading up on another post saying it is unsafe since the variables can be tampered with. Do I need to encrypt the form?
Cheers,
Nick
I'm just going to answer my OWN question. The solution is to just compare the "item_name" and "amount" variables and make sure they are exactly the same if say I generated using a database. And if someone tampers it and pays me $1.00 instead of $100.00 then thats a free donation and bad luck for them :P
What I will be doing is this:
Create a database to store item name, amount, currency etc.
On the shopping page I will dynamically generate it using the item_name and amount
Set up my paypal to send transactions made to the IPN listener that I will make
Using the database to compare the item_name and amount, it will validate whether it is a valid form submission or not.
Simple! I like it! WOO!
Related
I've been looking through the following PayPal guide (as it's the only available document I could find that details PHP implementation AND can handle basket/cart/multiple purchases):
https://www.paypal.com/mk/smarthelp/article/how-do-i-add-paypal-checkout-to-my-custom-shopping-cart-ts1200
I'm however thinking that something is seriously wrong. It suggests sending payment information in hidden form inputs, like so:
<input type="hidden" name="cmd" value="_ext-enter">
<form action="https://www.paypal.com/us/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="you#youremail.com">
<input type="hidden" name="item_name" value="Item Name">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="amount" value="0.00">
<input type="image" src="http://www.paypal.com/en_US/i/btn/x-click-but01.gif" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
But that seems seriously wrong. Can't a website user remove the "hidden" property using basic tools and then manipulate the price to whatever they want? Or edit the price directly?
I understand that the merchant would then receive an invoice with an incorrect price and would have to double check it and cancel the order if necessary, but surely that is not standard practice? Because if large numbers of users attempt to abuse this exploit and therefore cause a large number of cancellations, would such a thing cause PayPal to terminate it's services with the merchant?
I have found the following documentation also:
https://developer.paypal.com/docs/platforms/checkout/set-up-payments/#step-1-add-payment-buttons-to-accept-payments
This seems to be using a completely different method, but this is in Javascript and doesn't support basket/cart/multiple purchases. It also would seem to have the same problem, in that someone could edit the JavaScript to manipulate the price (if I'm not mistaken).
So is the initial method just standard practice and I should follow that, or is there an alternate more secure method that I have been unable to find?
Recommended solution:
Front-end code: https://developer.paypal.com/demo/checkout/#/pattern/server , which will call two routes on your server, one to 'Set up Transaction', and one to 'Capture Transaction'.
You will need to create those two corresponding server-side routes, each of which will call the PayPal API directly (and securely). Guide for implementation: https://developer.paypal.com/docs/business/checkout/server-side-api-calls/#server-side-api-calls
I'm configuring a PayPal IPN listener from this tutorial and ipnlistener.php.
When I need a user to pay, I show him this form
<form name="_xclick" action="https://www.sandbox.paypal.com/cgi-bin/webscr"
method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="<? echo $myPaypalEmail; ?>">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="item_name" value="Digital Download">
<input type="hidden" name="amount" value="<? echo $price; ?>">
<input type="hidden" name="return" value="THIS URL">
<input type="hidden" name="notify_url" value="myhost.com/ipn.php">
<input type="image" src="http://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"
border="0" name="submit">
</form>
Following the guide, I correctly receive a POST request to the file ipn.php. I receive a lot of useful data about the payment but my problem is: how can I know which user made the payment?
A "user" is a person registering on my website, giving me personal informations and his/her email address. How can I connect these informations to the POST request I receive back from PayPal? The email used to register on my website may be different from the one used in PayPal.
I can think of 2 solutions:
a) Place a unique user id in the return URL, parse it with $_GET and then... This could hardly solve the problem.
b) Get the payment ID as soon as the transaction starts. But I have no idea on how to do that.
As you can see, my problem is to associate a user with the transaction id. The workflow is:
HTML Form -> Paypal website -> ipn.php
HTML Form has user info while ipn.php receive transaction info: I need the user info to go into ipn.php in order to check if the total has been correctly paid and to perform stuff on the user account. How can I do this?
Many thanks.
You could also pass the user ID in the "custom" field. This can be literally anything you want, up to 255 characters. This gets passed to Paypal and is sent in the IPN response as well. I use this field to distinguish between my various databases when I am storing IPN data.
Hope this helps.
<input type="hidden" name="item_number" value="UNIQUE_USER_ID">
item_number allows to pass any arbitrary numeric values back and forth. I can use this to identify the user from the payment. $_POST['item_number'] will allow to see this value in the ipn.php file.
I'm building a simple shopping cart using PHP and I want to be able to use paypal with it. I want to use the tools described here:
https://www.paypal.com/cgi-bin/webscr?cmd=p/pdn/howto_checkout-outside
This seems to be the easiest way to go about doing this. I looked over at their development page, and was really confused, but this made sense. My only problem is with this I have been told that it's fairly easy to change the prices. Now I could run a script to check the return from paypal to check to see if their order price matches their cart total, but I want to stop this before it happens. The one thing I did take from the development site was their token call. Would I be able to build a function that creates the buy now button by providing all the items through the method above, and then making a token call to link the id of those items and prices to the button? I'm just a bit confused, a lot of people have said to look at the documentation, but I'm having a difficult time understanding all of it so any help is really appreciated.
You just pass the variable that has the total to paypal
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="you#youremail.com">
<input type="hidden" name="item_name" value="Item Name">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="amount" value="$TOTAL">
<input type="image" src="http://www.paypal.com/en_US/i/btn/x-click-but01.gif" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
If you want to stick with Payments Standard you can u se the cart upload method to send all of the info over to the PayPal checkout.
If you're comfortable with PHP, though, I'd recommend using the Express Checkout API. This will free you up to a lot more with your checkout experience.
You might want to check out this PHP class library for PayPal. It makes this very simple for you. With that library it's just a matter of knowing which API calls to make and then using the included files to pass in your own data accordingly.
For Express Checkout you would be using SetExpressCheckout, GetExpressCheckoutDetails, and DoExpressCheckoutPayment.
I have built a product generation and display plugin for the Wordpress CMS and I am now trying to integrate some form of PayPal integration for the checkout process.
I have the cart, the products, the shipping, totals, all that figured out on my end and I was hoping someone could point me in the simplest direction of sending this information to PayPal. I understand some methods of doing this are not that secure and others make you jump through hoops like some sort of show dog. I've been trying to learn how to use cURL and then how to get it to work with PHP - it really seems like a bit of a mess. I do now have cURL working on my WAMP server ... but..
Is there a better way or should I continue to learn cURL?
I can format the data however it needs to be to send off to PayPal and would not mind doing this with JavaScript - this is not a pay-wall and every order is checked for accuracy by a human - so someone messing with the client-side script will not bother me. I also definitely want to send them to PayPal, I want no part of storing/processing their credit card information. It would, however, be nice to have IPN. Can someone point me in the right direction or assure me that I already am headed that way?
Thanks alot.
This is how i automatically redirect to PayPal with all the form details;
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" id="paypal">
<input type="hidden" name="cmd" value="_xclick" />
<input type="hidden" name="cbt" value="Return to example" />
<input type="hidden" name="business" value="email" />
<input type="hidden" name="item_name" value="example Purchase" />
<input type="hidden" name="amount" value="9.99">
<input type="hidden" name="button_subtype" value="services" />
<input type="hidden" name="no_shipping" value="1">
<input type="hidden" name="return" value="URL" />
<input type="hidden" name="notify_url" value="URL"/>
<input type="hidden" name="cancel_return" value="URL" />
<input type="hidden" name="currency_code" value="USD"/>
<input type="hidden" name="image_url" value="" />
<input type="hidden" id="custom" name="custom" value="invoice_id to track"/>
<input type="hidden" class="btn btn-primary" style="width:100%" alt="PayPal - The safer, easier way to pay online!"/>
</form>
For multiple products, you can simply add more products to the form, example;
<input type="hidden" name="item_name_1" value="Item #1">
<input type="hidden" name="amount_1" value="1.00">
<input type="hidden" name="item_name_2" value="Item #2">
<input type="hidden" name="amount_2" value="2.00">
However, using this method is not all great
All the data would need to be generated with PHP and input into the page, you would also need to check the transaction when the IPN calls back to ensure its been paid.
<script type="text/javascript">
function myfunc () {
var frm = document.getElementById("paypal");
frm.submit();
}
window.onload = myfunc;
</script>
You may want to use the new PayPal
SDK. They have a good set of sample code,
including code for express checkout and IPN.
Try here
https://www.x.com/developers/paypal/documentation-tools/paypal-sdk-index
Get the SDK for Express checkout. At this
time, they should be at SDK 98 for PHP.
You won't have to worry about the Curl,
the SDK takes care of all that for you.
A typical call might be something like this.
$setECResponse = $paypalService->SetExpressCheckout($setECReq);
This line of code is modeled after the samples. It's
all object oriented. They provide you with classes.
In this case there is a request object you fill out,
the examples show exactly how to do it; just use the
samples as your template.
It sounds like you want to do PayPal Express checkout,
this way you won't have to handle credit cards or anything
like that. The user is redirected to the PayPal website
and all the financial transactions happen there. The
user is redirected back to your site. Then you have a
page where the user can review the order and click
submit if they approve. When the user clicks submit,
you call a PayPal API telling PayPal that the transaction
is approved. PayPal then executes the transaction and
sends you back a confirmation with a transaction id.
You can then call getTransactionDetails and display the
confirmation to the customer. You can additionally put
those transaction details into a database.
Here are the APIs you can call for this. These
are modeled closely to the sample code they provide
$paypalService->SetExpressCheckout($setECReq);
control goes to PayPal URL, and the user goes
through a few pages there. control returns to you.
your order review page
$paypalService->GetExpressCheckoutDetails($getExpressCheckoutReq);
your order confirmation page
$paypalService->GetExpressCheckoutDetails($getECReq);
$paypalService->DoExpressCheckoutPayment($DoECReq);
Tells PayPal to do the transaction.
$paypalService->GetTransactionDetails($request);
Here you can put transaction details into a database.
You can also send yourself a mail with all the details,
that way you will know whenever a transaction occurs.
IPN can be a bit tricky. There is a sample IPN listener
that they provide, that will help. You will need to
set up your listener URL on the PayPal website. You will
also need to set up an SSL certificate.
The SDKs are fairly new, but PayPal is working on an even
newer way to do things, developer.paypal.com. It just came out
within the last month or so. You may want to look into that too.
What's the best way to dynamically generate an "Add to Cart" PayPal button in PHP? My idea is to take the basic HTML code and simply echo the required variable but I'm not sure if it's the most secure way...
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="me#mybusiness.com">
<input type="hidden" name="currency_code" value="NZD">
<input type="hidden" name="item_name" value="<?=$name?>">
<input type="hidden" name="amount" value="<?=$price?>">
<input type="image" src="http://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif"
border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>
(Code above from PayPal's Advanced Techniques page)
Doing it that way isn't very secure because people can still view source and see the end-result on your page. Then they could take that, make changes to it, load it in their own browser and pay you for an item at a much lower price.
You can utilize IPN to help flag orders that don't look accurate by cross-references your pricing, but this can be a hassle.
You could use the Button Manager API to generate your buttons as hosted buttons on PayPal. This way people can't see the details in the source code and wouldn't be able to make changes.
Alternatively, you could use the Express Checkout API which is what I prefer and recommend if you know how to work with web service API's.