Matching user email with PayPal email from IPN - php

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.

Related

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.

Easier way to integrate PayPal express checkout?

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.

paypal - notify_url on transfer between two personal accounts

working on an auction site using phpprobid software and come to the point of integrating paypal payments for buyers to pay sellers for items. the form is like the code below, i can see the money being transferred from the buyer to the seller but the notify_url callback is not being run. the notify_url (used to mark item as paid for and other db operations) is accessible, not on localhost. are notify_url's called between two personal accounts? all the documentation only talks about personal to business transactions; does that mean to allow users to sell items and accept payment via paypal they need a business account?
this process worked in the sandbox so i know there are no errors in the script at notify_url, but there you need a simulated business account so this wasn't an issue. i've added some mail() calls to the notify script so i can see it isn't actually running. the transfers work and the return url appears after so that works too.
<form action="https://www.paypal.com/cgi-bin/webscr/" method="post" id="form_paypal">
<input name="submit" type="submit">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="bn" value="wa_dw_2.0.4">
<input type="hidden" name="business" value="Business Name">
<input type="hidden" name="receiver_email" value="paypal#SELLERSBUSINESS.com">
<input type="hidden" name="amount" value="SOME_AMOUNT">
<input type="hidden" name="currency_code" value="A_VALID_CURR_CODE">
<input type="hidden" name="return" value="OURSITE/RETURN_URL">
<input type="hidden" name="cancel_return" value="OURSITE/FAILED_URL">
<input type="hidden" name="item_name" value="DESCRIPTION_OF_ITEM">
<input type="hidden" name="custom" value="VALUE_TO_BE_SPLIT_FOR_SPECIFIC_DATA">
<input type="hidden" name="notify_url" value="OURSITE/CALLBACK_SCRIPT_URL">
</form>
tl;dr... if a paypal transaction is between two personal accounts, is the notify_url called?
IPN can be used with any type of account. Are you absolutely sure it's not actually getting POSTed but your script has an issue so you don't see the result?
You need to confirm this by checking your PayPal IPN History and your web server logs.
If PayPal IPN History shows nothing then you know the IPN's aren't getting sent at all. If it shows a 200 OK you know it's getting sent and your server is returning a successful response that the script completed without error. If you see anything other than 200 OK you know there is an error happening with your script. You can check your web server logs to find the exact error.
You could also build yourself a simple test form with hidden variables that match what you expect to get from PayPal. Set the action of this form to your IPN listener and POST it directly. This way you can see the result on screen and this can help troubleshoot your issues.
Just keep in mind that when testing this way the data isn't coming from PayPal, therefore, the validation will fail. You can adjust your code to handle this accordingly for testing purposes.

Paypal dynamic button and Linking with IPN

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!

Link PayPal "Donate" button to Wordpress "Post Comment" button

I am using a Wordpress template to serve as a system to collect verbal bids, really post comments, that will cost visiters to the site $1 to make. I've changed the standard "Post Comment" text at the end of posts to "Submit Bid".
I've also installed a PayPal donation plugin that displays a "Donate" button on the page.
I want to combine the functionality of both of these buttons into one button, the "Submit Bid" button. To be clear, the Submit Bid button posts the user's comment to the post page; I need a button that does this while simultaneously directing the user to PayPal to donate the $1.
Ideally, I'd have a check in place to verify that the user actually paid the $1 in order for the bid to be submitted, but since this is more complicated, and because this is for charitable purposes, I am putting faith in my users to actually pay. After the donation, PayPal will redirect them to the page to which they submit their verbal bid ("comment").
The php for the "Submit Bid" button looks like (it's from the standard "comments.php of the typical wordpress blog):
<input type="submit" value="Submit Bid" /><input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" />
The PayPal "Donate" button is a plugin actually placed on the page as a function:
<?php echo Paypal_payment_accept(); ?>
The function code is quite long, but the code placing the actual "Donate" button on the page is:
$output .= "<input type=\"image\" src=\"$payment_button\" name=\"submit\" alt=\"Make payments with payPal - it's fast, free and secure!\" />";
Would greatly appreciate thoughts on how to solve this seemingly trivial problem!
Actually, there might be a simpler way, rather than using the Paypal submission using a form.
Keep the redirect code, but edit the $location variable to be the URL that takes the user to paypal, with all the variables you want to send to them,
eg:
https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=email%40paypalhacks%2Ecom&amount=1%2E00&currency_code=USD&item_name=donation&item_number=1001&quantity=1&shipping=3%2E00&no_shipping=0
So it will process the comment normally, and then send the user to the paypal page to make the payment. You can go to that URL in your browser to check it works. Probably add a 'return' variable as well to send the user back to the original $location value, so the user will get to the comment page upon successful payment to paypal.
You basically want one button, to perform 2 actions. So rather than having two forms (paypal plugin will add its own form tag), why don't you add the paypal redirecting functionality either before or after the comment processing code?
So when the user presses the submit button on a comment, let the page process the submission normally, but in that file, after it processes the comment, redirect the user to paypal.
You can change the code in wp-comments-post.php file, which is in your root Wordpress folder.
You need not use a plugin for this, its a pretty simple paypal code:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="<!-- paypal user email which receives payments -->">
<input type="hidden" name="lc" value="CA">
<input type="hidden" name="item_name" value="<!-- donation -->">
<input type="hidden" name="item_number" value="1">
<input type="hidden" name="amount" value="<!-- donation amount -->">
<input type="hidden" name="currency_code" value="CAD">
<input type="hidden" name="return" value="<!-- the URL to redirect the user after payment -->">
<input type="hidden" name="button_subtype" value="services">
<input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHosted">
<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"><br />
</form>
Also, you could moderate all comments, so they are not published on the website until approved by a moderator. You can manage these settings in Dashboard > Settings > Discussion. This way, you can choose to approve comments only for users who have successfully made a payment through paypal (by comparing their email IDs).

Categories