so I've been trying to set up Paypal IPN, and been trying tonnes of different solutions to get my IPN to validate. For some reason, it works fine when I'm using Sanbox paypal, but as soon as I try to use the live version, nothing happens. No error logs, no IPN logs, nothing. I'm just lost.
I was wondering if any new eyes would spot the problem. Here's my paypal.php class:
<?php
session_start();
$base = "/var/www/html/";
include("db.php");
require_once('paypal.class.php'); // include the class file
$p = new paypal_class; // initiate an instance of the class
//$p->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; // testing paypal url
$p->paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; // paypal url
// setup a variable for this script (ie: 'http://www.micahcarrick.com/paypal.php')
$this_script = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
// if there is not action variable, set the default action of 'process'
if (empty($_GET['action'])) $_GET['action'] = 'process';
if (empty($_GET['amm'])) $_GET['amm'] = '1';
$EMAIL = 'emailaddresshere';
switch ($_GET['action']) {
case 'process': // Process and order...
if (empty($_GET['prod'])){
header("Location: confirm-product.php"); //Was donate.php (but no file for that, so might be confirm-product)
exit;
}
if (empty($_GET['username'])){
if($_GET['action'] = 'process'){
header("Location: confirm-product.php"); // was donate.php as well
exit;
}
}
//if(!isset($_SESSION["username"])) {
// header("Location: login.php");
// exit;
//}
//include("include.php");
//die("donation is temporarily disabled!");
// There should be no output at this point. To process the POST data,
// the submit_paypal_post() function will output all the HTML tags which
// contains a FORM which is submited instantaneously using the BODY onload
// attribute. In other words, don't echo or printf anything when you're
// going to be calling the submit_paypal_post() function.
// This is where you would have your form validation and all that jazz.
// You would take your POST vars and load them into the class like below,
// only using the POST values instead of constant string expressions.
// For example, after ensureing all the POST variables from your custom
// order form are valid, you might have:
//
// $p->add_field('first_name', $_POST['first_name']);
// $p->add_field('last_name', $_POST['last_name']);
$price = '10.00';
if($_GET['prod'] == 1)
$price = '10.00';
if($_GET['prod'] == 2)
$price = '45.00';
if($_GET['prod'] == 3)
$price = '80.00';
if($_GET['prod'] == 4)
$price = '300.00';
if($_GET['prod'] == 5) //remove/change prod 5 after testing
$price = '0.01';
$name = '1K Donator Points';
if ($_GET['prod'] == 1)
$name = '1K Donator Points';
if ($_GET['prod'] == 2)
$name = '5K Donator Points';
if ($_GET['prod'] == 3)
$name = '10K Donator Points';
if ($_GET['prod'] == 4)
$name = '50K Donator Points';
if ($_GET['prod'] == 5)
$name = 'Testing Payment';
$p->add_field('custom', $_GET['username']);
$p->add_field('business', $EMAIL);
$p->add_field('return', $this_script.'?action=success');
$p->add_field('cancel_return', $this_script.'?action=cancel');
$p->add_field('notify_url', $this_script.'?action=ipn');
$p->add_field('item_name', ''.$name);
$p->add_field('item_number', $_GET['prod']);
$p->add_field('currency_code', 'USD');
$p->add_field('amount', $price);
//$p->add_field('quantity', $_GET['amm']);
$p->add_field('lc', 'GB');
$p->submit_paypal_post(); // submit the fields to paypal
// $p->dump_fields(); // for debugging, output a table of all the fields
break;
case 'success': // Order was successful...
// This is where you would probably want to thank the user for their order
// or what have you. The order information at this point is in POST
// variables. However, you don't want to "process" the order until you
// get validation from the IPN. That's where you would have the code to
// email an admin, update the database with payment status, activate a
// membership, etc.
//include("include.php");
echo "<h2>Donation Successful</h2><p>Your payment has been completed.</p>";
// You could also simply re-direct them to another page, or your own
// order status page which presents the user with the status of their
// order based on a database (which can be modified with the IPN code
// below).
break;
case 'cancel': // Order was canceled...
// The order was canceled before being completed.
//include("include.php");
echo "<h2>Payment Cancelled</h2><p>Your payment was cancelled.</p>";
break;
case 'ipn': // Paypal is calling page for IPN validation...
// It's important to remember that paypal calling this script. There
// is no output here. This is where you validate the IPN data and if it's
// valid, update your database to signify that the user has payed. If
// you try and use an echo or printf function here it's not going to do you
// a bit of good. This is on the "backend". That is why, by default, the
// class logs all IPN data to a text file.
if ($p->validate_ipn()) {
error_log("Made it to validating IPN", 3, "myerrors.log");
// Payment has been recieved and IPN is verified. This is where you
// update your database to activate or process the order, or setup
// the database with the user's order details, email an administrator,
// etc. You can access a slew of information via the ipn_data() array.
// Check the paypal documentation for specifics on what information
// is available in the IPN POST variables. Basically, all the POST vars
// which paypal sends, which we send back for validation, are now stored
// in the ipn_data() array.
if($p->ipn_data["payment_status"] != "Completed") die();
error_log("Payment Status = Completed, if this message shows - ", 3, "myerrors.log");
if($p->ipn_data["mc_gross"] > 0 && strcmp ($p->ipn_data["business"],$EMAIL) == 0) {
error_log("Blah blah blah 33", 3, "myerrors.log");
$user = $p->ipn_data["custom"];
$date = $p->ipn_data["payment_date"];
$prodid = $p->ipn_data["item_number"];
$amount = $p->ipn_data["mc_gross"];
$amountTickets = 1;
$user = str_replace("-", "_", $user);
$user = str_replace(" ", "_", $user);
$user = mysqli_real_escape_string($mysqli, $user);
$prodid = mysqli_real_escape_string($mysqli, $prodid);
$amount = mysqli_real_escape_string($mysqli, $amount);
$mysqli = new mysqli("host", "name", "pass", "db");
if ($mysqli->connect_error) {
// error_log("Connection Failed to Database", 3, "myerrors.log");
}
$query = "INSERT INTO donation (username, time, productid, price, tickets) VALUES ('".$user."', '".$date."', '".$prodid."', '".$amount."', '".$amountTickets."');";
$mysqli->query($query);
//
error_log("Passed through MySql Table insertion lines.", 3, "myerrors.log");
}
error_log(" - Finished validating IPN process.", 3, "myerrors.log");
}
break;
}
?>
And here's my paypal.class.php class
<?php
/*******************************************************************************
* PHP Paypal IPN Integration Class
*******************************************************************************
* Author: Micah Carrick
* Email: email#micahcarrick.com
* Website: http://www.micahcarrick.com
*
* File: paypal.class.php
* Version: 1.3.0
* Copyright: (c) 2005 - Micah Carrick
* You are free to use, distribute, and modify this software
* under the terms of the GNU General Public License. See the
* included license.txt file.
*
*******************************************************************************
*/
class paypal_class {
var $last_error; // holds the last error encountered
var $ipn_log; // bool: log IPN results to text file?
var $ipn_log_file; // filename of the IPN log
var $ipn_response; // holds the IPN response from paypal
var $ipn_data = array(); // array contains the POST values for IPN
var $fields = array(); // array holds the fields to submit to paypal
public $timeout = 30;
private $post_data = array();
private $post_uri = '';
private $response_status = '';
private $response = '';
const PAYPAL_HOST = 'www.paypal.com';
function paypal_class() {
// initialization constructor. Called when class is created.
$this->paypal_url = 'https://www.paypal.com/cgi-bin/webscr'; //real one
// $this->paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; //testing one
$this->last_error = '';
$this->ipn_log_file = '.ipn_results.log';
$this->ipn_log = true;
$this->ipn_response = '';
// populate $fields array with a few default values. See the paypal
// documentation for a list of fields and their data types. These defaul
// values can be overwritten by the calling script.
$this->add_field('rm','2'); // Return method = POST
$this->add_field('cmd','_xclick');
}
public function getPostUri() {
return $this->post_uri;
}
function add_field($field, $value) {
// adds a key=>value pair to the fields array, which is what will be
// sent to paypal as POST variables. If the value is already in the
// array, it will be overwritten.
$this->fields["$field"] = $value;
}
function submit_paypal_post() {
// this function actually generates an entire HTML page consisting of
// a form with hidden elements which is submitted to paypal via the
// BODY element's onLoad attribute. We do this so that you can validate
// any POST vars from you custom form before submitting to paypal. So
// basically, you'll have your own form which is submitted to your script
// to validate the data, which in turn calls this function to create
// another hidden form and submit to paypal.
// The user will briefly see a message on the screen that reads:
// "Please wait, your order is being processed..." and then immediately
// is redirected to paypal.
echo "<html>\n";
echo "<head><title>Processing Payment...</title></head>\n";
echo "<body onLoad=\"document.forms['paypal_form'].submit();\">\n";
echo "<center><h2>Please wait, your order is being processed and you";
echo " will be redirected to the paypal website.</h2></center>\n";
echo "<form method=\"post\" name=\"paypal_form\" ";
echo "action=\"".$this->paypal_url."\">\n";
foreach ($this->fields as $name => $value) {
echo "<input type=\"hidden\" name=\"$name\" value=\"$value\"/>\n";
}
echo "<center><br/><br/>If you are not automatically redirected to ";
echo "paypal within 5 seconds...<br/><br/>\n";
echo "<input type=\"submit\" value=\"Click Here\"></center>\n";
echo "</form>\n";
echo "</body></html>\n";
}
function validate_ipn() {
// parse the paypal URL
// $url_parsed=parse_url($this->paypal_url);
error_log(" - Parsed URL.", 3, "myerrors.log"); //remove after
// generate the post string from the _POST vars aswell as load the
// _POST vars into an arry so we can play with them from the calling
// script.
$post_string = ''; //old
// $post_string="cmd=_notify-validate"; //new
foreach ($_POST as $field=>$value) {
$this->ipn_data["$field"] = $value;
$post_string .= $field.'='.urlencode(stripslashes($value)).'&'; //old
// $post_string .= '&' . $field.'='.urlencode(stripslashes($value)); //new
}
$post_string.="cmd=_notify-validate"; // append ipn command
error_log(" - Into ValidatingIPN, Line 187.", 3, "myerrors.log"); //remove after
// open the connection to paypal
// $fp = fsockopen($url_parsed['host'], 443, $errnum, $errstr, 30); //old real one
// $fp = fsockopen('ssl://www.paypal.com', 443, $errnum, $errstr, 30); //try this
// $fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30); //try this
// $fp = fsockopen('https://www.paypal.com', 443, $errnum, $errstr, 30);
// $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); //testing one
/* if ($url_parsed['scheme'] == 'https') {
$url_parsed['port'] = 443;
$ssl = 'ssl://';
} else {
$url_parsed['port'] = 80;
$ssl = '';
}
$fp = fsockopen($ssl.$url_parsed['host'], $url_parsed['port'], $errnum, $errstr, 30); */
//Real One v2
$uri = 'ssl://www.paypal.com';
$port = '443';
$this->post_uri = $uri.'/cgi-bin/webscr';
$fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout);
if(!$fp) {
throw new Exception("fsockopen error: [$errno] $errstr");
}
// Post the data back to paypal
// fputs($fp, "POST $url_parsed[path] HTTP/1.1\r\n"); //old
/* fputs($fp, "POST /cgi-bin/webscr HTTP/1.1\r\n");
fputs($fp, "Host: www.sandbox.paypal.com\r\n"); //sandbox - www.sandbox.paypal.com
fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-Length: ".strlen($post_string)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $post_string . "\r\n\r\n"); */
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.paypal.com\r\n"; //real - www.paypal.com
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: ".strlen($post_string)."\r\n";
$header .= "Connection: Close\r\n\r\n";
fputs($fp, $header.$post_string."\r\n\r\n");
error_log(" - Connected to paypal connection. Posted Data to paypal.", 3, "myerrors.log"); //remove after
// loop through the response from the server and append to variable
while(!feof($fp)) {
$this->ipn_response .= fgets($fp, 1024); //old
}
fclose($fp); // close connection
// if (eregi("VERIFIED",$this->ipn_response)) { //old
if (preg_match("VERIFIED", $this->ipn_response)) { //new ~VERIFIED~i for sandbox
// Valid IPN transaction.
error_log(" - Valid IPN Transaction.", 3, "myerrors.log"); //remove after
$this->log_ipn_results(true);
return true;
} else {
// Invalid IPN transaction. Check the log for details.
$this->last_error = 'IPN Validation Failed.';
error_log(" - IPN Validation Failed", 3, "myerrors.log"); //remove after
$this->log_ipn_results(true); //Default: false
return false;
}
}
function log_ipn_results($success) {
if (!$this->ipn_log) return; // is logging turned off?
// Timestamp
$text = '['.date('m/d/Y g:i A').'] - ';
// Success or failure being logged?
if ($success) $text .= "SUCCESS!\n";
else $text .= 'FAIL: '.$this->last_error."\n";
// Log the POST variables
$text .= "IPN POST Vars from Paypal:\n";
foreach ($this->ipn_data as $key=>$value) {
$text .= "$key=$value, ";
}
// Log the response from the paypal server
$text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response;
// Write to log
$fp=fopen($this->ipn_log_file,'a');
fwrite($fp, $text . "\n\n");
fclose($fp); // close file
}
function dump_fields() {
// Used for debugging, this function will output all the field/value pairs
// that are currently defined in the instance of the class using the
// add_field() function.
echo "<h3>paypal_class->dump_fields() Output:</h3>";
echo "<table width=\"95%\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\">
<tr>
<td bgcolor=\"black\"><b><font color=\"white\">Field Name</font></b></td>
<td bgcolor=\"black\"><b><font color=\"white\">Value</font></b></td>
</tr>";
ksort($this->fields);
foreach ($this->fields as $key => $value) {
echo "<tr><td>$key</td><td>".urldecode($value)." </td></tr>";
}
echo "</table><br>";
}
}
I have to use dodirect payment method after the form submission. The form will be displayed on the site for all the card detail such as card type (visa or master), card card no, security number, expiration date, name on card, address, state, postal, country, phone, email etc.
I searched how to use the dodirect method and found as below
<?php
/** DoDirectPayment NVP example; last modified 08MAY23.
*
* Process a credit card payment.
*/
$environment = 'sandbox'; // or 'beta-sandbox' or 'live'
/**
* Send HTTP POST Request
*
* #param string The API method name
* #param string The POST Message fields in &name=value pair format
* #return array Parsed HTTP Response body
*/
function PPHttpPost($methodName_, $nvpStr_) {
global $environment;
// Set up your API credentials, PayPal end point, and API version.
$API_UserName = urlencode('my_api_username');
$API_Password = urlencode('my_api_password');
$API_Signature = urlencode('my_api_signature');
$API_Endpoint = "https://api-3t.paypal.com/nvp";
if("sandbox" === $environment || "beta-sandbox" === $environment) {
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
}
$version = urlencode('51.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if(!$httpResponse) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
// Set request-specific fields.
$paymentType = urlencode('Authorization'); // or 'Sale'
$firstName = urlencode('customer_first_name');
$lastName = urlencode('customer_last_name');
$creditCardType = urlencode('customer_credit_card_type');
$creditCardNumber = urlencode('customer_credit_card_number');
$expDateMonth = 'cc_expiration_month';
// Month must be padded with leading zero
$padDateMonth = urlencode(str_pad($expDateMonth, 2, '0', STR_PAD_LEFT));
$expDateYear = urlencode('cc_expiration_year');
$cvv2Number = urlencode('cc_cvv2_number');
$address1 = urlencode('customer_address1');
$address2 = urlencode('customer_address2');
$city = urlencode('customer_city');
$state = urlencode('customer_state');
$zip = urlencode('customer_zip');
$country = urlencode('customer_country'); // US or other valid country code
$amount = urlencode('example_payment_amuont');
$currencyID = urlencode('USD'); // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
// Add request-specific fields to the request string.
$nvpStr = "&PAYMENTACTION=$paymentType&AMT=$amount&CREDITCARDTYPE=$creditCardType&ACCT=$creditCardNumber".
"&EXPDATE=$padDateMonth$expDateYear&CVV2=$cvv2Number&FIRSTNAME=$firstName&LASTNAME=$lastName".
"&STREET=$address1&CITY=$city&STATE=$state&ZIP=$zip&COUNTRYCODE=$country&CURRENCYCODE=$currencyID";
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('DoDirectPayment', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
exit('Direct Payment Completed Successfully: '.print_r($httpParsedResponseAr, true));
} else {
exit('DoDirectPayment failed: ' . print_r($httpParsedResponseAr, true));
}
?>
I didn't get an idea how to use this code on submission of the form that I have on my site. Can anyone help me out how to use this after submitting form.
Thanks in advance :)
That's really not a very well built function. It's basically wanting you to just fill in the values within the function rather than pass them in. It's a pretty rough example and you can see it was last updated in 2008 according to the comments.
If you want to use it, though, you can simply fill in all those placeholders where they show things like "my_api_username" with the data that you want to actually include.
If you want something a lot easier to work with, I would recommend using this PHP library for PayPal that I developed and have maintained for years. It's current and contains straight forward samples for running DoDirectPayment. You could have it up-and-running within minutes.
I offer 30 min of free training via screen share, too, if you're interested in that.
Actually there are samples available for DoDirectPayment as part of the official SDKs available at https://www.x.com/developers/paypal/documentation-tools/paypal-sdk-index#expresscheckoutnew
Suggest using the official SDK and check the samples inside them. In case of any issues please post back here or open an issue at https://github.com/paypal/merchant-sdk-php/issues
I have been attempting to implement a paypal functionality into my application by following the example here: http://www.alexventure.com/2011/04/02/zend-framework-and-paypal-api-part-2-of-2/
This is my paymentAction in my controller.
public function paymentAction()
{
$auth= Zend_Auth::getInstance();
$user= $auth->getIdentity();
$username = $user->username;
$cart = new Application_Model_DbTable_Cart();
$select = $cart->select()
->from(array('c' => 'cart'))
->join(array('p' => 'product'), 'p.productid = c.productid')
->where('username = ?', $username)
->setIntegrityCheck(false);
$fetch = $cart->fetchAll($select)->toArray();
$paypal = new My_Paypal_Client;
$amount = 0.0;
foreach($fetch as $item) {
$amount = $amount + ($item['price']*$item['quantity']);
}
$returnURL = 'http://www.google.com';
$cancelURL = 'http://www.yahoo.com';
$currency_code = 'USD';
$reply = $paypal->ecSetExpressCheckout(
$amount,
$returnURL,
$cancelURL,
$currency_code
);
if ($reply->isSuccessfull())
{
$replyData = $paypal->parse($reply->getBody());
if ($replyData->ACK == 'SUCCESS' || $replyData->ACK == 'SUCCESSWITHWARNING')
{
$token = $replyData->TOKEN;
$_SESSION['CHECKOUT_AMOUNT'] = $amount;
header(
'Location: ' .
$paypal->api_expresscheckout_uri .
'?&cmd=_express-checkout&token=' . $token
);
}
}
else
{
throw new Exception('ECSetExpressCheckout: We failed to get a successfull response from PayPal.');
}
}
However, this is the error that returns.
Message: No valid URI has been passed to the client
Where did i go wrong? I would be happy to provide code from other areas of my application if needed. Thanks.
Zend_Http_Client::request() has not received a valid instance of Zend_Uri_Http.
Here's where the error occurs:
/**
* Send the HTTP request and return an HTTP response object
*
* #param string $method
* #return Zend_Http_Response
* #throws Zend_Http_Client_Exception
*/
public function request($method = null)
{
if (! $this->uri instanceof Zend_Uri_Http) {
/** #see Zend_Http_Client_Exception */
require_once 'Zend/Http/Client/Exception.php';
throw new Zend_Http_Client_Exception('No valid URI has been passed to the client');//Note the exact message.
}//Truncated
The only obvious error I see in the code you provided is :
$paypal = new My_Paypal_Client;//no () at end of declaration
I hope you implemented part one of the tutorial where the constructor is built. Otherwise you may just need to pass a better uri.
[EDIT]
I think your problem is here:
//needs a uri value for Zend_Http_Client to construct
$paypal = new My_Paypal_Client($url);
ecSetExpressCheckout does not construct the http client so it has no idea of where it's requesting the token from.
Alternatively you could just add this line below $paypal and above $reply:
//pass the uri required to construct Zend_Http_Client
$paypal->setUri($url);
I just hope you know what the url shouild be.
Good Luck.
I have seen a few similar questions but I think this is new...
I am trying to add a popover on a blog that will contain a Facebook like button for a Facebook page and wil only show if the user does not already like the Facebook page.
Reading through the documentation this should be achievable with the Graph API pages.isFan method but does this require the user to give permissions? If so would it be possible to not have the app request permissions but rather fail gracefully?
Any help much appreciated.
You can tell if a user likes a page from the signed_request which is sent in the request from facebook. You don't have to query the graph api.
We use c# and get it like so:
protected void Page_Load(object sender, EventArgs e)
{
Result = DecodePayload(Request["signed_request"]);
}
public JObject DecodePayload(string payload)
{
var encoding = new UTF8Encoding();
var decodedJson = payload.Split('.')[1].Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
Json = encoding.GetString(base64JsonArray);
var result = JObject.Parse(Json);
return result;
}
Then in the page
<% if (Result["page"] == null || Result["page"]["liked"] == null || !(bool) Result["page"]["liked"])
{%>
Content if liked
<%}%>
One more important thing as of the 30th March the page layout is changing to timeline and you should be aware of a bug currently that does not refresh the page upon liking it see this:
Does anyone know a fix for the lack of page refresh on facebook timeline pages when liking?
UPDATE
The php for decoding the signed request is:
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
I have created a application and connected it to a fan page so that application content is loaded in that page.
To access user_id and name of user can only be accessed if user have authorized the application.
How application can be authorized at the same time as user have liked the page?
I mean that when user clicks on like page button application authorization dialog box should also appear. Or if i am wrong please suggest the right way.
--- EDIT ----
I am using php-sdk v3.1.1.
This isn't possible, the page like button is not connected in any way to your application.
What you can do is parse the signed_request parameter which is passed to your application to check if the user has liked the page, if he did you can then check if you can get the user object and redirect him to authorization if needed.
If you don't need the user id or any other extended features (such as posting to the wall) and just want to check if a user has liked the page you can just use the signed request and forget about the rest of the authorization.
You can decode the signed_request using your application secret key and the following function:
function parse_signed_request_outside($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode_outside($encoded_sig);
$data = json_decode(base64_url_decode_outside($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode_outside($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
In order to determine the like you need to do the following:
$secret = "SECRET KEY";
$decodedSignedRequest = parse_signed_request_outside($_REQUEST['signed_request'], $secret);
if ($decodedSignedRequest['page']['liked'] == 1){
{
// load content
}