using paypal ipn with kohana
Using the script at:
http://www.19.5degs.com/element/369.php
Create a new file called: application/librairies/Paypal_ipn.php
<?php defined('SYSPATH') OR die('No direct access allowed.');
/**
* Paypal IPN library.
*/
class Paypal_ipn_Core {
var $paypal_post_vars;
var $paypal_response;
var $timeout;
var $error_email;
function __construct($paypal_post_vars) {
$this->paypal_post_vars = $paypal_post_vars;
$this->timeout = 120;
}
function send_response($paypal_host)
{
$fp = @fsockopen($paypal_host, 80, &$errno, &$errstr, 120 );
if (!$fp) {
$this->error_out("PHP fsockopen() error: " . $errstr , "");
} else {
foreach($this->paypal_post_vars AS $key => $value) {
if (@get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
$values[] = "$key" . "=" . urlencode($value);
}
$response = @implode("&", $values);
$response .= "&cmd=_notify-validate";
fputs( $fp, "POST /cgi-bin/webscr HTTP/1.0\r\n" );
fputs( $fp, "Content-type: application/x-www-form-urlencoded\r\n" );
fputs( $fp, "Content-length: " . strlen($response) . "\r\n\n" );
fputs( $fp, "$response\n\r" );
fputs( $fp, "\r\n" );
$this->send_time = time();
$this->paypal_response = "";
// get response from paypal
while (!feof($fp)) {
$this->paypal_response .= fgets( $fp, 1024 );
if ($this->send_time < time() - $this->timeout) {
$this->error_out("Timed out waiting for a response from PayPal. ($this->timeout seconds)" , "");
}
}
fclose( $fp );
}
}
function is_verified() {
if( ereg("VERIFIED", $this->paypal_response) )
return true;
else
return false;
}
function get_payment_status() {
if(empty($this->paypal_post_vars['payment_status'])) {
return "Recurring"; //HACKY
} else {
return $this->paypal_post_vars['payment_status'];
}
}
function error_out($message, $em_headers)
{
$message .= "\n\nThe following data was received from PayPal:\n\n";
@reset($this->paypal_post_vars);
while( @list($key,$value) = @each($this->paypal_post_vars)) {
$message .= $key . ':' . " \t$value\n";
}
mail($this->error_email, "paypay_ipn notification", $message, $em_headers);
}
}
?>
Create a controller application/controller/ipn.php
<?php defined('SYSPATH') or die('No direct script access.');
class Ipn_Controller extends Controller {
public function index() {
//$paypal_host = "www.paypal.com";
$paypal_host = "www.sandbox.paypal.com";
// paypal email
$paypal_email = "yourpaypal@email.com";
$error_email = "email@email.com";
// email header
$em_headers = "From: You <email@email.com>\n";
$em_headers .= "Reply-To: email@email.com\n";
$em_headers .= "Return-Path: email@email.com\n";
$em_headers .= "Organization: Your Business\n";
$em_headers .= "X-Priority: 3\n";
$paypal_ipn = new Paypal_ipn($_POST);
foreach ($paypal_ipn->paypal_post_vars as $key=>$value) {
if (getType($key)=="string") {
eval("\$$key=\$value;");
}
}
$paypal_ipn->send_response($paypal_host);
$paypal_ipn->error_email = $error_email;
if (!$paypal_ipn->is_verified()) {
$paypal_ipn->error_out("Bad order (PayPal says it's invalid)" . $paypal_ipn->paypal_response , $em_headers);
die();
}
switch( $paypal_ipn->get_payment_status() )
{
case 'Pending':
$pending_reason=$paypal_ipn->paypal_post_vars['pending_reason'];
if ($pending_reason!="intl") {
$paypal_ipn->error_out("Pending Payment - $pending_reason", $em_headers);
break;
}
case 'Completed':
if ($paypal_ipn->paypal_post_vars['txn_type']=="reversal") {
$reason_code=$paypal_ipn->paypal_post_vars['reason_code'];
$paypal_ipn->error_out("PayPal reversed an earlier transaction.", $em_headers);
// you should mark the payment as disputed now
} else {
if ((strtolower(trim($paypal_ipn->paypal_post_vars['business'])) == $paypal_email)) { //maybe more check here
//$qry="INSERT INTO paypal_table VALUES (0 , '$payer_id', '$payment_date', '$txn_id', '$first_name', '$last_name', '$payer_email', '$payer_status', '$payment_type', '$memo', '$item_name', '$item_number', $quantity, $mc_gross, '$mc_currency', '$address_name', '".nl2br($address_street)."', '$address_city', '$address_state', '$address_zip', '$address_country', '$address_status', '$payer_business_name', '$payment_status', '$pending_reason', '$reason_code', '$txn_type')";
//if (mysql_query($qry)) {
$paypal_ipn->error_out("This was a successful transaction", $em_headers);
// you should add your code for sending out the download link to your customer at $payer_email here.
//} else {
//$paypal_ipn->error_out("This was a duplicate transaction", $em_headers);
//}
} else {
$paypal_ipn->error_out("Someone attempted a sale using a manipulated URL", $em_headers);
}
}
break;
case 'Failed':
// this will only happen in case of echeck.
$paypal_ipn->error_out("Failed Payment", $em_headers);
break;
case 'Denied':
// denied payment by us
$paypal_ipn->error_out("Denied Payment", $em_headers);
break;
case 'Refunded':
// payment refunded by us
$paypal_ipn->error_out("Refunded Payment", $em_headers);
break;
case 'Canceled':
// reversal cancelled
// mark the payment as dispute cancelled
$paypal_ipn->error_out("Cancelled reversal", $em_headers);
break;
case 'Recurring':
$paypal_ipn->error_out("Recurring billing", $em_headers);
break;
default:
// order is not good
$paypal_ipn->error_out("Unknown Payment Status - " . $paypal_ipn->get_payment_status(), $em_headers);
break;
}
}
}
Modify for your needs.
page revision: 6, last edited: 02 Apr 2009 17:47