I have a REST url (coded in Java using DropWizard) to which I want to POST a json from PHP. However I am getting 415 Unsupported MediaType error. I have looked up over many forums and I am not able to figure out what the error might be. My code at both ends is as follows:
SERVER
#POST
#Path("/update-table")
#Timed
public TableUpdateResponse updateTable(TestClass testObj) {
LOG.info("inside updateTable function");
//other code ...
}
CLIENT
<?php
$url = "localhost:8084/update-table"
$ch = curl_init($url);
$jsonString = array("testString" => "Hello World!");
$json = json_encode($jsonString);
$headers = array();
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
echo $response;
?>
TestClass
public class TestClass {
private String testString;
public TestClass(String testString) {
super();
this.testString = testString;
}
public TestClass() {
super();
}
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
}
The request is not reaching REST (the LOG line does not get printed). What am I missing here?
Try to change the application/json content type to one of these
application/json
application/x-javascript
text/javascript
text/x-javascript
text/x-json
Altough the correct one specified in RFC is application/json, your java code might have a problem with it
add the annotation #Consumes(MediaType.APPLICATION_JSON)
Related
From a C# library I need to use the SP rest Api to upload a document to a document library then set properties for it.
I almost have this working by making the following sequence of calls:
Post to /contextinfo to get the FormDigestValue
Post the binary to /Files/Add including the digest in the header property X-RequestDigest
Get /ListItemAllFields the digest in the header property X-RequestDigest
The next call is a Post to _api/web/lists/GetByTitle('library name')/Items(157)
The same digest value is included in the header property X-RequestDigest as can be seen below:
POST
https://xxx.uk/_api/web/lists/GetByTitle('AssetMgmtEfilesDemo')/Items(157) HTTP/1.1
Accept: application/json, application/xml; odata=verbose
X-HTTP-Method: MERGE
IF-MATCH: *
X-RequestDigest: 0x01426A9818F7145E12BC2E99246C7E00AC1A3905D27204C783107FDDE806D2629171FAD8DCC61008E109DD9948BEB4208DC62107B2336B1228ABA143A2D5B3C6,19 Feb 2019 15:20:44 -0000
Content-Type: application/json; charset=utf-8
Host: xxx.uk
Content-Length: 359
Expect: 100-continue
{
__metadata":{
"type":"SP.Data.AssetMgmtEfilesDemoItem"
},
"UPRN":"U1",
"KeystoneDocType":"Document"
}
My problem is that for this request, I get a "403 forbidden" response.
Can anyone see where I went wrong?
Did you try getting a fresh new form digest value before making the post call ? form digest value do expire after some time (default 30 mins).
You can also check your permission on the specific list.
Sample code for your reference, call Rest API in C# code, reference System.Web.Extensions dll:
using System.Net;
using System.IO;
using System.Web.Script.Serialization;
static void Main(string[] args)
{
UpdateListItem();
}
public static string GetFormDigest()
{
string formDigest = null;
string resourceUrl = "http://sp/sites/dev/_api/contextinfo";
HttpWebRequest wreq = HttpWebRequest.Create(resourceUrl) as HttpWebRequest;
wreq.UseDefaultCredentials = true;
wreq.Method = "POST";
wreq.Accept = "application/json;odata=verbose";
wreq.ContentLength = 0;
wreq.ContentType = "application/json";
string result;
WebResponse wresp = wreq.GetResponse();
using (StreamReader sr = new StreamReader(wresp.GetResponseStream()))
{
result = sr.ReadToEnd();
}
var jss = new JavaScriptSerializer();
var val = jss.Deserialize<Dictionary<string, object>>(result);
var d = val["d"] as Dictionary<string, object>;
var wi = d["GetContextWebInformation"] as Dictionary<string, object>;
formDigest = wi["FormDigestValue"].ToString();
return formDigest;
}
public static void UpdateListItem()
{
string result = string.Empty;
Uri uri = new Uri("http://sp/sites/dev/_api/web/lists/getbytitle('AssetMgmtEfilesDemo')/items(1)");
HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(uri);
wreq.Credentials = CredentialCache.DefaultNetworkCredentials;
wreq.Method = "POST";
wreq.Accept = "application/json; odata=verbose";
wreq.ContentType = "application/json; odata=verbose";
wreq.Headers.Add("X-HTTP-Method", "MERGE");
wreq.Headers.Add("IF-MATCH", "*");
wreq.Headers.Add("X-RequestDigest", GetFormDigest());
string stringData = "{'__metadata': { 'type': 'SP.Data.AssetMgmtEfilesDemoItem' }, 'Title': 'UpdatedViaRest','UPRN':'U1','KeystoneDocType':'Image'}";
wreq.ContentLength = stringData.Length;
StreamWriter writer = new StreamWriter(wreq.GetRequestStream());
writer.Write(stringData);
writer.Flush();
WebResponse wresp = wreq.GetResponse();
using (StreamReader sr = new StreamReader(wresp.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
Very short, lots of questions on this and I have gone through a bunch of them and can't find the answer.
It should be straight forward, I copy the github sample code to my server, point paypal IPN simulator at it and it should give me a handshake. It doesn't.
I initiate the IPN simulator and the error message I get is:
"IPN was not sent, and the handshake was not verified. Review your information."
I have stepped through line by line and I am using the exact sample code, I have made sure I am sending to sandbox...
I have been struggling for 2 days to get this to work. Any help would be greatly appreciated.
Here is the class:
<?php
class PaypalIPN
{
/**
* #var bool $use_sandbox Indicates if the sandbox endpoint is used.
*/
private $use_sandbox = false;
/**
* #var bool $use_local_certs Indicates if the local certificates are used.
*/
private $use_local_certs = true;
/** Production Postback URL */
const VERIFY_URI = 'https://ipnpb.paypal.com/cgi-bin/webscr';
/** Sandbox Postback URL */
const SANDBOX_VERIFY_URI = 'ssl:https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';
/** Response from PayPal indicating validation was successful */
const VALID = 'VERIFIED';
/** Response from PayPal indicating validation failed */
const INVALID = 'INVALID';
/**
* Sets the IPN verification to sandbox mode (for use when testing,
* should not be enabled in production).
* #return void
*/
public function useSandbox()
{
$this->use_sandbox = true;
}
/**
* Sets curl to use php curl's built in certs (may be required in some
* environments).
* #return void
*/
public function usePHPCerts()
{
$this->use_local_certs = false;
}
/**
* Determine endpoint to post the verification data to.
* #return string
*/
public function getPaypalUri()
{
if ($this->use_sandbox) {
return self::SANDBOX_VERIFY_URI;
} else {
return self::VERIFY_URI;
}
}
/**
* Verification Function
* Sends the incoming post data back to PayPal using the cURL library.
*
* #return bool
* #throws Exception
*/
public function verifyIPN()
{
if ( ! count($_POST)) {
throw new Exception("Missing POST Data");
}
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode('=', $keyval);
if (count($keyval) == 2) {
// Since we do not want the plus in the datetime string to be encoded to a space, we manually encode it.
if ($keyval[0] === 'payment_date') {
if (substr_count($keyval[1], '+') === 1) {
$keyval[1] = str_replace('+', '%2B', $keyval[1]);
}
}
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
}
// Build the body of the verification post request, adding the _notify-validate command.
$req = 'cmd=_notify-validate';
$get_magic_quotes_exists = false;
if (function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}
foreach ($myPost as $key => $value) {
if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
}
$req .= "&$key=$value";
}
// Post the data back to PayPal, using curl. Throw exceptions if errors occur.
$ch = curl_init($this->getPaypalUri());
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_SSLVERSION, 6);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// This is often required if the server is missing a global cert bundle, or is using an outdated one.
if ($this->use_local_certs) {
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/cert/cacert.pem");
}
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);
if ( ! ($res)) {
$errno = curl_errno($ch);
$errstr = curl_error($ch);
curl_close($ch);
throw new Exception("cURL error: [$errno] $errstr");
}
$info = curl_getinfo($ch);
$http_code = $info['http_code'];
if ($http_code != 200) {
throw new Exception("PayPal responded with http code $http_code");
}
curl_close($ch);
// Check if PayPal verifies the IPN data, and if so, return true.
if ($res == self::VALID) {
return true;
} else {
return false;
}
}
}
And Here is the listener.php:
<?php
namespace Listener;
require('PaypalIPN.php');
use PaypalIPN;
$ipn = new PaypalIPN();
// Use the sandbox endpoint during testing.
$ipn->useSandbox();
$verified = $ipn->verifyIPN();
if ($verified) {
/*
* Process IPN
* A list of variables is available here:
* https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNandPDTVariables/
*/
}
// Reply with an empty 200 response to indicate to paypal the IPN was received correctly.
header("HTTP/1.1 200 OK");
Working with REST API (https://qwintry.com/ru/api-docs), trying make method which will register new user.
There is the part of API docs about registering user request:
Login
Request example:
<?php
define('site_url', 'qwintry.com');
$url = 'https://' . site_url.'/api-rest/v2/user/login';
$data = array (
'email' => 'op#b.c',
'password' => '123',
'key' => '9e4fddbb3adc4c67f74bb2b7757cebf9',
);
$data_string = http_build_query($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
$response = curl_exec($ch);
curl_close($ch);
print_r($response);
Parameters:
email — E-mail of user
password — Password
key — Unique key of request
There is my implementation of method loginUser:
#Service
public class LogisticServiceImpl implements LogisticService {
private final String BASE_URL = "http://www.qwintry.com/api-rest/v2";
#Override
public String userLogin(String email, String password) throws Exception {
String url = BASE_URL + "/user/login";
Map<String, Object> params = new HashMap<>();
params.put("email", email);
params.put("password", password);
HttpResponse<String> jsonResponse = Unirest.post(url).fields(params).asString();
return jsonResponse.getBody();
}
Getting such response permanently:
301 Moved Permanently 301 Moved Permanently
nginx
expected Json format.
What I'm doing wrong?
Found mistake in docs, its not POST but GET request, now everything works
Is there already ANY solution how to insert/edit/delete events in google Calendar using Zend Gdata Framework.
Since November 17 it doesn't work.
Thanks
First you have to follow this step:
http://cornempire.net/2012/01/08/part-2-oauth2-and-configuring-your-application-with-google/
When it's done you can use my class : !! Curl has to be enable on your server.
class gcalendar{
private $cal_id;
//To get credentials follow this steps ==> http://cornempire.net/2012/01/08/part-2-oauth2-and-configuring-your-application-with-google/
private $client_secret='to_change';//TO CHANGE
private $refresh_token='to_change';//TO CHANGE
private $client_id='to_change';//TO CHANGE
public $spindle='+01:00';
private $token;
public function __construct($cal_id){
$this->token=$this->get_access_token();
$this->cal_id=$cal_id;
}
//Retourne un token
private function get_access_token(){
$tokenURL = 'https://accounts.google.com/o/oauth2/token';
$postData = array(
'client_secret'=>$this->client_secret,
'grant_type'=>'refresh_token',
'refresh_token'=>$this->refresh_token,
'client_id'=>$this->client_id
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tokenReturn = curl_exec($ch);
$token = json_decode($tokenReturn);
$accessToken = $token->access_token;
return $accessToken;
}
//liste tous les events sur la période définit en param
public function list_events($start_date,$end_date){
return $this->execute('list_events',false,array('start_date'=>$start_date,'end_date'=>$end_date));
}
//Récupere l'event ayant l'id passer en param
public function get_event($event_id){
return $this->execute('get_event',false,array('event_id'=>$event_id));
}
//Ajoute un event !!Attention$_data doit respecter une certaine syntaxe voir plus bas fonction create_args!
public function add_event($_data){
$args=$this->create_args($_data);
return($this->execute('add_event',$args));
}
//Modifie un rdv (heures, titre ou contenu).
public function update_event($event_id,$_data){
$ev=json_decode($this->get_event($event_id));
$_data['sequence']=$ev->sequence+1;
$args=$this->create_args($_data);
return($this->execute('update_event',$args,array('event_id'=>$event_id)));
}
//Supprime un event
public function delete_event($event_id){
return $this->execute('delete_event',false,array('event_id'=>$event_id));
}
/*
** $_data=array(
!start_date => Date de début de l'event au format Y-m-d
!start_time => Heure de début de l'event au format HH:ii
!end_date => Date de fin de l'event Y-m-d
!end_time => Heure de fin de l'event HH:ii
summary => Titre de l'event (title)
description => Description de l'event
sequence => Sequence de l'event (C'est un numéro à incrémenter à chaque update de l'event). Obligatoire lors d'un update.
)
Les champs avec un ! sont obligatoires!
**
*/
private function create_args($_data){
$_args=array( 'start' => array('dateTime'=>$_data['start_date']."T".$_data['start_time'].":00.000".$this->spindle),
'end' => array('dateTime'=>$_data['end_date']."T".$_data['end_time'].":00.000".$this->spindle));
unset($_data['start_date']);
unset($_data['start_time']);
unset($_data['end_date']);
unset($_data['end_time']);
foreach($_data as $key=>$value){
$_args[$key]=$value;
}
return json_encode($_args);
}
//execute les requetes curl adaptée selon le type ($type_exe)
private function execute($type_exe,$args=false,$opt=false){
switch ($type_exe){
case 'list_events':
$request='https://www.googleapis.com/calendar/v3/calendars/'.urlencode($this->cal_id).'/events?timeMax='.urlencode($opt['end_date'].'T23:59:59.000'.$this->spindle).'&timeMin='.urlencode($opt['start_date'].'T00:00:01.000'.$this->spindle);
$session = curl_init($request);
break;
case 'get_event':
$request='https://www.googleapis.com/calendar/v3/calendars/'.urlencode($this->cal_id).'/events/'.$opt['event_id'];
$session = curl_init($request);
break;
case 'add_event':
$request='https://www.googleapis.com/calendar/v3/calendars/'.urlencode($this->cal_id).'/events';
$session = curl_init($request);
curl_setopt ($session, CURLOPT_POST, true);
break;
case 'update_event':
$request = 'https://www.googleapis.com/calendar/v3/calendars/'.urlencode($this->cal_id).'/events/'.$opt['event_id'];
$session = curl_init($request);
curl_setopt($session, CURLOPT_CUSTOMREQUEST, "PUT");
break;
case 'delete_event':
$request='https://www.googleapis.com/calendar/v3/calendars/'.urlencode($this->cal_id).'/events/'.$opt['event_id'];
$session = curl_init($request);
curl_setopt($session, CURLOPT_CUSTOMREQUEST, "DELETE");
break;
}
if($args){
curl_setopt ($session, CURLOPT_POSTFIELDS, $args);
}
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($session, CURLOPT_VERBOSE, true);
curl_setopt($session, CURLINFO_HEADER_OUT, true);
curl_setopt($session, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Authorization: Bearer ' . $this->token,'X-JavaScript-User-Agent: My_company'));
$response = curl_exec($session);
curl_close($session);
return $response;
}
}
And this is how you can use it
//How to use the class:
$gcal=new gcalendar('**calendar_id**');//TO CHANGE
// Add an event
$result=$gcal->add_event(array('start_date'=>'2014-11-20','start_time'=>'12:00','end_date'=>'2014-11-20','end_time'=>'14:00','summary'=>'My event','description'=>'The desc of my event'));
//List events between two dates
// $result=$gcal->list_events('2014-11-01','2014-11-30');
//update an event with ID
// $result=$gcal->update_event('ID_OF_EVENT',array('start_date'=>'2014-11-20','start_time'=>'12:00','end_date'=>'2014-11-20','end_time'=>'14:00','summary'=>'Rdv banane','description'=>'Ceci est une banane'));
//Delete an event with ID
// $result=$gcal->delete_event('ID_OF_EVENT');
//Display result
$res=json_decode($result);
print_r($res);
Hope it will help. If you have any question...
//How to use the class:
$gcal=new gcalendar('**your_mail_adress**');//TO CHANGE
It's not your mail adress here but your calendar id
I am using the script below. Everything was working perfectly fine until 3/13/2013.. I have been pulling my hair out for the past few hours and cannot find the problem at all...
<?php
/**
* PayPal IPN Listener
*
* A class to listen for and handle Instant Payment Notifications (IPN) from
* the PayPal server.
*
* https://github.com/Quixotix/PHP-PayPal-IPN
*
* #package PHP-PayPal-IPN
* #author Micah Carrick
* #copyright (c) 2012 - Micah Carrick
* #version 2.1.0
*/
class IpnListener {
/**
* If true, the recommended cURL PHP library is used to send the post back
* to PayPal. If flase then fsockopen() is used. Default true.
*
* #var boolean
*/
public $use_curl = true;
/**
* If true, explicitly sets cURL to use SSL version 3. Use this if cURL
* is compiled with GnuTLS SSL.
*
* #var boolean
*/
public $force_ssl_v3 = true;
/**
* If true, cURL will use the CURLOPT_FOLLOWLOCATION to follow any
* "Location: ..." headers in the response.
*
* #var boolean
*/
public $follow_location = false;
/**
* If true, an SSL secure connection (port 443) is used for the post back
* as recommended by PayPal. If false, a standard HTTP (port 80) connection
* is used. Default true.
*
* #var boolean
*/
public $use_ssl = true;
/**
* If true, the paypal sandbox URI www.sandbox.paypal.com is used for the
* post back. If false, the live URI www.paypal.com is used. Default false.
*
* #var boolean
*/
public $use_sandbox = true;
/**
* The amount of time, in seconds, to wait for the PayPal server to respond
* before timing out. Default 30 seconds.
*
* #var int
*/
public $timeout = 30;
private $post_data = array();
private $post_uri = '';
private $response_status = '';
private $response = '';
const PAYPAL_HOST = 'www.paypal.com';
const SANDBOX_HOST = 'www.sandbox.paypal.com';
/**
* Post Back Using cURL
*
* Sends the post back to PayPal using the cURL library. Called by
* the processIpn() method if the use_curl property is true. Throws an
* exception if the post fails. Populates the response, response_status,
* and post_uri properties on success.
*
* #param string The post data as a URL encoded string
*/
protected function curlPost($encoded_data) {
if ($this->use_ssl) {
$uri = 'https://'.$this->getPaypalHost().'/cgi-bin/webscr';
$this->post_uri = $uri;
} else {
$uri = 'http://'.$this->getPaypalHost().'/cgi-bin/webscr';
$this->post_uri = $uri;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO,
dirname(__FILE__)."/cert/api_cert_chain.crt");
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
if ($this->force_ssl_v3) {
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
}
$this->response = curl_exec($ch);
$this->response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
if ($this->response === false || $this->response_status == '0') {
$errno = curl_errno($ch);
$errstr = curl_error($ch);
throw new Exception("cURL error: [$errno] $errstr");
}
}
/**
* Post Back Using fsockopen()
*
* Sends the post back to PayPal using the fsockopen() function. Called by
* the processIpn() method if the use_curl property is false. Throws an
* exception if the post fails. Populates the response, response_status,
* and post_uri properties on success.
*
* #param string The post data as a URL encoded string
*/
protected function fsockPost($encoded_data) {
if ($this->use_ssl) {
$uri = 'ssl://'.$this->getPaypalHost();
$port = '443';
$this->post_uri = $uri.'/cgi-bin/webscr';
} else {
$uri = $this->getPaypalHost(); // no "http://" in call to fsockopen()
$port = '80';
$this->post_uri = 'http://'.$uri.'/cgi-bin/webscr';
}
$fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout);
if (!$fp) {
// fsockopen error
throw new Exception("fsockopen error: [$errno] $errstr");
}
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: ".$this->getPaypalHost()."\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: ".strlen($encoded_data)."\r\n";
$header .= "Connection: Close\r\n";
fputs($fp, $header.$encoded_data."\r\n\r\n");
while(!feof($fp)) {
if (empty($this->response)) {
// extract HTTP status from first line
$this->response .= $status = fgets($fp, 1024);
$this->response_status = trim(substr($status, 9, 4));
} else {
$this->response .= fgets($fp, 1024);
}
}
fclose($fp);
}
private function getPaypalHost() {
if ($this->use_sandbox) return self::SANDBOX_HOST;
else return self::PAYPAL_HOST;
}
/**
* Get POST URI
*
* Returns the URI that was used to send the post back to PayPal. This can
* be useful for troubleshooting connection problems. The default URI
* would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr"
*
* #return string
*/
public function getPostUri() {
return $this->post_uri;
}
/**
* Get Response
*
* Returns the entire response from PayPal as a string including all the
* HTTP headers.
*
* #return string
*/
public function getResponse() {
return $this->response;
}
/**
* Get Response Status
*
* Returns the HTTP response status code from PayPal. This should be "200"
* if the post back was successful.
*
* #return string
*/
public function getResponseStatus() {
return $this->response_status;
}
/**
* Get Text Report
*
* Returns a report of the IPN transaction in plain text format. This is
* useful in emails to order processors and system administrators. Override
* this method in your own class to customize the report.
*
* #return string
*/
public function getTextReport() {
$r = '';
// date and POST url
for ($i=0; $i<80; $i++) { $r .= '-'; }
$r .= "\n[".date('m/d/Y g:i A').'] - '.$this->getPostUri();
if ($this->use_curl) $r .= " (curl)\n";
else $r .= " (fsockopen)\n";
// HTTP Response
for ($i=0; $i<80; $i++) { $r .= '-'; }
$r .= "\n{$this->getResponse()}\n";
// POST vars
for ($i=0; $i<80; $i++) { $r .= '-'; }
$r .= "\n";
foreach ($this->post_data as $key => $value) {
$r .= str_pad($key, 25)."$value\n";
}
$r .= "\n\n";
return $r;
}
/**
* Process IPN
*
* Handles the IPN post back to PayPal and parsing the response. Call this
* method from your IPN listener script. Returns true if the response came
* back as "VERIFIED", false if the response came back "INVALID", and
* throws an exception if there is an error.
*
* #param array
*
* #return boolean
*/
public function processIpn($post_data=null) {
$encoded_data = 'cmd=_notify-validate';
if ($post_data === null) {
// use raw POST data
if (!empty($_POST)) {
$this->post_data = $_POST;
$encoded_data .= '&'.file_get_contents('php://input');
} else {
throw new Exception("No POST data found.");
}
} else {
// use provided data array
$this->post_data = $post_data;
foreach ($this->post_data as $key => $value) {
$encoded_data .= "&$key=".urlencode($value);
}
}
if ($this->use_curl) $this->curlPost($encoded_data);
else $this->fsockPost($encoded_data);
if (strpos($this->response_status, '200') === false) {
throw new Exception("Invalid response status: ".$this->response_status);
}
if (strpos($this->response, "VERIFIED") !== false) {
return true;
} elseif (strpos($this->response, "INVALID") !== false) {
return false;
} else {
throw new Exception("Unexpected response from PayPal.");
}
}
/**
* Require Post Method
*
* Throws an exception and sets a HTTP 405 response header if the request
* method was not POST.
*/
public function requirePostMethod() {
// require POST requests
if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') {
header('Allow: POST', true, 405);
throw new Exception("Invalid HTTP request method.");
}
}
}
Look at this link. It seems Paypal changed IPN codes. I'm no expert on this but been struggling to get this resolved until I stumbled upon that link. It seem to be working now, my only problem is the MySQL insert Into code which doesn't seem to insert new record.
http://www.johnboy.com/blog/http-11-paypal-ipn-example-php-code
I had the same problem here, PayPal IPN Listener won't work anymore and found this fix, that maybe can help you.
at near of the end of your IPN Listener,
if (strpos($this->response, "VERIFIED") !== false) {
return true;
} elseif (strpos($this->response, "INVALID") !== false) {
return false;
} else {
throw new Exception("Unexpected response from PayPal.");
}
change "!== false" with "== 0" (equal to zero); in both IF conditions. It works for me!
Now I've just written my ask/self-answer that i've linked up and wait some programmer more experienced than me can confirm and explain this problem (and if I have done right).