Paypal IPN keeps Retrying, but notification url did't even got callback - php

I've done test everying in Paypal sandbox, and everything goes well.
Then I'm trying to go live, but it is very strange that all my payment notification
just keeps retrying. And there is even no response (or response code) from my site.
I even try to commet all my php script and write:
<?php
writeFile("debug.log","up\n",'a');
function writeFile($file, $str, $mode = 'w')
{
$oldmask = #umask(0);
$fp = #fopen($file, $mode);
#flock($fp, 3);
if (!$fp) {
Return false;
} else {
#fwrite($fp, $str);
#fclose($fp);
#umask($oldmask);
Return true;
}
}
?>
And guess what? nothing.
no logs written.
the script didn't event fire up.
but i call my url manually, i got my log.
it just keeps retrying, and i got nothing.
so, seems like, the IPN did't even call that url.
my web is hosted on godaddy.
please help me in here, many thanks!
here are ipn infomations:
Message ID 7XL84004V1546282C
Date/time created 2/13/2014 00:44 PST
Original/Resent Original
Latest delivery attempt date/time 2/13/2014 01:26 PST
Notification URL [hidden manually]
HTTP response code
What's this?
Delivery status Retrying
No. of retries 9
as you can see, there is nothing in the row "HTTP response code".

ok I know what is going on here.
ALWAYS REMEMBER TO ADD http:// or https:// to Paypal button for your IPN listener url!
mine was like
<input type="hidden" name="notify_url" value="www.blahblah.com/test/paypal_ipn.php">
this fails,
but
<input type="hidden" name="notify_url" value="http://www.blahblah.com/test/paypal_ipn.php">
works fine :)

Related

Issue while trying to receive message notifications from Slack

About
I am trying to receive message posted on my server as soon as user post message the message in group or channel or direct in slack.
App Status
Code in the verified file where challenge was posted.
header('Content-type: application/json');
$myfile = fopen("test.txt", "w") or die("Unable to open file!");
$data = json_decode(file_get_contents('php://input'), true);
fwrite($myfile, $data["challenge"]);
fclose($myfile);
$json = '{"challenge":' . $data["challenge"] . '}';
echo json_encode(["challenge" => $json]);
Question
Now that the above url has been verified successfully, I am still not able to receive the posted messages. I was expecting messages posted at same url which was used to verify challenge parameter. Is that correct?
Am I missing anything retrieving the messages posted on my server?
Update - 1
Due to some reasons I am not even able to verify the url anymore. My server is not receiving any data. I am trying to save whatever is being posted my side but it is always blank everytime,
I think your assumptions are correct.
According to slack documentation you should be receiving posts with the given payload in this endpoint:
https://api.slack.com/apis/connections/events-api#the-events-api__receiving-events__events-dispatched-as-json
I'm still unsure how are you validating that this isn't the case though, if you kept the code above you would see no result of the post data sent by slack, also if you don't return a response status 200, slack will stop posting to this endpoint after 1 hour.
https://api.slack.com/apis/connections/events-api#the-events-api__responding-to-events
Can you try adding test.php file something like:
<?php
// get all the POST requests
if ($_SERVER["REQUEST_METHOD"] == "POST") {
file_put_contents('test.json', json_encode($_POST, JSON_PRETTY_PRINT), FILE_APPEND);
// return 200
http_response_code(200);
echo json_encode(["success" => true]);
return;
}
At the very beginning, validate the url again and check if the requests start being saved on test.json.
Alternatively can you check if you web server is routing POST requests to this url?
Try using postman to validate that

php webhook not responding to Stripe test event

I've setup a basic webhook php page as modeled on the stripe documentation and listed below. When I send a test event from the Stripe webhooks dashboard, stripe responds "Test webhook sent successfully" with a blankk reponse. However, the output log file is not written to, no email is sent and there is nothing logged to the http server error log or the php error log. My php version is 5.3.3. What am I doing wrong?
<?php
error_reporting(15);
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey("secret_test_key");
$handle = fopen("webhook.log","a");
// Retrieve the request's body and parse it as JSON
$input = file_get_contents("php://input");
$event_json = json_decode($input);
// Do something with $event_json
if (fwrite($handle, $event_json) === FALSE) {
mail("mike#example.com","Cannot write to webhook.log","");
echo "Cannot write to webhook.log";
exit;
}
mail('mike#example.com','Webhook Event',$event_json);
header(':', true, 200);
//http_response_code(200); // PHP 5.4 or greater
?>
You have a few potential problems. As a quick rule of thumb, the best way to debug this is to start by triggering the event yourself, which you can do simply by loading up your webhook url in a browser yourself. Then you can test it directly and make sure it is doing what you expect it to be doing. There are obviously two possibilities:
Stripe is not triggering your webhook handler for some reason
Your handler is not properly logging itself
The latter first: it could be that Stripe is triggering your handler but it isn't logging that fact successfully. This would mean that both your email logging and file logging are failing. That is actually quite possible. Email logging with the mail function is actually very unreliable, unless you know for a fact that it works. Mail sent with the mail function is dropped silently by most modern email systems (gmail, etc) unless you have your DNS records properly configured, which most people don't. So unless you know for sure that your mail attempt is working properly, it probably isn't. If you also happen to have a permission issue in your attempt to write to a log file (which is not uncommon for a newly setup server), your logs could simply be failing. The easiest way to check that is to load up the webhook URL in a browser yourself. That way you know it is being triggered, and can know for sure if the issue is improper logging or Stripe not calling your webhook.
If you determine for sure that stripe isn't calling your webhook, the most likely culprit would be an invalid HTTPS certificate. Is your webhook connected via HTTPS (it should be)? If so, is it a valid certificate? You can tell your browser to ignore an invalid certificate when you browse your own site, but stripe will simply refuse to send the request if it encounters an invalid certificate.
If none of the above fixes it then it will be time for more digging, but I would start with those: they are probably the most likely problems.
The solution is that $event_json is an object and the fwrite failed because it expects a string not an object. By converting to an array and then serializing I was able to both write to the log and send the email.
$event_json = (array)json_decode($input);
$event = serialize($event_json);

Paypal PHP not working. No response received from Sandbox; only Connection: close

I've been at it for 24 hours now and am about to pull my hair out. I've checked all over the Web and within Stackoverflow and can find nothing that helps. I've even checked previous posts such as Not receiving a response from Paypal IPN Sandbox but the responses aren't working for me. Perhaps I've missed the post that'll help me; if I have, please excuse me for repeating a same question, but this matter is rather urgent and I'm at the end of my rope.
Anyway, the issue is this:
I have a PHP cart going and it sends clients to Paypal. Everything is working perfectly. I've built it according to Paypal's instructions when it comes to sending all codes to them. Everything fine except when it comes to the final step, the return POST from Paypal back to my server to check everything's OK. Even there I've copied the entire Paypal code as is and just added the functions that'll check everything matches on my part. However, I can't get it to work. I try sending the results to a DB and nothing happens. So I placed a PHP Mail command right where the last action should be if everything's OK and I don't receive the E-Mail. I've placed this same Mail command almost everywhere else to try and find out what's going on and have received different clues from different places.
First, when I call to print into the E-Mail the vars Paypal's supposed to send back to my server, I get the E-Mail with all vars except for item_name and item_number, which I get blank; this is strange, because up to that point Paypal Sandbox is showing me every single product I'm supposedly purchasing. I tried giving these vars on the PHP code a fixed value in light of the fact that Paypal is not posting a value to them, at least at that point. I wanted to see if the lack of these two values was the reason for the error; the error persisted, however, even with the set values.
Second, there's a while loop in the Paypal code (the loop that a response in the link given above says one should replace with $res=stream_get_contents($fp, 1024);, this, however, didn't work for me either), so I placed the Mail command in there to see what I got back. I asked to print the $res var and the payment_status and got, as expected, several E-Mails, the collected results of which are as follows:
payment_status = Pending
$res = HTTP/1.0 302 Found
Location: https://www.sandbox.paypal.com
Server: BigIP
Connection: close
Content-Length: 0
So I'm guessing the error is occurring at this point. Something is happening (or not happening) which is not only not returning the Completed status for payment_status that the code looks for in order to continue checking and etc., but it's not even returning an INVALID response. So I'm getting no response and nothing to show me whether everything's OK or not. And, what's strange, and even worse, is the fact that Sandbox is still fake-charging me for every single one of these payment attempts, even though it's clear that there's an error somewhere and the process is not being fulfilled. (This, of course, brings out another dilemma: once all this is solved, if there is a server error at some point for X reason, will Paypal still charge my client and I won't even know somebody has bought something on my Website?)
Well, I suppose that's as much as I can explain on this matter. At this point I can't see where I could have gone wrong. The code should make this a pretty straightforward thing. So really I don't see how I could have messed up the copy & paste. I suppose that at least should have no errors, unless they come with the original code. Moreover, because everything else to that point is working 100% fine, the only place where this error could be is within this PHP file Paypal has to call once the payment process is completed by the user.
ANY idea on the matter will be EXTREMELY appreciated!
Here goes the code.
PHP CODE:
include('../inc/db_fns.inc'); //<--All my DB work is in here.
include('../inc/shipping.inc');
$paypal_email = "seller_1360198925_biz#hotmail.com";
$paypal_currency = 'USD';
//Here begin the functions I'm using to check everything and pass data to DB.
function no_paypal_trans_id($trans_id) {
$connection = db_connect();
$query = sprintf("SELECT id FROM orders WHERE paypal_trans_id = '%s'", mysql_real_escape_string($trans_id));
$result = mysql_query($query);
$num_results = mysql_num_rows($result);
if($num_results == 0) {
return true;
}
return false;
}
function payment_amount_correct($shipping, $params) {
$amount = 0.00;
for ($i=1; $i <= $params['num_cart_items']; $i++) {
$query = sprintf("SELECT precio FROM products WHERE id='%s'", mysql_real_escape_string($params["item_number{$i}"]));
$result = mysql_query($query);
if($result) {
$item_price = mysql_result($result, 0, 'precio');
$amount += $item_price * $params["quantity{$i}"];
}
}
if(($amount+$shipping) == $params['mc_gross']) {
return true;
} else {
return false;
}
}
function create_order($params) {
db_connect();
$query = sprintf("INSERT INTO orders set orders.firstname = '%s', orders.lastname = '%s', orders.email = '%s', orders.country = '%s', orders.address = '%s', orders.city = '%s', orders.zip_code = '%s', orders.state = '%s', orders.status = '%s', orders.amount = '%s', orders.paypal_trans_id = '%s', created_at = NOW()", mysql_real_escape_string($params['first_name']), mysql_real_escape_string($params['last_name']), mysql_real_escape_string($params['payer_email']), mysql_real_escape_string($params['address_country']), mysql_real_escape_string($params['address_street']), mysql_real_escape_string($params['address_city']), mysql_real_escape_string($params['address_zip']), mysql_real_escape_string($params['address_state']), mysql_real_escape_string($params['payment_status']), mysql_real_escape_string($params['mc_gross']), mysql_real_escape_string($params['txn_id']));
$result = mysql_query($query);
if(!$result) {
return false;
}
$order_id = mysql_insert_id();
for ($i=1; $i <= $params['num_cart_items'] ; $i++) {
$product = find_product($params["item_number{$i}"]);
$query = sprintf("INSERT INTO items set order_id = '%s', product_id = '%s', title = '%s', price = '%s', qty = '%s'", mysql_real_escape_string($order_id), mysql_real_escape_string($product['id']), mysql_real_escape_string($product['title']), mysql_real_escape_string($product['price']), mysql_real_escape_string($params["quantity{$i}"]));
$result = mysql_query($query);
if(!$result) {
return false;
}
}
return true;
}
//Here begins the Paypal code as is
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// 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 ('www.sandbox.paypal.com', 80, $errno, $errstr, 30); //<--Here I also tried out the other response to the question linked above and it actually returned a 'Invalid host' into he $res var-
// assign posted variables to local variables
$item_name = $_POST['item_name']; //<--These are the two vars for which
$item_number = $_POST['item_number'];// Paypal Sandbox posts no value.
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if ($_POST['payment_status'] == 'Completed' && no_paypal_trans_id($_POST['txn_id']) && $paypal_email == $_POST['receiver_email'] && $paypal_currency == $_POST['mc_currency'] && payment_amount_correct($shipping, $_POST)) {
// process payment
create_order($_POST);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
EDIT 1: Gave it another go: No luck!
I've just tried the original, untouched Paypal code. I've just copied and pasted it into this PHP and then run the Sandbox buy. Same outcome. No response, no data inserted into tables, no way of me knowing somebody has actually bought something off my cart, but Paypal still fake-charges the buy. This supports my suspicion that the error comes in the original code and has nothing to do with the functions I've added. Hope somebody can make sense of this soon. Thousand thanks in advance to that person!
EDIT 2: Following 1st response.
A kind user who has now deleted his/her response was kind enough to give it a first try. He/she recommended that the Paypal documentation mentions https://www.sandbox.paypal.com/cgi-bin/webscr where I have http://www.sandbox.paypal.com. Perhaps I have an older version of the code, so I tried out his/her recommendation. Now I comment what happened:
First of all, thanks a lot for your response. Unfortunately, no luck with it. Having substituted one address with the other, now the process doesn't get to the while loop, it stops at the fsockopen. I placed a Mail command to print out the $errno and $errstr contained in that command. With https://www.sandbox.paypal.com/cgi-bin/webscr substituting http://www.sandbox.paypal.com I get Unable to find the socket transport "https" - did you forget to enable it when you configured PHP? So I stripped the "https://" and tried again. Now I get php_network_getaddresses: getaddrinfo failed: Name or service not known. Any ideas?
EDIT 3: Following my conversation with #hexacyanide in the comments section:
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=20%3A55%3A22+Feb+08%2C+2013+PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123%2C+any+street&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross_1=9.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=2229455&notify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AsdNkKD2ktCz.aUB.9WYWy-g8MHoAa-TsvSjUgGstseJVdUhQTq3aCwW
Sorry, that was $req, not $res var. The $res var is returned by the while loop. I placed a mail command there and I get several E-Mails with the $res values. These are:
X-Frame-Options: SAMEORIGIN
HTTP/1.0 200 OK
Strict-Transport-Security: max-age=14400
INVALID
Content-Type: text/html; charset=UTF-8
Date: Sat, 09 Feb 2013 05:44:33 GMT
Connection: close
Content-Length: 7
EDIT 4: Absolutely dumbfounded: Not even simple Paypal IPN code straight from the Paypal Developer website and tested with the Paypal Developer website IPN Tester works...
I've used the Paypal IPN script generator found here.
I chose to generate a script that would mail back to me a VALID or INVALID response.
I copied it in its entirety and pasted it into a PHP file I saved in my server.
I checked and re-checked that no part of the code was left behind.
I targeted this PHP file on my server from the IPN Simulator found here.
Simulator shows a Check and says "IPN successfully sent."
I go to check my mail to see what response I got, whether it was VALID or INVALID... I got no response at all. So the IPN reaches the PHP buy at some point the process is broken so that it doesn't even get to the VALID/INVALID functions. However, this is the very code Paypal gives you and is tested with the very sim it has designed for it. So what's going on?
DAY 2 OF THIS ODYSSEY
O.K. Needless to say: no luck yet. But I've now decided to exhaustively track everything that's going into the PHP code and out to Paypal. The idea is that a response of VALID occurs when this code sends back to Paypal those initial values Paypal inserted into it and in the very same order (this according to Paypal documentation).
The first issue is that I was receiving no response at all from the code. So the supposition was that the code was failing at the very start. It happened that the first issue was that the Sandbox links do no work. (I got to this point with the aid of #hexacyanide, who was very kind to follow along yesterday with my progress or lack thereof. Whenever I get enough reputation to positively mark his/her response, I will.) So I stripped off the sandbox. and, voilĂ , it was returning a response, but now the response was INVALID.
From that time to now I've understood that IPN is just for seller-side transaction checking and data logging. Paypal doesn't care about the outcome of the IPN. So my cart IS working 100%. A user can buy something and Paypal will charge the user for it. The IPN will only check for me if the buy info is in fact coming from Paypal and all is well there and will then (in my script) send all this info into a DB so I can fulfill my side of the service. So, even though the transaction happens successfully without IPN, IPN would be an invaluable mechanism to facilitate the overall selling process. However, all this last info settles my suspicion that all my cart's code is O.K., and that the issue is ONLY here, with this code, or the way Paypal is handling it. (The fact that Paypal's "virgin" code passed through Paypal's own IPN Simulator returns no response, but the same error at the initial state of not being able to connect to the the Paypal server makes me inclined to think that the issue has to do with something wrong on Paypal's side.)
So, the log of everything going into and out of this PHP. I located Mail commands at every single significant point in the code in order to create checkpoints. Inside the foreach() command I included an incremental variable in order to have and ordered list of the POSTED data coming in. And this is what I got:
This is the data being POSTED into the code by Paypal (in the order it's being POSTED)
test_ipn=1
payment_type=instant
payment_date=08%3A42%3A23+Feb+09%2C+2013+PST
payment_status=Completed
payer_status=verified
first_name=John
last_name=Smith
payer_email=buyer%40paypalsandbox.com
payer_id=TESTBUYERID01
business=seller%40paypalsandbox.com
receiver_email=seller%40paypalsandbox.com
receiver_id=TESTSELLERID1
residence_country=US
item_name1=something
item_number1=AK-1234
quantity1=1
tax=2.02
mc_currency=USD
mc_fee=0.44
mc_gross=15.34
mc_gross_1=12.34
mc_handling=2.06
mc_handling1=1.67
mc_shipping=3.02
mc_shipping1=1.02
txn_type=cart
txn_id=23291642
notify_version=2.4
custom=xyz123
invoice=abc1234
charset=windows-1252
At a glance, I seem to be getting all the data I should from Paypal. And this is the order in which PP sends it. So if I were to send this data in this order back and PP actually does check it for this same order, then I should, in theory, get a VALID response.
So what the code does is add "cmd=_notify-validate", which is the only addition (the PP documentation makes it clear that this is necessary addition is necessary), and passes all this data into a var called $req in this way: A=X&B=Y&C=Z....
Here is the message from the next checkpoint, added just after the foreach() command closes.
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=08%3A42%3A23+Feb+09%2C+2013+PST&payment_status=Completed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=15.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=23291642&notify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb
Note the verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb at the end. I can't account for that piece of data because it was not spit out in the form of an E-Mail during the foreach() loop. So where does it come from? Could this be the culprit piece of data that returns the INVALID response? Open question. But at this point, all this data is passed by the code at the "DATA COMING IN" checkpoint; so if this data is what's coming in and my code sends it back out, then everything should be fine.
So the next checkpoint will be "DATA COMING OUT." I located this checkpoint right before the fputs ($fp, $header . $req); code which writes $req back to PP. And this is what is coming out of the code:
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=08%3A42%3A23+Feb+09%2C+2013+PST&payment_status=Completed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=15.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=23291642&notify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb
HUM! Am I missing something? Are my eyes skipping over the tiniest hiccough that makes this code trip? The output seems to be exactly the same as the input. Let's assume that PP worked up their code fine, that the POSTED data is turned into a string in a way that PP expects and, therefore, checks for... assuming all this, what could be wrong?
Let's see... again: open questions:
Could it be an issue with the header? According to documentation, this is the header one should use... so unless they're off on this, then it should work fine.
Could it be an issue with the URL given? O.K., this IS in fact an issue, or rather WAS at some point. There are at least 6 or 7 different URLs running around the Internet which are supposed to work and not work. Some have worked for some people and not for others, some seem never to work, etc. Not even PP themselves are sure what URL is supposed to be used, as in their own documentation it varies. What is clear is that using the sandbox. URLs will return nothing--one is to suppose that these are broken.
Could it be an issue with the charset? Could there be an incompatibility? This just occurred to me as I was seeing the data come in and out with Hex codes. The thing is that this should make it compatible, right? However, yesterday, as I was checking what was going on in the while() loop, and catching the info sent back from PP into the $res var I wasn't getting Hex codes, as you can see further up in this testament.
The next checkpoint is the classic one at if() VALID and if() INVALID. And, of course, I get the one that tells me it all came out INVALID, once again.
Hopefully this detailed info I'm giving will make someone's light bulb shine brightly! As for me, I'm still dumbfounded.
Thanks in advance!
THANKS A LOT TO BOTH OF YOU FOR YOUR RESPONSES!
I haven't tried the second one out, though it sounds pretty sensible. Sounds like that could have been the issue with the original code I got from PayPal. If I have any time to try it out and see if the code works with it, I'll post my feedback here. Hopefully someone will find all this useful.
After a week banging my head against the walls and a little time off to cool the issue in my brain, I have finally, a couple of days ago, found another way to solve the issue somewhere in the Web which is pretty similar to the second part of Hexacyanide's response. I'm posting it below for anyone who's following this string. However, I must say, the PayPal code is pretty buggy. At least the one I received. I have since had several other issues I've had to solve via workarounds. An the worst part is that PayPal has no support AT ALL. I even called three times: the first, the person hung up on me; then, they told me it could be a virus issue (typical response when they don't really know what's going on).
Anyway, I wish I could rate both your responses but I need more than +15 points for that, so I'll praise them verbally here. I tried out Hexacynide's response code as is but it didn't work or me, so I can't mark it as checked. If I have time to try out the other in the future, and it works, I'll mark it as correct.
Until then, here is my code update using CURL.
$ch = curl_init('https://www.paypal.com/pe/cgi-bin/webscr');
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
if( !($res = curl_exec($ch)) ) {
// error_log("Got " . curl_error($ch) . " when processing IPN data");
curl_close($ch);
exit;
}
curl_close($ch);
NOTE: Here it's targeted to the real thing because it's now up and running, however, using it with sandbox. works as well.
I'm new to Stackoverflow, so I didn't realize one can answer one's own question. Anyway, I had answered it at the end of the original post by editing it about last week. Now I include it here so that anybody who's having such trouble can refer back to this and realize this is the way I was able to solve the issue.
I tried the first solution given here by a fellow contributor but unfortunately it didn't work for me. The second solution arrived once I had already been able to solve it another way, so I haven't tried it. Perhaps I'll get to it sometime in the future. But if anyone tries it, please leave your comments here so other benefit from the wisdom.
Here is my solution:
After a week banging my head against the walls and a little time off to cool the issue in my brain, I have finally, a couple of days ago, found another way to solve the issue somewhere in the Web which is pretty similar to the second part of Hexacyanide's response. I'm posting it below for anyone who's following this string. However, I must say, the PayPal code is pretty buggy. At least the one I received. I have since had several other issues I've had to solve via workarounds. An the worst part is that PayPal has no support AT ALL. I even called three times: the first, the person hung up on me; then, they told me it could be a virus issue (typical response when they don't really know what's going on).
Anyway, I wish I could rate both your responses but I need more than +15 points for that, so I'll praise them verbally here. I tried out Hexacynide's response code as is but it didn't work or me, so I can't mark it as checked. If I have time to try out the other in the future, and it works, I'll mark it as correct.
Until then, here is my code update using CURL.
$ch = curl_init('https://www.paypal.com/pe/cgi-bin/webscr');
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
if( !($res = curl_exec($ch)) ) {
// error_log("Got " . curl_error($ch) . " when processing IPN data");
curl_close($ch);
exit;
}
curl_close($ch);
NOTE: Here it's targeted to the real thing because it's now up and running, however, using it with sandbox. works as well.
Try changing this:
// 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 ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
To this:
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Connection: close\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
Essentially, PayPal is discontinuing support for HTTP 1.0. I believe that it's already been discontinued on the Sandbox, but it's still supported on the live site (but not for much longer). This article has some more information on it: https://www.paypal-notify.com/eventnotification/event_details?eventId=2891
Additionally, you should be posting back to the SSL-enabled host. I want to say that PayPal will refuse to verify an IPN on the HTTP URL (and just redirect to the PayPal home page on the SSL-enabled server), but I'm not 100% sure on this.
Lastly, to answer your question -- IPN is an asynchronous process, and it doesn't start until after the payment has completed. Therefore, if you don't receive an IPN for whatever reason, the payment has already completed and won't get reversed just because you didn't receive the IPN. If you want something that will definitely ping back your site before the payment is made, I'd suggest looking into Express Checkout.
I've just been through this. You have to APPEND the command to the response rather than prepending it. Once you do that, you should receive the coveted 'VERIFIED' response from paypal. For your convenience, I have posted the code that worked for me. I've been where you are, brother, and figured I would actually respond rather than closing the browser and going to bed (I've had a long day with this too!). Anyway, without further adieu, here 'tis:
function verifyPayment($request)
{
if($request->is('post') && !empty($request->data))
{
//build response string
$response = '';
foreach($request->data as $field => $value)
{
//build response string
$response .= $field . '=' . urlencode(stripslashes($value)) . '&';
}
if(empty($id))
{
return false; //invalid transaction
}
//append notify validate command
$response .= "cmd=_notify-validate";
//respond to paypal - open connection
$parsedUrl = parse_url('https://www.sandbox.paypal.com/cgi-bin/webscr');
$sock = fsockopen('ssl://' . $parsedUrl['host'], "443", $errorNumber, $error, 30);
if(!$sock)
{
return false; //could not open connection - must be able to verify
}
//post data back to paypal
fputs($sock, "POST $parsedUrl[path] HTTP/1.1\r\n");
fputs($sock, "Host: $parsedUrl[host]\r\n");
fputs($sock, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($sock, "Content-length: " . strlen($response) . "\r\n");
fputs($sock, "Connection: close\r\n\r\n");
fputs($sock, $response . "\r\n\r\n");
//loop through response and append
$ipnResponse = '';
while(!feof($sock))
{
$ipnResponse .= fgets($sock, 1024);
}
//close connection
fclose($sock);
if(!eregi("VERIFIED", $ipnResponse))
{
return false; //paypal reports invalid transaction
}
//if we made it here, transaction is valid
return true;
}
}
I sincerely hope that this helps you and anyone else dealing with the frustration of paypal!
Cheers!
Jay Good

PHP how to loop until confirmation.

I am doing a script to send a string via URL link to an SMS gateway and get the response from them.
They will respond with a code and text for the answer, either '200 = SUCCESS' or an error-code: '-100 = UNKNOWN ERROR' , '-101 = MISSING PARAMETER' , etc.
In my back-end code, I would like to know how to keep looping, waiting for the return message from the SMS Gateway with an error-code and resend my string to the SMS gateway until success or confirmation?
$link = "http://www.smsgateway.com/send.php?phoneno=".$phonenumber."&message=".urlencode($smsMessage);
Next, I use cURL to send this link and get the response:
$returned_content = using_cURL_function_to_get_response($link);
Now, my $returned_content will show:
Success Code: 200 = SUCCESS
Failure Code: -100 = UNKNOWN ERROR
Failure Code: -101 = MISSING PARAMETER
and many more -1xx failure / error-codes
Then, I want to perform a loop to check the $returned_content, if it is a failure / error-code then send again the string via cURL to the SMS gateway.
if ($returned_content = 'ANY FAILURE / ERROR-CODE') {
//redo cURL
$link = "http://www.smsgateway.com/send.php?phoneno=".$phonenumber."&message=".urlencode($smsMessage);
$returned_content = using_cURL_function_to_get_response($link);
// Check the $returned_content
} else {
// inform me the '200 = SUCCESS' via email
mail($myEmail, $successfulSubjectt, $returned_content, $msgHeaders);
}
I'm not sure about this looping part, anyone could help?
I guess what you're trying to do is this:
$link = "http://www.smsgateway.com/send.php?phoneno=".$phonenumber."&message=".urlencode($smsMessage);
while ($returned_content != '200 = SUCCESS')
{
$returned_content = using_cURL_function_to_get_response($link);
}
mail($myEmail, $successfulSubjectt, $returned_content, $msgHeaders);
But it's not a good idea. Suppose you never do get a success? You will have an infinite loop. You should really rethink what you're trying to do.
So when you try to send an SMS and you get an error, you want to retry sending? How would that work?
Also, not sure, but the target server might interpret this as a DoS attack.
I think you should rethink your approach. If your goal is enabling some users to send SMS, then how about presenting them with a message saying that there was an error delivering their SMS and they should try later?

iPhone Push Notification - Error response problem

I've got a problem when checking for a response error after sending a Push Notification. This is my setup:
From my PHP server, I'm sending Push Notifications. These notifications are send in the enhanced format, so I can get an error response from the Apple server. For example: Error #7 "Invalid payload size".
The way I check for errors is reading the socket response:
const ERROR_RESPONSE_SIZE = 6;
$errorResponse = #fread($this->_apnsSocket, self::ERROR_RESPONSE_SIZE);
This works fine when there is an actual error. By my problem is: when there's no error, the "fread" call doesn't return anything and keeps loading forever.
Can anyone help me with this? Thanks for your help!
You need to set stream_set_blocking($this->_apnsSocket, 0); to 0 which is non-blocking mode, because on success Apple doesn't send back anything, but the fread is waiting for data in blocking mode.

Categories