I am having trouble getting my PayPal Gateway php script to update my database automatically after successful payment. Currently testing in sandbox mode. IPN is enabled.
Anyone have any idea what would be causing the database to not update automatically as shown in paypal_ipn.php?
I noticed that the IPN response from gateway server is blank......
log file....
Code:
[04/25/2012 8:22 AM]
FAIL: fsockopen error no. 0:
php_network_getaddresses: getaddrinfo failed: Name or service not known
IPN POST Vars from gateway:
mc_gross=0.99,
protection_eligibility=Eligible,
address_status=confirmed,
payer_id=C2F3NJ48W5LMA,
tax=0.00,
address_street=1 Main St,
payment_date=08:22:11 Apr 25, 2012 PDT,
payment_status=Completed,
charset=windows-1252,
address_zip=95131,
first_name=Test,
mc_fee=0.33,
address_country_code=US,
address_name=Test User,
notify_version=3.4,
custom=2_1,
payer_status=verified,
business=seller_1316790187_biz@yahoo.com,
address_country=United States,
address_city=San Jose,
quantity=1, verify_sign=A1RtNIP4pI0KEZl1HI0lniHIM6H3AtXKfPsh.8V8J2r92kAfIqvOPfzX, payer_email=japani_1316789859_per@yahoo.com, txn_id=8TE62355N9983493W,
payment_type=instant,
last_name=User,
address_state=CA,
receiver_email=seller_1316790187_biz@yahoo.com,
payment_fee=0.33, receiver_id=NNWHFKJGP9B22,
txn_type=web_accept,
item_name= Premium Account (1 day),
mc_currency=USD,
item_number=1,
residence_country=US,
test_ipn=1,
handling_amount=0.00,
transaction_subject=2_1,
payment_gross=0.99,
shipping=0.00,
ipn_track_id=3ce09ffe5591d,
IPN Response from gateway Server:
PaymentGateway.php
PHP Code:
<?php
/**
* Payment Gateway
*
* This library provides generic payment gateway handling functionlity
* to the other payment gateway classes in an uniform way. Please have
* a look on them for the implementation details.
*
* @package Payment Gateway
* @category Library
* @author Md Emran Hasan <phpfour@gmail.com>
* @link http://www.phpfour.com
*/
abstract class PaymentGateway
{
/**
* Holds the last error encountered
*
* @var string
*/
public $lastError;
/**
* Do we need to log IPN results ?
*
* @var boolean
*/
public $logIpn;
/**
* File to log IPN results
*
* @var string
*/
public $ipnLogFile;
/**
* Initialization constructor
*
* @param none
* @return void
*/
public function __construct()
{
// Some default values of the class
$this->lastError = '';
$this->logIpn = TRUE;
$this->ipnResponse = '';
$this->testMode = FALSE;
}
/**
* Adds a key=>value pair to the fields array
*
* @param string key of field
* @param string value of field
* @return
*/
public function addField($field, $value)
{
$this->fields["$field"] = $value;
}
/**
* Submit Payment Request
*
* Generates a form with hidden elements from the fields array
* and submits it to the payment gateway URL. The user is presented
* a redirecting message along with a button to click.
*
* @param none
* @return void
*/
public function submitPayment()
{
$this->prepareSubmit();
echo "<html>\n";
echo "<head><title>Processing Payment...</title></head>\n";
echo "<body onLoad=\"document.forms['gateway_form'].submit();\">\n";
echo "<p style=\"text-align:center;\"><h2>Please wait, your order is being processed and you";
echo " will be redirected to the payment website.</h2></p>\n";
echo "<form method=\"POST\" name=\"gateway_form\" ";
echo "action=\"" . $this->gatewayUrl . "\">\n";
echo "<p style=\"text-align:center;\"><br/><br/>If you are not automatically redirected to ";
echo "payment website within 5 seconds...<br/><br/>\n";
echo "<input type=\"submit\" value=\"Click Here\"></p>\n";
echo "</form>\n";
echo "</body></html>\n";
}
/**
* Perform any pre-posting actions
*
* @param none
* @return none
*/
protected function prepareSubmit()
{
// Fill if needed
}
/**
* Enables the test mode
*
* @param none
* @return none
*/
abstract protected function enableTestMode();
/**
* Validate the IPN notification
*
* @param none
* @return boolean
*/
abstract protected function validateIpn();
/**
* Logs the IPN results
*
* @param boolean IPN result
* @return void
*/
public function logResults($success)
{
/**
* Paypal Class
*
* Integrate the Paypal payment gateway in your site using this easy
* to use library. Just see the example code to know how you should
* proceed. Btw, this library does not support the recurring payment
* system. If you need that, drop me a note and I will send to you.
*
* @package Payment Gateway
* @category Library
* @author Md Emran Hasan <phpfour@gmail.com>
* @link http://www.phpfour.com
*/
include_once ('../PaymentGateway.php');
class Paypal extends PaymentGateway
{
/**
* Initialize the Paypal gateway
*
* @param none
* @return void
*/
public function __construct()
{
parent::__construct();
// Some default values of the class
$this->gatewayUrl = 'https://www.paypal.com/cgi-bin/webscr';
$this->ipnLogFile = 'paypal.ipn_results.log';
// Populate $fields array with a few default
$this->addField('rm', '2'); // Return method = POST
$this->addField('cmd', '_xclick');
}
/**
* Enables the test mode
*
* @param none
* @return none
*/
public function enableTestMode()
{
$this->testMode = TRUE;
$this->gatewayUrl = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
}
/**
* Validate the IPN notification
*
* @param none
* @return boolean
*/
public function validateIpn()
{
// parse the paypal URL
$urlParsed = parse_url($this->gatewayUrl);
// generate the post string from the _POST vars
$postString = '';
// enable test mode if needed if($config['paypal_test'] == 'true'){ $p->enableTestMode(); }
// let's start the train! $p->submitPayment();
?>
paypal_ipn.php
PHP Code:
<?php
// include header include("../../header.php");
// include the paypal library include_once("Paypal.php");
// create an instance of the paypal library $p = new Paypal();
// check validity and write down it if($p->validateIpn()) { if($p->ipnData['payment_status'] == 'Completed') { // get package id and user id from custom var list($user_id, $package_id) = explode("_", $p->ipnData['custom']);
// get package details $package = mysql_fetch_assoc(mysql_query("SELECT * FROM packages WHERE package_id = '".$package_id."' LIMIT 1"));
// update users fields mysql_query("UPDATE members SET premium = '1', premium_active = '1', premium_start = '".time()."', premium_end = '".strtotime("+" . $package['package_length'] . "days")."' WHERE user_id = '".$user_id."'");
Note the quotes (') around the 'host' key in the $urlParsed array
EDIT: Really good job for posting all the code and the log file, by the way. That will definitely help you to an answer faster! Also, for the record, the IPN response is only blank because the initial request to PayPal with the payment information failed. PayPal can't IPN if it wasn't N'ed about the payment itself!
Last edited by aj_nsc; 04-25-2012 at 12:04 PM.
I've switched careers...
I'm NO LONGER a scientist,
but now a web developer...
awesome.
I don't think sandbox is working for ipn. You got to try with real cash.
This is incorrect. Sandbox works fine for IPN. PayPal has numerous code samples on it's site showing you how to use IPN during live transactions and in the sandbox.
Ok, so the request went through. But I've got my money on the fact that you want this request to be made to the paypal sandbox (looking at your first request with the _biz@yahoo.com which looks like something generated in the PayPal sandbox). You're actually making you're request to the 'live' PayPal API and it's returning that the request was invalid because you're supposed to be checking it via the sandbox URL. Hopefully that wasn't too repetitive.
The solution is built into your class so you can do that easily by adding this line:
PHP Code:
$config['paypal_test'] = true;
right above this:
PHP Code:
// enable test mode if needed if($config['paypal_test'] == 'true'){ $p->enableTestMode(); }
in paypal_start.php
It's important to keep in mind if you are testing in the sandbox, or are performing live transactions and make the changes to your script accordingly.
Good luck.
I've switched careers...
I'm NO LONGER a scientist,
but now a web developer...
awesome.
You are correct, and you are initially posting to the sandbox, that was my bad.
However, in paypal_ipn.php, you are need to enable test-mode again to validate the IPN received. If not, then it tries to validate the IPN received against the 'live' server.
In paypal_ipn.php
1. Include the paypal configuration file in the header of this file and
2. add this line:
// check validity and write down it if($p->validateIpn())
If you don't do this, then PayPal's sandbox sends you out an IPN and you go and ask www.paypal.com if they sent you the request and they will give you a FAILED result (which they did). What you need to do is go and ask www.sandbox.paypal.com to validate the request that they sent you and you will see a valid request, I am positive.
I've switched careers...
I'm NO LONGER a scientist,
but now a web developer...
awesome.
But it's enabled and I am initially taken to the sandbox page during payment. Somewhere along the line it goes to paypal.com instead. I cant figure out where or why that is happening........
paypal_ipn.php is already posted above in the second post
Bookmarks