2008-11-26 22:50:40 +00:00
< ? php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software ; you can redistribute it and / or
* modify it under the terms of the Open AgileBill License
* License as published at http :// www . agileco . com / agilebill / license1 - 4. txt
2009-08-03 04:10:16 +00:00
*
* Originally authored by Tony Landis , AgileBill LLC
*
* Recent modifications by Deon George
*
* @ author Deon George < deonATleenooksDOTnet >
* @ copyright 2009 Deon George
* @ link http :// osb . leenooks . net
2008-11-26 22:50:40 +00:00
*
* @ link http :// www . agileco . com /
* @ copyright 2004 - 2008 Agileco , LLC .
* @ license http :// www . agileco . com / agilebill / license1 - 4. txt
2009-08-03 04:10:16 +00:00
* @ author Tony Landis < tony @ agileco . com >
2008-11-26 22:50:40 +00:00
* @ package AgileBill
2009-08-03 04:10:16 +00:00
* @ subpackage Checkout : Paypal
2008-11-26 22:50:40 +00:00
*/
2009-08-03 04:10:16 +00:00
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_RECURRING extends plg_chout_base_PAYPAL {
public function __construct ( $checkout_id = false , $multi = false ) {
$this -> name = 'PAYPAL_RECURRING' ;
parent :: __construct ( $checkout_id , $multi );
$this -> recurr_only = true ;
2008-11-26 22:50:40 +00:00
}
# Perform the checkout transaction (new purchase):
2009-08-03 04:10:16 +00:00
public function bill_checkout ( $amount , $invoice , $currency_iso , $acct_fields , $total_recurring = false , $recurr_bill_arr = array ()) {
global $C_debug ;
# Validate we have configured the account
if ( ! $this -> cfg [ 'email' ]) {
$C_debug -> alert ( _ ( 'Sorry, unable to use this payment method, it has not been configured properly.' ));
return false ;
}
2008-11-26 22:50:40 +00:00
# Validate the currency:
2009-08-03 04:10:16 +00:00
if ( ! $this -> validate_currency ( $currency_iso ))
return false ;
2008-11-26 22:50:40 +00:00
# Special JPY formatting:
2009-08-03 04:10:16 +00:00
if ( $currency_iso == 'JPY' )
$amount = round ( $amount );
2008-11-26 22:50:40 +00:00
# Get the regular period for this subscription:
2009-08-03 04:10:16 +00:00
switch ( $recurr_bill_arr [ 0 ][ 'recurr_schedule' ]) {
case 0 : $p3 = '1' ; $t3 = 'W' ; break ;
case 1 : $p3 = '1' ; $t3 = 'M' ; break ;
case 2 : $p3 = '3' ; $t3 = 'M' ; break ;
case 3 : $p3 = '6' ; $t3 = 'M' ; break ;
case 4 : $p3 = '1' ; $t3 = 'Y' ; break ;
case 5 : $p3 = '2' ; $t3 = 'Y' ; break ;
default :
$C_debug -> error ( __FILE__ , __METHOD__ , sprintf ( 'Unknown recurr_schedule %s' , $recurr_bill_arr [ 0 ][ 'recurr_schedule' ]));
return false ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
# Calculate the payment fee to be adde
$fee = $fee_recurring = 0 ;
switch ( $this -> cfg [ 'feetype' ]) {
case '2' :
$fee = $fee_recurring = $this -> cfg [ 'fee' ];
printf ( '<script type="text/javascript">alert("%s")</script>' ,
sprintf ( _ ( 'Please note, a payment processing fee of %3.2f will automatically be added to this payment schedule.' ), $this -> cfg [ 'fee' ]));
break ;
case '1' :
$fee = round ( $amount * $this -> cfg [ 'fee' ], 2 );
$fee_recurring = round ( $total_recurring * $this -> cfg [ 'fee' ], 2 );
printf ( '<script type="text/javascript">alert("%s")</script>' ,
sprintf ( _ ( 'Please note, a payment processing fee of %3.2f%% will automatically be added to this payment schedule.' ), $this -> cfg [ 'fee' ] * 100 ));
break ;
}
$amount += $fee ;
$total_recurring += $fee_recurring ;
# Set the vars
$vals = array (
array ( 'cmd' , '_xclick-subscriptions' ),
array ( 'txn_type' , 'subscr_signup' ),
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' ]),
array ( 'a1' , $amount ),
array ( 'a3' , $total_recurring ),
array ( 'p3' , $p3 ),
array ( 't3' , $t3 ),
array ( 'sra' , 1 ),
array ( 'src' , 1 ),
array ( 'item_name' , 'Automatic Payment' ),
array ( 'usr_manage' , 0 )
);
2008-11-26 22:50:40 +00:00
# Get the next bill date for this subscription:
2009-08-03 04:10:16 +00:00
# @todo Dont we already know this next date?
if ( $recurr_bill_arr [ 0 ][ 'recurr_type' ] == '1' ) {
2008-11-26 22:50:40 +00:00
# Pro-rate billing:
2009-08-03 04:10:16 +00:00
include_once ( PATH_MODULES . 'product/product.inc.php' );
2009-10-01 23:35:52 +00:00
$product = new product ;
2008-11-26 22:50:40 +00:00
2009-08-03 04:10:16 +00:00
$arr = $product -> recurrDates ( $recurr_bill_arr [ 0 ][ 'recurr_schedule' ], $recurr_bill_arr [ 0 ][ 'recurr_weekday' ], $recurr_bill_arr [ 0 ][ 'recurr_week' ]);
$remain_time = $arr [ 'end' ] - $arr [ 'date' ];
$period1 = round ( $remain_time / 86400 );
switch ( $recurr_bill_arr [ 0 ][ 'recurr_schedule' ]) {
case 0 :
array_push ( $vals , array ( 'p1' , round ( $period1 / 7 )));
array_push ( $vals , array ( 't1' , 'W' ));
break ;
case 1 :
case 2 :
case 3 :
array_push ( $vals , array ( 'p1' , round ( $period1 / 365 * 12 )));
array_push ( $vals , array ( 't1' , 'M' ));
break ;
case 4 :
case 5 :
array_push ( $vals , array ( 'p1' , round ( $period1 / 365 )));
array_push ( $vals , array ( 't1' , 'Y' ));
break ;
default :
$C_debug -> error ( __FILE__ , __METHOD__ , sprintf ( 'Unknown recurr_schedule %s' , $recurr_bill_arr [ 0 ][ 'recurr_schedule' ]));
return false ;
}
2008-11-26 22:50:40 +00:00
2009-08-03 04:10:16 +00:00
# Bill on anniversary:
} else {
array_push ( $vals , array ( 'p1' , $p3 ));
array_push ( $vals , array ( 't1' , $t3 ));
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
$this -> post_vars ( sprintf ( '%s/cgi-bin/webscr' , $this -> getLocation ()), $vals );
2008-11-26 22:50:40 +00:00
return true ;
}
# Postback Validation
2009-08-03 04:10:16 +00:00
public function postback () {
# Read the post from PayPal system and add 'cmd'
global $_POST , $C_debug ;
2008-11-26 22:50:40 +00:00
$req = 'cmd=_notify-validate' ;
2009-08-03 04:10:16 +00:00
2008-11-26 22:50:40 +00:00
foreach ( $_POST as $key => $value ) {
$value = urlencode ( stripslashes ( $value ));
2009-08-03 04:10:16 +00:00
$req .= sprintf ( '&%s=%s' , $key , $value );
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
$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
2008-11-26 22:50:40 +00:00
$header = " POST /cgi-bin/webscr HTTP/1.0 \r \n " ;
$header .= " Content-Type: application/x-www-form-urlencoded \r \n " ;
2009-08-03 04:10:16 +00:00
$header .= sprintf ( " Content-Length: %s \r \n \r \n " , strlen ( $req ));
2008-11-26 22:50:40 +00:00
2009-08-03 04:10:16 +00:00
$fp = fsockopen ( $this -> getLocation ( false , true ), 80 , $errno , $errstr , 30 );
2008-11-26 22:50:40 +00:00
2009-08-03 04:10:16 +00:00
# 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' ];
2008-11-26 22:50:40 +00:00
else
2009-08-03 04:10:16 +00:00
$ret [ 'amount' ] = $_POST [ 'payment_gross' ];
$ret [ 'subscription_id' ] = $_POST [ 'subscr_id' ];
# 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 'subscr_cancel' : $ret [ 'status' ] = false ; break ;
case 'subscr_failed' : $ret [ 'status' ] = false ; break ;
case 'subscr_eot' : $ret [ 'status' ] = false ; break ;
2008-11-26 22:50:40 +00:00
}
2009-08-03 04:10:16 +00:00
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' ]) {
2008-11-26 22:50:40 +00:00
include_once ( PATH_MODULES . 'checkout/checkout.inc.php' );
$checkout = new checkout ;
$checkout -> postback ( $ret );
2009-08-03 04:10:16 +00:00
}
2008-11-26 22:50:40 +00:00
2009-08-03 04:10:16 +00:00
fclose ( $fp );
2008-11-26 22:50:40 +00:00
2009-08-03 04:10:16 +00:00
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, PayPal subscription id %s' , $ret [ 'invoice_id' ], $res , $ret [ 'subscription_id' ]));
fclose ( $fp );
header ( 'HTTP/1.0 404 Not Found' );
return false ;
2008-11-26 22:50:40 +00:00
}
}
}
2009-08-03 04:10:16 +00:00
header ( 'HTTP/1.0 500 Temporary Failure' );
2008-11-26 22:50:40 +00:00
}
}
# Postback Function
2009-08-03 04:10:16 +00:00
if ( empty ( $VAR ) && empty ( $VAR [ 'do' ])) {
2008-11-26 22:50:40 +00:00
include_once ( '../../config.inc.php' );
2009-08-03 04:10:16 +00:00
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 ;
2008-11-26 22:50:40 +00:00
$plg = new plg_chout_PAYPAL_RECURRING ;
$plg -> postback ();
}
2009-08-03 04:10:16 +00:00
?>