How to validate PayPal return data? - php

I'm integrating paypal and I have done it correctly. I have set the return URL, so it give me below result set in url $_GET.
Array ( [tx] => 7XV08083GT683520Y [st] => Completed [amt] => 22.16 [cc] => USD [cm] => [item_number] => item_number )
My concern is there is no way to validate the data that has returned from Paypal. I have experienced with other payment gateways. Other payment gateways allow you to do hashMatch which allows to make sure that submitted data by the form has been not edited.
My form is as below.
<form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr">
<!-- Identify your business so that you can collect the payments. -->
<input type="hidden" value="dasun_1358759028_biz#archmage.lk" name="business">
<!-- Specify a Buy Now button. -->
<input type="hidden" value="_xclick" name="cmd">
<!-- Specify details about the item that buyers will purchase. -->
<input type="hidden" value="AM Test Item" name="item_name">
<input type="hidden" value="22.16" name="amount">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" value="item_number" name="item_number">
<!-- Display the payment button. -->
<input type="image" name="submit" border="0" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif" alt="PayPal - The safer, easier way to pay online">
<img alt="" border="0" width="1" height="1" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" >
</form>
My php code output
<input type="hidden" value="50.16" name="amount">
But I used firebug and edited it to below & did the payment.
<input type="hidden" value="22.16" name="amount">
Still I get the result as it's a Completed payment but It should not be since I have made changes manually. Anyone who has a knowledge can edit them. How can I make sure that this is a valid payment ? How can I make sure that form data is not edited like I did ?

Anything that is critical and requires DB interaction should use Paypals IPN for data that MUST be verified. Essentially Paypal will Post the URL on your website with data and your script will have to post the exact data back plus a command to verify that the data is indeed correct. After Paypal gives an "verified" response, then you update your data.
Another alternative is using Paypal's express checkout, essentially you are getting an "ok" to charge a customer for "x" amount, once the customer agrees to pay the amount, you post the data to Paypal with the customers "agreement" and you will get a response if the transaction was complete or not.
https://www.paypal.com/ipn
https://www.x.com/developers/paypal/documentation-tools/express-checkout/integration-guide/ECGettingStarted

Before redirecing to paypal store your data in database (product_id, amount, quantity, etc)
After returning from payapl check the return values with your database.
This is the proper way of doing it.

If you want to notify whether you are returned from paypal than You should use Paypal API instead of "Buy now" button API provide more flexibility and power to control your payment process

You may try some of these:
1) Creating an Encrypted Button on the PayPal Website
2) Encrypting Buttons Dynamically With Encrypted Website Payments (EWP)
available at: http://www.paypalobjects.com/en_US/ebook/PP_WebsitePaymentsStandard_IntegrationGuide/encryptedwebpayments.html
Also, this SO link has some details:
Dynamic PayPal button generation - isn't it very insecure?

Related

PayPal Payment Integration with Dynamic Paypal Account

I have a website (built in Laravel) that allow merchants with a PayPal account to sell their items, which is similar to eBay with no cart function. However, I have issue on integrating PayPal into my website as I do not know what is the best way to ensure the data are correct. I have think of the follow method to implement, but it seems none of the are looking good for me.
Using JavaScript button
<script src="/js/paypal-button.min.js?merchant=MERCHANT_EMAIL"
data-button="buynow"
data-name="My product"
data-amount="1.00"
async
></script>
This is not secure as any user can tamper with the detail of the order such as price and there is no way to prevent this.
Using HTML form
<form method="post" action="https://www.paypal.com/cgi-bin/webscr" class="paypal-button" target="_top">
<div class="hide" id="errorBox"></div>
<input type="hidden" name="button" value="buynow">
<input type="hidden" name="item_name" value="My product">
<input type="hidden" name="amount" value="1.00">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="MERCHANT_EMAIL">
<input type="hidden" name="env" value="www">
<button type="submit" class="paypal-button large">Buy Now</button>
</form>
This method also have the same issue as method 1 as user can change the value in the form before submitting the order.
Using PayPal Hosted Button
By far, I think this is one of the secure way to integrate a PayPal Pay button into my website. But I cannot dynamically change the item details and price on my website as the button is hosted in PayPal.
Using PayPal IPN
The PayPal IPN is used to validate the payment detail after the payment is done by the user. As each of the merchant has different PayPal account, I could not configure the IPN url for each of their account. So passing notify_url variable while submitting the payment form are necessary to make sure all the payment detail are sent and returned to my dedicated IPN url.
I searched online and found most of the people are using this method to validate the fraud payment, but I think this is only suitable for payment to only one PayPal account instead of dynamic merchant's PayPal account. If I passed the notify_url variable in HTML form, the user can still tamper with the value which lead to the failure of validating the payment detail as the IPN url is not valid or tampered, and in the end the result would be either Payment Pending or Payment not received as I couldn't validate the payment details.
Is there a good solution or suggestion to my problem?

handling paypal payment in backend

I've got a custom form which makes a request to paypal. The problem with this is that people can edit this in inspector.
I've got the cart info into a cookie and database too. is there a way to first go to the back end, check all info there and then send it to paypal?
I've looked into IPN but don't understand it really. also my website is currently running on localhost so I need to set some ports open to get messages from paypal. which can't because I'm working on a network where I can't access the router.
I've tried send the form to the backend, compared it with the cart cookie & database. But I don't know if I can send the form in backend.
<div class="paypal pull-right">
<form name="_xclick" action="https://www.sandbox.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="[Business name here]">
<input type="hidden" name="currency_code" value="EUR">
<input type="hidden" name="return" value="http://domain/shop/paid">
<input type="hidden" name="cancel_return" value="http://domain/shop/payment_failed">
<?php
$i = 1;
?>
#foreach($cart as $item)
<input type="hidden" name="item_name_{{ $i }}" value="{{$item['name']}}" />
<input type="hidden" name="amount_{{ $i }}" value="{{$item['price']}}" />
<input type="hidden" name="quantity_{{ $i }}" value="{{$item['quantity']}}" />
<?php $i++; ?>
#endforeach
<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>
You could just create a hosted button and then people can't edit the info for the transaction. When creating the button in your PayPal account just make sure to use the "Save at PayPal" option.
EDIT You won't be able to use a hosted button because of your itemized, dynamic pricing, so Express Checkout is going to be your best bet.
I would recommend you switch to using the Express Checkout APIs instead of Payments Standard. It has quite a few advantages over Payments Standard, primarily the ability the force the guest checkout experience so non-PayPal account holders can easily pay with a credit card.
This PayPal PHP SDK will make the API calls very quick and easy for you.
Basically, you'll use SetExpressCheckout to start the process, then GetExpressCheckoutDetails to pull the buyer's details from PayPal after they've logged in, and then DoExpressCheckoutPayment to finalize the transaction and process the payment.
This method will also keep people from doing anything with the button code because it's all in PHP and API calls.
IPN is still a great tool, but you wouldn't need it to validate your pricing or anything like that (unless you just still wanted to for any reason).
It's a tool you can use to automate pretty much any post-transaction task. This includes payments, refunds, disputes, cleared e-checks, etc. So you can update your database, send custom email notifications, hit 3rd party web services, etc. automatically when transactions hit your PayPal account.

Run function only after paypal transaction success and redirected to my page

I am building an page with some items that I gonna sell through paypal. first I did generic buttons with fixed prices,after clicking you redirected to paypal page with your values like that:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" class="payPalBtn">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="test#gmail.com">
<input type="hidden" name="item_name" value="test">
<input type="hidden" name="button_subtype" value="services">
<input type="hidden" name="no_note" value="0">
<input type="hidden" name="amount" value="10.00">
<input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHostedGuest">
<input type="image" src="https://www.paypalobjects.com/he_IL/IL/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
But this is to dangerous because the client can change the amount value...and it can make some problems. So I chose using their API - this means, on server side sending some values like price,amount... ang getting back token id. After that sending this again with some data, and in the end the payment is transferred and every thing is closed. One of the parameters is: $PayPalReturnURL , this the page after success result, the user redirected to.
Now after I did that and verified that the payment pass I want to start an private program that do some private function (each time I run it it cost me money) that should be done only once, after the payment passed. The page I redirect is for example : payment.php, and there I simply start my function.
The question is: how can I be sure that the user wont go straight to that PHP address and automatically start this function. what are my options guarantee that this function would run only once after paypal redirect to me.
You are making it complex. Here is how I did paypal integration.
Alone with the input price send the transaction no in a hidden field as below.
<input type="hidden" name="amount" value="10.00">
<input type="hidden" name="tx_id" value="1234">
Before generation this form insert a database record with the status of the transaction as pending as below.
tx_id = 1234
amount = 10.00
tx_status = 0 // pending
When the transaction is complete paypal will return amount, your tx_id and status of the transaction. Using a SELECT query you can check whether returned amount is the same amount whether in the database table.
SELECT amount FROM table_name WHERE tx_id = 1234
Then If it's correct change the tx_status to paid. Else mark it as fraud.
To protect your button you could either setup a hosted button through Payments Standard or you could integrate the Express Checkout API if you're familiar with using web services.
As for the automated post-order processing you won't want to do that on your return URL. There is no guarantee that page will get hit even with Auto-Return enabled in your PayPal account. If the buyer closes their browser before that redirect happens your code will never run and your automation will not work correctly.
To avoid this, and to protect from people going directly to your return URL, you can utilize Instant Payment Notification. This will be triggered with every payment regardless of whether the user makes it back to your site or not, and you can verify the data with PayPal to ensure it actually came from them so people can't try to be sneaky with your IPN script.

Which user subscribed to my site via PayPal?

I have been developing a website with PHP in which users will subscribe and pay their subscription fees monthly to resume their memberships. To do this, I created a Subscribe button from PayPal and tested it with sandbox, I can receive the payment. However, I couldn't find a way to determine which user have subscribed.
Here is the HTML code for the PayPal button:
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="BUTTONID">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
As you can guess all users have unique IDs, I want to pass this unique ID to the PayPal page where payment is done then PayPal will pass this ID to me again, therefore the users account will be activated.
I have been searching for this for a very long time. There are many tutorials to do it with IPN but I can't see where to send the user id as an IPN parameter. I haven't managed to use PayPal APIs since their documentation is totally crap.
Maybe someone can give a link with a complete tutorial for this, or tell me what I understood wrongly?
Thanks
As far as I know, you can add up to 255 bytes of data to field labeled CUSTOM in just about every request to PayPal. PayPal returns this field in its responses and IPN's.
For something like subscriptions, I would recommend you to checkout the recurring payment mechanism offered by PayPal via NVP and SOAP. It is not that easy as just generating a button and placing it on your website but since you already wrote an entire website in PHP, you will not have any problems coding it. Recurring payments should provide everything you need to let your users subscribe and pay a monthly fee, including the ability to track who is who.

PHP verify PayPal Donation

How can I verify a paypal donation?
In the user panel I have a donate button. And once someone actually donates I want to do something to him. But I do not know how to check if the user actually donated or just clicked the donate button.
Look in to Paypal's IPN (Instant Payment Notification)
When someone makes a payment or donation to your Paypal account, Paypal will send a post message to your web server with all the payment details. You can then send a message back to Paypal to make sure that the payment was real...
There are even some code examples on paypal's website. Including one for PHP.
Note you have to enable IPN and define the call back URL in your paypal account before you can start using IPN.
It's in the same manual. It may be a bit tougher to do however, as you will need a PHP script that receives the payment info.
Return URL – Let people return to a page on your website if they
click a return link or button on the
PayPal payment confirmation page.
To learn more, see Step 2 of Page 2 – Specifying Advanced Features
of Your Donate Button or HTML
Variables for Displaying PayPal
Checkout Pages.
Auto Return – Have PayPal return people automatically to a page on your
website.
Important: PayPal recommends that you turn Payment Data Transfer on
when you turn Auto Return on. With
Auto Return on, PayPal redirects
people to your website from an
alternative PayPal payment
confirmation page that does not
display a View Printable Receipt link,
so people cannot print PayPal payment
receipts. Payment Data Transfer
provides the transaction information
that you need to let people print
receipts from your website.
To learn more, see Auto Return.
Payment Data Transfer – PayPal includes information about the
completed transaction when you use a
return URL or Auto Return to send
people back to your website. Use the
information that Payment Data Transfer
provides to display a “thank you,
print your receipt” page on your
website.
To learn more, see the Payment Data Transfer page on Developer
Central.
There are two way to check donor made donation:
1) used "notify_url" parameter (safe)
2) used "return" parameter ( unsafe)
Code example:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<!-- Identify your business so that you can collect the payments. -->
<input type="hidden" name="business"
value="donations#kcparkfriends.org">
<input type="hidden" name="bn" value="mbjtechnolabs_SP">
<!-- Specify a Donate button. -->
<input type="hidden" name="cmd" value="_donations">
<!-- Specify details about the contribution -->
<input type="hidden" name="item_name" value="Friends of the Park">
<input type="hidden" name="item_number" value="Fall Cleanup Campaign">
<input type="hidden" name="amount" value="25.00">
<input type="hidden" name="currency_code" value="USD">
<!-- Display the payment button. -->
<input type="image" name="submit" border="0"
src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif"
alt="PayPal - The safer, easier way to pay online">
<img alt="" border="0" width="1" height="1"
src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" >
</form>
When some one made donation donor automatically redirect to return url but this option is not safe because may be some one direct open this url.
best way to know donor made donation choose paypal notify_url parameter.
PayPal will send post request to notify_url.

Categories