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.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License