PHP Confirming a Secure Paypal payment - php

I have a website providing a product such as an EBook. Initially i was configuring the site to use Paypal's basic payment processing.
The user would:
Register
Make an order
Proceed to paypal checkout
Return to a site page (after successful payment) containing a download link.
I had this in place but then spotted a glaring issue. The return url upon successful payment is stored in a hidden input; as such, a user could simply view the source of the page, take the return URL and traverse to it. Even if i pass a validation token, it wont prevent the issue as no matter what i do, the user can see the URL.
I have looked into using the IPN service and i can see this will provide me with a way of confirming if a transaction has been accomplished.
My questions is: How would i approach securely confirming a registered user has paid before providing either a URL download link or simply an email containing the ebook.

You answered it yourself. IPN is what you want. When a transaction takes place you'll get an IPN with data like txn_type, txn_id, payment_status, etc. If you check the payment status within this script and it's completed then you know you can deliver the link. If not, deliver a different message accordingly.
For example, if somebody pays with an e-check you'll get an IPN with a payment_status of pending. You could have your IPN script generate an email that says "thanks for your payment, it is currently pending. As soon as it clears you will receive your download link."
Then when it does clear (or fail) you'll get another IPN with an updated payment_status but the same txn_id. If the status is completed at that point it would generate a completed email, or if it failed, a failed email, etc.
There are all sorts of cool things you can do within IPN to automate tasks based on transactions.

If you want it to work over PDT, then Why don't you Save button at PayPal - all you'll get is a button code in the form. here's how:-
and the button code will look something like:-
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="N3AAAFZTMQ7S">
<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>
Your return URL (where from users can download stuff) will not be shown anywhere. Everything will be stored in the button configuration at PayPal servers and will be tied to the button id.
Otherwise, as Andrew suggested, you can always use IPN or PDT+IPN.

Related

Do I receive callback from Paypal buy now button for all events?

I am currently testing the buy now button on a PHP website. Here is the code I have (more or less) :
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="encrypted" value="........"
<input type="image" src="https://www.paypalobjects.com/fr_CA/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - la solution de paiement en ligne la plus simple et la plus sécurisée !">
<img alt="" border="0" src="https://www.sandbox.paypalobjects.com/fr_CA/i/scr/pixel.gif" width="1" height="1">
<input name="notify_url" value="https://www.example.com/paypal_notifications.php" type="hidden">
</form>
The sandbox transaction is working (sending complete) but I don't know if I will get only a one-time message or updates.
Do I receive an event if the payment is revoked ― say ― a week later? (Is there a way to immediately revoke a payment from within a sandbox account?)
I am using only notify_url and not the IPN setting in the account because the account is used with more than one website (and I couldn't find it... :P).
The notify_url setting in a Web Checkout form overrides the profile IPN URI, so if a form doesn't specify a notify_url then the profile value will be used, but if a form does specify an address then the profile value will not be used. I appreciate this is confusing because the PayPal Profile page (where you specify the default IPN address) does not mention this, neither does PayPal's own documentation.
(To further frustrate things, PayPal's documentation still has screenshots and text describing the old (2005-2015) account management pages, they still haven't updated them).
Note that despite the name "Instant Payment Notifications", the messages are not actually Instant - in my experience there is a lag time of between 15 seconds and (rarely) up to 2 minutes before my code receives an IPN message. For this reason if you really need instant notification you should also use PDT to augment your IPN handler. PDT is where PayPal's web checkout process will redirect your customers back to a custom URL with an opaque Transaction ID in the querystring, which you can use to retrieve the actual transaction details in your own code when you handle the incoming request from the returning customer.
The IPN system is now decades-old, dating back to the late-1990s - consequently its design is a bit strange, and you will, in fact, receive multiple notifications for the same transaction - but it depends on the type of transaction. This is documented in PayPal's IPN documentation, but again, they don't give you all of the details and in many cases you have to learn through trial-and-error.
For example, if it's a straight-forward Web Checkout using PayPal's own checkout pages and the customer is paying with a credit card or PayPal account balance then you'll get a single notification informing you the transaction was successful and that's it. However if a customer pays by US ACH (aka eCheck) then you will receive multiple notifications because the clearing process takes a while: you'll first get an initial notification that a payment was made, but that it hasn't cleared yet, then you'll get another notification 2-3 days later notifying you if the payment cleared successfully (and your PayPal account actually has the funds) or if it failed.
I don't personally recommend using the PayPal Sandbox for more than trivial exercises because it fails to simulate all possible scenarios in real-life, and it's a pain to set-up. How seriously you take testing depends on how critical this code is to your business.
In short, and for PayPal in particular, don't be afraid to test-in-production, and make sure your code gracefully handles unusual messages and I strongly recommend recording and saving every incoming IPN message so you can get a better "feel" for the data you can process - again, because PayPal's documentation is lacking in many areas.

using paypal button - can my webpage tell if paypal transaction was successful or not?

I am using joomla and have brought a component which allows users to post listings on my site. The plugin uses a credit system to pay for the listing but the credit system is quite complex and confusing so i have disabled it.
I found that PayPal provides some code which inserts a Buy Now button on any webpage :) perfect, just what i wanted!
The only problem I am having is at the moment the button is displayed on my Add Listing form (which is again part of the component) but it can easily be bypassed by just clicking on the form's submit button, meaning the listing can be published without having to pay.
So my questions are:
Once the user clicks on the Buy It Now button is it possible to
redirect them back to the 'Add Listing' form they were just filling
out?
Can I disable the submit button on the form until the payment has been
confirmed?
Does the PayPal 'Buy Now' button return any information
confirming the process was successful?
i am using html + php :)
the code i used to produce the buy now button is
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="smyacc#hotmail.com">
<input type="hidden" name="lc" value="GB">
<input type="hidden" name="item_name" value="listing-purchase">
<input type="hidden" name="amount" value="2.99">
<input type="hidden" name="currency_code" value="GBP">
<input type="hidden" name="button_subtype" value="services">
<input type="hidden" name="no_note" value="0">
<input type="hidden" name="shipping" value="0.00">
<input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHostedGuest">
<input type="image" src="https://www.paypalobjects.com/en_US/GB/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_GB/i/scr/pixel.gif" width="1" height="1">
</form>
would really appreciate any help with this!!!
Luke
Good news - the answer to your questions is essentially yes. Your end goal is definitely doable, but in order to really solve your problem in its entirety, we may need a little bit more information.
How you go about it can vary from case to case, however, and unfortunately it's been a while since I configured these buttons, so bear with me ;-)
once the user clicks on the buy it now button is it possible to redirect them back the the add listing form they were just filling out?
Yes, this is a very standard functionality that PayPal has built into their buttons and their process. What you are looking for here is what PayPal calls "Return URLs" or "Auto Return". Here's the page with more of the documentation I quoted below so you can decide whether the Return URL or the Auto Return or the Payment Data Transfer option is best suited for you.
Returning buyers to your website after they check out
The basic checkout experience leaves buyers on the PayPal website
after they check out. Use one of the following techniques to enhance
the checkout experience so that buyers return to your website,
instead.
Return URL: Allow buyers 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 item #5 under Step 3: Adding advanced features to
your Buy Now button or HTML variables for displaying PayPal checkout
pages.
Auto Return: Have PayPal return customers 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
buyers to your website from an alternative PayPal payment confirmation
page, which does not allow them to print PayPal receipts. Payment Data
Transfer provides the transaction information that you need to allow
buyers to 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 customers
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.
Question Can I disable the submit button on the form until the payment has been confirmed?
Certainly. To disable the submit button on the form until the payment has been confirmed, simply do one of two things until you can detect that the payment has been confirmed:
Add the 'disabled' attribute to the Submit button. This will grey out and disable the Submit button, rendering it unusable. However, since the button would still be visible and all, a web-savvy end user might just go into the HTML and remove the disabled attribute and be on his merry way.
<button type="submit" disabled>Submit Listing</button>
Hide the Submit button. In this case, the web-savvy end user could technically still go into the HTML and remove the styling so that the button is visible, but without seeing it...well, you know, 'out of sight, out of mind'
<button type="submit" style="display:none">Submit Listing</button>
Question Does the PayPal 'Buy Now' button return any information confirming the process was successful?
Again, there's a few ways of attacking this.
Method 1 The simplest way might be to use the PayPal Return URLs and some GET parameters to tell you whether or not things were completed or cancelled. There is something like a Return URL for Cancellations and a Return URL for Completions. From that same page that I linked, PayPal documents the creation of a button with respect to this feature:
Take buyers to a specific webpage (URL) after checkout cancellation
(optional)?
Select the checkbox and enter a URL in the text box if you have a
special page on your website where you want buyers to return to if
they cancel their checkouts before completing their transactions.
Take buyers to a specific webpage (URL) after successful checkout
(optional)?
Select the checkbox and enter a URL in the text box if you have a
special page on your website where you want buyers to return to after
they complete checkout successfully.
Method 2 The more advanced way (which is also more foolproof, given that in the first Method a hacker could try and guess your Successful Return URL) is using PayPal's Instant Payment Notification feature. With this feature, PayPal sends a POST request to a private (behind the scenes) URL which allows you to capture the data it sends you pertaining to the payment completion.
So your backend receives the information on the completion of the payment, and there are countless ways (AJAX requests, require the user refresh the browser or send the user an email telling them to come back and finish it, etc) that you can go about updating the frontend for the user so that they can use the now visible/enabled Submit button.
For details and documentation on PayPal's notify_url through their IPN system.
Best of luck!
I think you will find PayPal supply merchant scripts which will do something like that. Instant Payment Notification under PayPal settings - only available in a business account.
The php scripts you can download can be customised to do pretty much whatever you want once they return from payment. On a successful purchase you can echo the submit button so that it is physically not present unless they are returning after payment echo '<input type="submit" name="submit">';
Under "Tools and Settings" "Process My Orders"
You then need to make adjustments in the PayPal merchant interface to return the user to your IPN script.

Paypal Security Flaw?

I have a the following form at the end of a booking process (simplified):
<form action="https://www.paypal.com/cgi-bin/webscr" name="paypalForm" method="post">
<input type="hidden" name="amount" value="<?=$price;?>">
<input type="hidden" name="business" value="business#email.co.uk">
<input type="hidden" name="notify_url" value="http://website.co.uk/ipn">
</form>
I have only left out things like address name etc. So when they pay via Paypal, I am using paypal IPN to mark them in the database as paid. However..
I have gone to the end of my booking system and viewed source of the webpage, modified the business email address and amount. I haven't tried a full transaction yet, but surely with the 'notify_url' in there Paypal with send an IPN message to my server and will mark the person off as paid? Isn't this terrible security? Surely this not how all paypal payments work, I must be missing something.
There are two things I can think of that might prevent this:
If I remove the "notify_url", will the IPN URL that I have set in paypal work instead? What value does paypal place on the hidden var notify_url, does it override the settings in the back end of paypal?
In my IPN code I could check for business and Amount. I don't currently, as I didn't read any where in the documentation that I should. But now, I am thinking that maybe it would be a terribly good idea.
There isn't any check that can be done by PayPal to know what the correct amount, or email address should be that was used, or that the IPN URL should only be used with a particular PayPal account. Your options would to be write in the additional checks like you have already mentioned. In additional to what you already stated about your 2 workarounds, a 3rd option would be to create a hosted or encrypted button on the fly using PayPal's BMCreateButton API. Then the buyer would only see the encrypted button code, they would not be able to view your HTML button code. Therefore they would not be able to modify any of the variables, or see what they are currently set to.

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