* @copyright 2009 Deon George * @link http://osb.leenooks.net * * @link http://www.agileco.com/ * @copyright 2004-2008 Agileco, LLC. * @license http://www.agileco.com/agilebill/license1-4.txt * @author Tony Landis * @package AgileBill * @subpackage Checkout:Paypal */ if (defined('PATH_MODULES')) include_once(PATH_PLUGINS.'checkout/PAYPAL/PAYPAL.php'); else include_once('PAYPAL/PAYPAL.php'); /** * The main AgileBill Paypal Payment Class * * @package AgileBill * @subpackage Checkout:Paypal */ class plg_chout_PAYPAL extends plg_chout_base_PAYPAL { public function __construct($checkout_id=false,$multi=false) { $this->name = 'PAYPAL'; parent::__construct($checkout_id,$multi); $this->recurr_only = false; } # Perform the checkout transaction (new purchase): public function bill_checkout($amount,$invoice,$currency_iso,$acct_fields,$total_recurring=false,$recurr_bill_arr=array(),$invoices=array()) { # Validate we have configured the account if (! $this->cfg['email']) { global $C_debug; $C_debug->alert(_('Sorry, unable to use this payment method, it has not been configured properly.')); return false; } # Validate the currency: if (! $this->validate_currency($currency_iso)) return false; # Special JPY formatting: if ($currency_iso == 'JPY') $amount = round($amount); # Set the vars $vals = array( array('cmd','_cart'), array('upload','1'), array('bn','osb_BuyNow_WPS_AU'), array('no_shipping','1'), array('no_note','1'), array('rm','2'), array('business',$this->cfg['email']), array('tax_cart','0'), array('return',$this->success_url.$invoice), array('cancel_return',$this->decline_url.$invoice), array('notify_url',$this->return_url), array('currency_code',$currency_iso), array('invoice',$invoice), array('first_name',$acct_fields['first_name']), array('last_name',$acct_fields['last_name']), array('payer_business_name',$acct_fields['company']), array('address_street',$acct_fields['address1']), array('address_city',$acct_fields['city']), array('address_state',$acct_fields['state']), array('address_zip',$acct_fields['zip']), array('address_country',$acct_fields['country_id']), array('payer_email',$acct_fields['email']), array('payer_id',$acct_fields['id']) ); if (! $invoices) $invoices[$invoice] = $amount; $i = 1; foreach ($invoices as $id => $total) { array_push($vals,array('item_number_'.$i,'INVOICE')); array_push($vals,array('item_name_'.$i,sprintf('%s - %s #%s',SITE_NAME,_('Invoice'),$id))); array_push($vals,array('amount_'.$i,$total)); $i++; } # Calculate the payment fee to be added switch ($this->cfg['feetype']) { case '2': array_push($vals,array('item_number_'.$i,'PAYFEE')); array_push($vals,array('item_name_'.$i,_('Payment Processing Fee'))); array_push($vals,array('amount_'.$i,round($this->cfg['fee'],2))); break; case '1': array_push($vals,array('item_number_'.$i,'PAYFEE')); array_push($vals,array('item_name_'.$i,_('Payment Processing Fee'))); array_push($vals,array('amount_'.$i,round($amount*$this->cfg['fee'],2))); break; } $this->post_vars(sprintf('%s/cgi-bin/webscr',$this->getLocation()),$vals); return true; } # Postback Validation public function postback() { # Read the post from PayPal system and add 'cmd' global $_POST,$C_debug; $req = 'cmd=_notify-validate'; foreach ($_POST as $key => $value) { $value = urlencode(stripslashes($value)); $req .= sprintf('&%s=%s',$key,$value); } $C_debug->error(__FILE__,__METHOD__,sprintf("%s: %s - Invoice: %s\r\n%s",$this->name,$_POST['txn_type'],$_POST['invoice'],$req)); # Post back to PayPal system to validate $header = "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= sprintf("Content-Length: %s\r\n\r\n",strlen($req)); $fp = fsockopen($this->getLocation(false,true),80,$errno,$errstr,30); # Needed for validation $ret['invoice_id'] = $_POST['invoice']; $ret['transaction_id'] = $_POST['txn_id']; $ret['currency'] = $_POST['mc_currency']; if (! empty($_POST['mc_gross'])) $ret['amount'] = $_POST['mc_gross']; else $ret['amount'] = $_POST['payment_gross']; # Validate if (! $fp) { $C_debug->error(__FILE__,__METHOD__,sprintf('Unable to connect to %s',$this->getLocation(false,true))); } else { fputs($fp,$header.$req); while (! feof($fp)) { $res = trim(strtoupper(fgets($fp,1024))); # HTTP traffic if (! $res || preg_match('/^HTTP/',$res) || preg_match('/^DATE/',$res) || preg_match('/^SERVER/',$res) || preg_match('/^SET-COOKIE/',$res) || preg_match('/^CONNECTION/',$res) || preg_match('/^CONTENT-TYPE/',$res)) continue; switch ($res) { case 'VERIFIED': # Get the payment status $ret['status'] = true; switch($_POST['txn_type']) { case 'cart': $ret['status'] = true; break; default: $ret['status'] = false; break; } if ($ret['status'] != false) { switch($_POST['payment_status']) { case 'Canceled_Reversal': $ret['status'] = true; break; case 'Completed': $ret['status'] = true; break; default: $ret['status'] = false; break; } } # Get the processor details $this->getDetailsName($this->name); $cfg = unserialize($this->flds['plugin_data']); if ($_POST['receiver_email'] == $cfg['email']) { include_once(PATH_MODULES.'checkout/checkout.inc.php'); $checkout = new checkout; $checkout->postback($ret); } fclose($fp); header('HTTP/1.1 200 OK'); header('Status: 200 OK'); return; break; default: # Log for manual investigation $C_debug->error(__FILE__,__METHOD__,sprintf('Postback for Invoice %s is %s (%s)',$ret['invoice_id'],$res,serialize($res))); fclose($fp); header('HTTP/1.0 404 Not Found'); return false; } } } header('HTTP/1.0 500 Temporary Failure'); } } # Postback Function if (empty($VAR) && empty($VAR['do'])) { include_once('../../config.inc.php'); require_once(PATH_ADODB.'adodb.inc.php'); require_once(PATH_CORE.'database.inc.php'); require_once(PATH_CORE.'setup.inc.php'); $C_debug = new CORE_debugger; $C_db = &DB(); $C_setup = new CORE_setup; $plg = new plg_chout_PAYPAL; $plg->postback(); } ?>