You Are Here Home > A Paypal IPN Script With Subscription Support

A Paypal IPN Script With Subscription Support

This is just a bare-bone script, you will have to adopt it for your own use, this is to demonstrate how it’s done:

<?php
 
	if (empty($_POST) || @count($_POST) < 1)
		exit;
 
	$query = array('cmd=_notify-validate');
	foreach ($_POST as $key => $val) {
		if (!empty($val))	{
			$query[] = $key .'=' .urlencode($val);
			$$key    = trim(strip_tags($val));
		}
	}
	$query = implode('&', $query);
 
	$has_curl = false;
	if (function_exists('curl_init') && $ch = curl_init()) {
		curl_setopt($ch, CURLOPT_URL, 'http://www.paypal.com/cgi-bin/webscr');
		curl_setopt($ch, CURLOPT_TIMEOUT, 30);
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_USERAGENT, 'Codehead + Curl');
		$result = curl_exec($ch);
		curl_close($ch);
		$has_curl = true;
	}
	if (!$has_curl) {
		$header  = "POST /cgi-bin/webscr HTTP/1.0\r\n";
		$header .= "Host: www.paypal.com\r\n";
		$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
		$header .= "Content-Length: " . strlen($query) . "\r\n\r\n";
		if ($fp = fsockopen(www.paypal.com, 80, $errno, $errstr, 30)) {
			socket_set_timeout($fp, 15);
			fwrite($fp, $header . $query);
			while (!feof($fp)) {
				$result = fgets($fp, 1024);
				if (strcmp($result, 'VERIFIED') == 0)
					break;
			}
			fclose($fp);
		}
	}
 
	if ($result == 'VERIFIED' || strtolower($result) == 'verified') {
 
		if($txn_type == 'subscr_signup') {
			/* Do something */
			exit;
		} else if($txn_type == 'subscr_modify') {
			/* Do something */
			exit;
		} else if($txn_type == 'subscr_cancel') {
			/* Do something */
			exit;
		} else if($txn_type == 'subscr_payment') {
			/* This will go bellow so the payments can be recorded */
		} else if($txn_type == 'subscr_failed') {
			/* Do something */
			exit;
		} else {
			/* Do something */
			exit();
		}
 
		$paypal = array();
		$paypal['user_id'] = $user_id;
		$paypal['payment_date'] = time();
		$paypal['completed_date'] = ($payment_status == 'Completed' ? time() : '');
		$paypal['item_name'] = $item_name;
		$paypal['payment_type'] = $payment_type;
		$paypal['payment_status'] = $payment_status;
		$paypal['pending_reason'] = $pending_reason;
		$paypal['payment_amount'] = $mc_gross;
		$paypal['paypal_fee'] = (isset($mc_fee) ? $mc_fee : 0);
		$paypal['payment_currency'] = $mc_currency;
		$paypal['txn_id'] = $txn_id;
		$paypal['receiver_email'] = $receiver_email;
		$paypal['payer_name'] = $first_name .' ' .$last_name;
		$paypal['payer_email'] = $payer_email;
		$paypal['custom'] = $custom;
		$paypal['raw_payment_data'] = serialize($_POST);
 
		if (DO YOU HAVE A PAYMENT WITH THIS INFO IN THE DB? IF YOU DO, THIS WAS PROBABLY CLEARED SA YOU DONT HAVE ) {
 
			/* Insert this row */
 
		} else if (YOU DO HAVE?) {
 
			/* Update this row */
 
		}
 
		$user = array();
		if ($payment_status == 'Completed') {
			/* Do something */
		} elseif ($payment_status == 'Pending') {
			/* Do something */
		} elseif ($payment_status == 'Failed') {
			/* If this is a subscription payment that is failed, then the code won't reach here and the $txn_type will be 'subscr_failed', see line 57 */
			/* Do something */
		}
	}
 
	header('HTTP/1.1 200 OK');
 
 
?>

I hope this helps someone :)

Update:

One of the ways to experiment with Paypal is to setup some fake payments – in Sandbox of course – and send the $_POST variable that comes to the IPN script in an email to yourself…

A Paypal IPN Script With Subscription Support
Filed under: General, PHP, Web Development   Posted by: Codehead on January 19, 2010

Disclaimer
1 - Use the information provided here at your own risk.
2 - You may not republish this content without prior written consent.




2 Comments »

  1. Karl:
     

    Good example but with which type of txn_type do payment_status go?

    Comment — January 25, 2010 @ 3:42 pm

  2. Codehead:
     

    One of the txn_types is web_accept, you can use Paypal Sandbox and email the $_POST variable to yourself and experiment…

    Comment — January 25, 2010 @ 4:06 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment