I've been using PayPal IPN for years, and on Sept 13, 2016, my IPN listener started having problems. It looks like the mc_shipping field isn't being returned at all now, and custom field is coming back empty (though I am sending the user's ID).
Here is the code I use to contact PayPal:
$ch = curl_init('https://www.paypal.com/cgi-bin/webscr');
$myemail = "molly#thetripclip.com";
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 = "CURL ERROR";
$text = "Got " . curl_error($ch) . " when processing IPN data";
include ("log_ipn_error.php");
curl_close($ch);
exit;
}
curl_close($ch);
Here is what I'm getting back from PayPal:
cmd=_notify-validate&mc_gross=4.95&protection_eligibility=Eligible&address_status=confirmed&item_number1=03&payer_id=[removed for security reasons]&address_street=[address removed for security reasons]&payment_date=09%3A04%3A13+Sep+14%2C+2016+PDT&payment_status=Completed&charset=windows-1252&address_zip=59422&first_name=[name removed for security reasons]&mc_fee=0.44&address_country_code=US&address_name=[name removed for security reasons]¬ify_version=3.8&custom=&payer_status=unverified&business=molly%40thetripclip.com&address_country=United+States&num_cart_items=1&mc_handling1=0.00&address_city=Choteau&verify_sign=AuRlNZvMOhdn8iDWY5YoMB9iRTDzAIjG.3f9vIDCnjWeCMq94kt.qaLM&payer_email=[customer email removed for security reasons]&btn_id1=16432817&contact_phone=[phone no removed for security reasons]&txn_id=95R75212V2997631V&payment_type=instant&last_name=[name removed for security reasons]&address_state=MT&item_name1=5+Trip+Clip+Activities&receiver_email=[my email address]&payment_fee=0.44&quantity1=1&receiver_id=FSRPNTT2JQ9LE&txn_type=cart&mc_gross_1=4.95&mc_currency=USD&residence_country=US&transaction_subject=&payment_gross=4.95&ipn_track_id=73e7cbaf7590a
I've found one other person asking a similar question (with no answer), but I can't find anything from PayPal saying that they are changing the IPN fields.
I have been experiencing this same issue with multiple paypal accounts for about 1 month now. This appears to be an issue with paypal according to a response I received from their support site.
Thank you for contacting Merchant Technical Support.
Unfortunately, the problem you're experiencing is being caused by some technical issues with the PayPal system. Our engineers are currently working diligently on a solution to this problem. I am going to assign this ticket to our internal engineering ticket so that when the problem is resolved, you will be notified of its completion right away.
I would suggest anyone else with a similar issue submit a ticket at https://www.paypal-techsupport.com/ in hopes they resolve this issue quickly
Related
Does RESTful APIs provides url encoding as default or do I have to encode it using other methods? I am using following code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"xmlRequest=" . $input_xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
$data = curl_exec($ch);
curl_close($ch);
There is no 'standard REST'. So it's often very difficult to say something specific, because in some ways it's just an idea.
But if you restrict REST to HTTP apis, generally the 'best practice' is that you use url encoding, where this is expected/needed by HTTP and don't use url encoding where it's unexpected.
To get a better answer, rephrase the question with a specific example that made you wonder about this.
This question follows on from my previous one. I thought I would perform a basic token authentication by calling the get_space_usage API function. I tried
$headers = array("Authorization: Bearer token",
"Content-Type:application/json");
$ch = curl_init('https://api.dropboxapi.com/2/users/get_space_usage/');
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
The documentation does not in fact indicate that it is necessary to provide a Content-Type header. However, without that header I get the message
Bad HTTP "Content-Type" header: "application/x-www-form-urlencoded". Expecting one of "application/json",...
Putting in that header but supplying no POST fields produces another error
request body: could not decode input as JSON
Just providing some dummy post data curl_setopt($ch,CURL_POSTFIELDS,json_encode(array('a'=>1))); does not do anything to remedy the situation. What am I doing wrong?
The documentation doesn't indicate that a Content-Type header is expected, because, since this endpoint doesn't take any parameters, no body is expected, and so there's no content to describe via a Content-Type header. Here's a working command line curl example, per the documentation:
curl -X POST https://api.dropboxapi.com/2/users/get_space_usage \
--header "Authorization: Bearer <ACCESS_TOKEN>"
Translating this to curl in PHP would involve making sure PHP also doesn't send up a Content-Type header. By default though, it apparently sends "application/x-www-form-urlencoded", but that isn't accepted by the API. If you do set a "application/json", the API will attempt to interpret the body as such, but won't be able to do so, since it isn't valid JSON, and so fails accordingly.
It's apparently not easy (or maybe not possible) to omit the Content-Type header with curl in PHP, so the alternative is to set "application/json", but supply valid JSON, such as "null". Here's a modified version of your code that does so:
<?php
$headers = array("Authorization: Bearer <ACCESS_TOKEN>",
"Content-Type: application/json");
$ch = curl_init('https://api.dropboxapi.com/2/users/get_space_usage');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "null");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
This question already has answers here:
Why is my e-mail still being picked up as spam? Using mail() function
(5 answers)
Closed 9 years ago.
I am sending an email using PHP but all the emails are going to the spam folder. Please tell me where I am making a mistake.
<?
$name=$_POST['name'];
$email=$_POST['email'];
$phone=$_POST['phone'];
$message=$_POST['message'];
$ToEmail = "me#example.com";
$ToSubject = "Message from your site";
$EmailBody = "Name: $name\n
Email: $email\n
Phone: $phone\n
Message: $message\n";
$Message = $EmailBody;
$headers .= "Content-type: text; charset=iso-8859-1\r\n";
$headers .= "From:".$name." / ".$email."\r\n";
mail($ToEmail,$ToSubject,$Message, $headers);
header("location: thankyou.php");
?>
Long story short, if the recipient's server put your mail into the spam box, your program is working all right and there is nothing you can do.
Longer Story: Nowadays most mailing servers will check that the email is from a server that actually holds the domain corresponding to the email. Suppose you are sending with account abc#gmail.com, the server of the recipient's email checks if the server from which this mail comes is gmail.com. This is done by checking the SPF record .
I am trying to get an access token for Paypal's RESTful web services but unfortunately not making any headway. This is my first time dealing with REST, so please be patient with me :)
Here is what I have:
Client_id and secret as provided by Paypal for a sandbox account through the paypal developer website.
The ENDpoint: https://api.sandbox.paypal.com/v1/oauth2/token
The documentation that i am referring to is : https://developer.paypal.com/webapps/developer/docs/integration/direct/make-your-first-call/
Now the juicy part of making that API call. I am developing in PHP so I am using CURL to make the calls. something like this;
const CLIENT_ID = ****..*** ;
const SECRET = ***..***;
$base64EncodedClientID = base64_encode(self::CLIENT_ID . ":" . self::SECRET);
$headers = array("Authorization" => "Basic " . $base64EncodedClientId, "Accept" =>"*/*", "Content-type" => "multipart/form-data");
$params = array("grant_type"=>"client_credentials");
$url = "https://api.sandbox.paypal.com/v1/oauth2/token";
$ch = curl_init();
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_HEADER, $headers);
curl_setopt($ch,CURLOPT_POSTFIELDS,$params);
$response = curl_exec($ch);
Pretty vanilla right? Except that I do not get the JSON response that I expect from Paypal but false. This implies that my CURL request was not prepared well, perhaps I am setting the header incorrectly or the params are incorrect. Regardless, the URL is definitely accessible since I was able to access it through command line with the same credentials and got the desired JSON response.
The one glaring problem I have with the above code is that I am providing the client_id and secret as a header option. basic sense tells me that they need to be part of the POST field data However, if you look at line 89 of this Github code https://github.com/paypal/rest-api-sdk-php/blob/master/lib/PayPal/Auth/OAuthTokenCredential.php (Paypals' official PHP REST SDK), it clearly states that the credentials are being set in the header field.
Where am I messing up ?
With curl you don't need to manually generate the base64 encoded value for the Authorization header just use the CURLOPT_USERPWD option and pass the clientID and secret as the user:pwd.
curl_setopt($curl, CURLOPT_USERPWD, $clientId . ":" . $clientSecret);
here is a sample - look for the get_access_token() method:
https://github.com/paypal/rest-api-curlsamples/blob/master/execute_all_calls.php
Had the exact same problem you ran into. The issue is that PayPal accepts the content-type application/x-www-form-urlencoded. Your code is attempting to send multipart/form-data. CURL by default sends application/x-www-form-urlencoded, but you are passing your data as an array. Instead, you should be passing the data like a url encoded string since this is what application/x-www-form-urlencoded data looks like:
$params = "grant_type=client_credentials";
Your headers have the same problem. Pass it as an array of strings instead of a dictionary. For instance:
$headers = ["Authorization Basic " . $base64EncodedClientId];
Also, you don't need those other two headers you passed in. The 'Accept' header does nothing since you are accepting everything, and the Content-type is wrong for one, and two is defaulted to 'application/x-www-form-urlencoded' by CURL so unless you need to override that, there is no need.
We develop an iPhone app, and have push notification for development and ad hoc version working properly. But when we try to send push notification to real user devices in our database, we got SSL connection reset, then Broken pipe error. We think maybe there are too many devices in our database (more than 70000), so it is failed to send all messages at the same time. So we try to send messages to 1000 devices once, but still got this "Broken pipe" error for around 100 messages. And we are not sure whether the messages have been send. Any suggestion?
We have solved this problem. It is broken due to invalid tokens in our database table.And apple apns service will disconnect us if there is an invalid token. Since the connection is broken, it will have "Broken Pipe" error when you try to send messages again. Basic solution is to find whether writing to pipe is successful, if not, just disconnect and reconnect again after some delay.
emagic is correct, one reason for the "broken pipe" error can occur from invalid tokens. There are a few other reasons it can occur too. The following is from Apple Technical Note TN2265:
The most common problem is an invalid device token. If the token came
from the sandbox environment, such as when you are testing a
development build in house, you can't send it to the production push
service. Each push environment will issue a different token for the
same device or computer. If you do send a device token to the wrong
environment, the push service will see that as an invalid token and
discard the notification.
An invalid device token can also mean that the user has deleted your
app from their device or computer. You should check the feedback
service at least once a day for device tokens that are no longer
valid.
Other possible issues might be sending a payload longer than 256
bytes, your payload might not be formatted correctly, or perhaps your
JSON dictionary has incorrect syntax.
An occasional disconnect while your provider is idle is nothing to be
concerned about; just re-establish the connection and carry on. If one
of the push servers is down, the load balancing mechanism will
transparently direct your new connection to another server assuming
you connect by hostname and not by static IP address.
Extending on emagic's answer, this is my php code snipplet:
private $fp;
private function connect(){
$apnsHost = 'gateway.push.apple.com';
$apnsCert = 'certs/cert.pem';
$apnsPort = 2195;
$pass = "blah";
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', $pass);
$this->fp = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext);
if (!$this->fp) return("Failed to connect: $err $errstr<br>");
echo 'Connected to APNS<hr />';
}
private function send(){
$this->connect();
foreach($pushes as $push) {
$payload['aps'] = array('alert' => $push->text, 'badge' => 0, 'sound' => 'default');
$payload2 = json_encode($payload);
$msg = chr(0) . pack('n', 32) . pack('H*', $push->token) . pack('n', strlen($payload2)) . $payload2;
try {
$result = fwrite($this->fp, $msg, strlen($msg));
}
catch (\Exception $e) {
fclose($this->fp);
echo('Error sending payload: ' . $e->getMessage());
sleep(5);
$this->connect();
}
}
}