I want to integrate Paypal in my site using Express Checkout and notify_url parameter which would notify my site and accordinly I can take actions.
I generated buynowbuttons. Sample buy now button is:
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<input name="notify_url" value='http://localhost:9000/Home/ProcessPayment' type="hidden"/>
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="something@something.com">
<input type="hidden" name="lc" value="US">
<input type="hidden" name="item_name" value="Basic">
<input type="hidden" name="amount" value="24.99">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="button_subtype" value="services">
<input type="hidden" name="no_note" value="0">
<input type="hidden" name="tax_rate" value="0.000">
<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.sandbox.paypal.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.sandbox.paypal.com/en_US/i/开发者_Python百科scr/pixel.gif"
width="1" height="1">
</form>
I added <input name="notify_url" value='http://localhost:9000/Home/ProcessPayment' type="hidden"/>
so it can notify my action method in my controller for debugging purpose. However, it is not working.
I get redirected to Paypal account :
https://www.sandbox.paypal.com/us/cgi-bin/webscr?cmd=_flow&SESSION=somesession&dispatch=somedispatch
But once the payment is completed it never hits my breakpoint in ProcessPayment action in Home controller. Is there something that I am missing?
Thanks in advance :)
UPDATE:- I had hidemyass pro account and all I had then was to setup my website in IIS and then my notify_url worked like a charm ;).
In usual cases your breakpoint will never be hit in this case, and that's normal, because:
If you don't have a "direct" external IP-address ( and you will AT LEAST have a router ) or you have configured everything to perform correct NAT port forwarding, the PayPal IPN will go either to:
1) Nirvana, because you have not configured the IP address correctly
OR
2) To your Testserver/Productionserver which IP-Adress for IPNs you actually configured.
UPDATE:
There are 2 Solutions:
- Set the PayPal IPN listener to your external address ( maybe your homerouter or your companyrouter ) and configure the NAT or ask your admin to do it
OR
- Use the Remote debugger on your live/test system, to attach to the iis-process and hit the breakpoint.
I personally would tend to solution 1., because i never got the remote debugger to work like i expected..
It is because they create their own HTTPRequest to that URL, and it is not part of your session.
They will try to contact your localhost:9000 from their server, and this URL doesnt exist to them.
You will need to put in some logging to check what happens when they talk to this URL, e.g. log that they have reached the page, and what happened in the code. Then put this page "Live" somewhere for PayPal to talk to.
see below a few comments that I believe will help you resolve this problem:
1 - the notify_url needs to be an url that can be accessed from PayPal. It should be something like http://www.example.com/path/to/your/script. This is the url PayPal will post to with the results of the transaction.
2 - You will need a way to identify the transaction when it comes back from PayPal. The way I do it is by including a field
<input type="hidden" name="invoice" value=$uniquevaluecreatedbyyourapplication>
Paypal will send this field back in the response.
In my case I add the transaction to a MySQL table and I pass the unique record id as the invoice number. When PayPal sends back the response I check the invoice number against my database to identify the transaction.
I hope this helps. If not, please post again.
Update to include more details about the IPN message
Basically when the transaction completes, PayPal will post to the script you passed in the notify_url field.
Paypal will append a token (tx) to that post. Your script will be called with something like this:
http://www.example.com/path/to/your/listener?tx=1234567890099r48&... (PayPal adds also other transaction fields here).
However you should not rely on the transaction fields PayPal adds to the first message because you don't really know it came from PayPal.
So in order to confirm that the message came from PayPal, you need to post back a message to PayPal including the tx_token PayPal sent you; an auth_token only you know (You get this from inside your PayPal seller account); and a cmd variable that tells PayPal you are verifying a transaction.
Once PayPal receives this post from your listener script, it will respond back with a post confirming that the transaction was completed and all the details. You can rely on this second post because it came as a result of your request to Paypal using your unique auth_token.
PayPal will send you a bunch of fields with transaction information including one that confirms whether the payment was successful or is in pending status. Depending on the method the client used to pay, the payment may remain in pending status for a while until it clears. PayPal will send you another message automatically when the payment clears. So you should configure your listener to handle this second message also. PayPal advises that you should not ship the product until the payment has cleared.
And to get you started, please see below the code I use for a listener script that process PayPal's response. You will need to adjust it for your needs, but it is working for me.
$req = 'cmd=_notify-synch';
$tx_token = $_GET['tx'];
$auth_token = "enter your own authorization token";
$req .= "&tx=$tx_token&at=$auth_token";
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
//$fp = fsockopen ('http://www.sandbox.paypal.com', 80, $errno, $errstr, 30);
// If possible, securely post back to paypal using HTTPS
// Your PHP server will need to be SSL enabled
// replace www.sandbox.paypal.com with www.paypal.com when you go live
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if (!$fp)
{
// HTTP ERROR
}
else
{
fputs ($fp, $header . $req);
// read the body data
$res = '';
$headerdone = false;
while (!feof($fp))
{
$line = fgets ($fp, 1024);
if (strcmp($line, "\r\n") == 0)
{
// read the header
$headerdone = true;
}
else if ($headerdone)
{
// header has been read. now read the contents
$res .= $line;
}
}
// parse the data
$lines = explode("\n", $res);
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0)
{
for ($i=1; $i<count($lines);$i++)
{
list($key,$val) = explode("=", $lines[$i]);
$keyarray[urldecode($key)] = urldecode($val);
}
$firstname = $keyarray['first_name'];
$lastname = $keyarray['last_name'];
$itemname = $keyarray['item_name'];
$amount = $keyarray['payment_gross'];
$invoiceid = $keyarray['invoice'];
$profileid = $keyarray['subscr_id'];
// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment
// show receipt to client
}
}
I hope this helps.
精彩评论