===== paypal.php ======= 以下paypal.php不适用于一次性付款,也不能用于定期付款 但是,当我在下面的$ return网址中将 notify = return更改为notify = paypalnotify 时,仅当我单击(返回商户)时,如果我没有单击(返回至商户),则不会发生任何事情,付款条目将不会保存在数据库中,这些更改 notify = return to notify = paypalnotify 在点击返回商户后不适用于重复付款,它显示无效的HTTP请求方法405 < / p>
<?php
function im_paypal_getway_process($order_val) {
//Is this a test transaction?
if ($order_val['billing_type'] !== 'free_mem') {
if (get_option('im_sabdbox_mode') == true)
$paypalurl = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
else
$paypalurl = 'https://www.paypal.com/cgi-bin/webscr';
$return_url = '';
$merchant_id = get_option('im_paypal_email');
if (get_option('im_return_page') == '') {
$return_url = site_url('?page_id=' . get_option('payment_status')) . '&';
} else {
$return_url = get_option('im_return_page') . '&';
}
if (get_option('im_paypal_locale') != '') {
$im_paypal_locale = get_option('im_paypal_locale');
} else {
$im_paypal_locale = 'us';
}
$notify_url = site_url('/') . "?notify=paypalnotify&product_key={$order_val['product_key']}&member_key={$order_val['member_key']}&uid={$order_val['user_id']}";
$cancel_url = site_url('/') . "?notify=paypalnotify&product_key={$order_val['product_key']}&member_key={$order_val['member_key']}&uid={$order_val['user_id']}";
$return_url = "{$return_url}notify=return&product_key={$order_val['product_key']}&member_key={$order_val['member_key']}&uid={$order_val['user_id']}";
$form = '';
$form .= '<form id="frm_payment_' . $order_val['form_id'] . '" name="frm_payment_method" action="' . $paypalurl . '" method="post">';
$form .= '<input type="hidden" name="business" value="' . $merchant_id . '" />';
$form .= '<input type="hidden" name="notify_url" value="' . $notify_url . '" />';
$form .= '<input type="hidden" name="cancel_return" value="' . $cancel_url . '" />';
$form .= '<input type="hidden" name="return" value="' . $return_url . '" />';
$form .= '<input type="hidden" name="rm" value="2" />';
$form .= '<input type="hidden" name="lc" value="' . $im_paypal_locale . '" />';
$form .= '<input type="hidden" name="no_shipping" value="1" />';
$form .= '<input type="hidden" name="no_note" value="1" />';
$form .= '<input type="hidden" name="currency_code" value="' . $order_val['currency_code'] . '" />';
$form .= '<input type="hidden" name="page_style" value="paypal" />';
$form .= '<input type="hidden" name="charset" value="utf-8" />';
$form .= '<input type="hidden" name="item_name" value="' . $order_val['item_name'] . '" />';
if ($order_val['billing_type'] == 'recurring') {
$form .= '<input type="hidden" name="cmd" value="_xclick-subscriptions" />';
$form .= '<input type="hidden" name="src" value="1" />';
if ($order_val['installment'] > 1) {
$form .= '<input type="hidden" name="srt" value="' . $order_val['installment'] . '" />';
}
$form .= '<input type="hidden" name="a1" value="' . $order_val['amount'] . '" />';
$form .= '<input type="hidden" name="p1" value="' . $order_val['f_period'] . '" />';
$form .= '<input type="hidden" name="t1" value="' . $order_val['f_cycle'] . '" />';
$form .= '<input type="hidden" name="a3" value="' . $order_val['s_price'] . '" />';
//<!-- Second Period -->
$form .= '<input type="hidden" name="p3" value="' . $order_val['s_period'] . '" />';
$form .= '<input type="hidden" name="t3" value="' . $order_val['s_cycle'] . '" />';
} else {
$form .= '<input type="hidden" value="_xclick" name="cmd"/>';
$form .= '<input type="hidden" name="amount" value="' . $order_val['amount'] . '" />';
}
if ($order_val['submit_btn'] != false) {
//$form .= '<input class="buy_btn" type="submit" value="Buy Now"/>';
}
$form .= '</form>';
}
return $form;
}
======= ipn.php ========
<?php
/**
* PHP-PayPal-IPN Example
*
*/
class InkMember_IPN {
/**
* Plugin directory path
* @var type string
*/
var $dir_path = '';
/**
* Stores site admin email
* @var type string
*/
var $admin_email = '';
var $varified = false;
var $listener = '';
/**
* Stores errors from fraud checks
* @var type string
*/
var $errormsg = '';
/**
* Stores post back data
* @var type array
*/
var $post_data = array();
/**
* Stores request back data
* @var type
*/
var $request = array();
/**
* Stores payment status
* @var type string
*/
var $payment_status = '';
/**
* Merchant email
*/
var $merchant_email = '';
/**
* Host Name
*/
var $host_name = '';
/**
* Ipn debug
*/
var $ipn_debug = true;
var $content = '';
function __construct() {
}
static function Instance() {
$obj = new InkMember_IPN();
$obj->dir_path = plugin_dir_path( __FILE__ );
/**
* Include Ipnlistener
*/
//include('ipnlistener.php');
require_once(plugin_dir_path( __FILE__ ).'/ipnlistener.php');
/**
* Assign merchant id
*/
$obj->merchant_email = get_option( 'im_paypal_email' );
/**
* Set variables
*/
$obj->admin_email = get_option( 'admin_email' );
$obj->host_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
/**
* Instantiate the IpnListener class
*/
$obj->listener = new IpnListener();
/**
* When you are testing your IPN script you should be using a PayPal "Sandbox"
* account: https://developer.paypal.com
* When you are ready to go live change use_sandbox to false.
*/
if ( get_option( 'im_sabdbox_mode' ) ) {
$obj->listener->use_sandbox = true;
}
if ( !empty( $_REQUEST ) ) {
$obj->request = $_REQUEST;
}
if ( !empty( $_POST ) ) {
$obj->post_data = $_POST;
}
if ( isset( $obj->request['notify'] ) && $obj->request['notify'] == 'paypalnotify' ) {
try {
$obj->listener->requirePostMethod();
$obj->varified = $obj->listener->processIpn();
} catch ( Exception $e ) {
error_log( $e->getMessage() );
exit( 0 );
}
$obj->payment_status = isset( $obj->post_data['payment_status'] ) ? $obj->post_data['payment_status'] : '';
add_filter( 'wp_mail_content_type', array( $obj, 'set_html_content_type' ) );
//$obj->debug_ipn();
/**
* Process the ipn
*/
$obj->process();
/**
* Reset content-type to avoid conflicts -- http://core.trac.wordpress.org/ticket/23578
*/
remove_filter( 'wp_mail_content_type', array( $obj, 'set_html_content_type' ) );
}
}
function debug_ipn() {
/**
* Debugging ipn
*/
if ( $this->ipn_debug && !empty( $this->post_data ) & !empty( $this->request ) ) {
$headers = 'From: ' . $this->host_name . ' <' . $this->admin_email . '>';
mail( $this->admin_email, __( 'Debug IPN', IM_SLUG ), $this->listener->getTextReport(), $headers );
}
}
function process() {
/*
The processIpn() method returned true if the IPN was "VERIFIED" and false if it
was "INVALID".
*/
if ( $this->varified ) {
switch ( strtolower( $this->payment_status ) ) :
case 'completed' :
$this->completed();
break;
case 'pending' :
$this->pending();
break;
case 'refunded' :
case 'reversed' :
case 'chargeback' :
$this->refunded();
break;
case 'denied' :
case 'expired' :
case 'failed' :
case 'voided' :
$this->failed();
break;
endswitch;
} else {
/**
* manually investigate the invalid IPN
*/
$headers = 'From: ' . $this->host_name . ' <' . $this->admin_email . '>';
mail( $this->admin_email, __( 'Invalid IPN', IM_SLUG ), $this->listener->getTextReport(), $headers );
}
}
function completed() {
/**
* Checking if receiver email and merchant email are similar
*/
// if ( $this->post_data['receiver_email'] != $this->merchant_email ) {
// //$this->errormsg .= "'receiver_email' does not match: ";
// //$this->errormsg .= $this->post_data['receiver_email'] . "\n";
// }
if ( !empty( $this->errormsg ) ) {
/**
* manually investigate errors from the fraud checking
*/
$body = "IPN failed fraud checks: " . $this->errormsg . "\n\n";
$body .= $this->listener->getTextReport();
$headers = 'From: ' . $this->host_name . ' <' . $this->admin_email . '>';
$subject = __( 'IPN Fraud Warning', IM_SLUG );
mail( $this->admin_email, $subject, $body, $headers );
} else {
/**
* Entries the transactions on transaction table
*/
$data = array(
'post_data' => $this->post_data,
'req_data' => $this->request
);
do_action( 'im_process_transaction_entry', $data );
/**
* Update membership entry
*/
im_update_transaction_status( $data );
/**
* Mail to admin for notify his sales
*/
$this->mail_to_admin();
/**
* Mail to user for notify his purchase
*/
$this->mail_to_user();
}
}
function mail_to_admin() {
$subject = __( $this->host_name . " Payment Received.", IM_SLUG );
$headers = 'From: ' . $this->host_name . ' <' . $this->admin_email . '>' . "\r\n";
$message = __( 'Dear Admin,', IM_SLUG ) . "<br/><br/>";
$message .= sprintf( __( 'Payment received successfully from %s %s.', IM_SLUG ), $this->post_data['first_name'], $this->post_data['last_name'] ) . "<br/><br/>";
$message .= __( 'Transaction Details', IM_SLUG ) . "<br/>";
$message .= "-------------------------------- <br/>";
$message .= __( 'Product Name: ', IM_SLUG ) . $this->post_data['item_name'] . "<br/>";
$message .= __( 'Amount Received: ', IM_SLUG ) . $this->post_data['mc_gross'] . "(" . $this->post_data['mc_currency'] . ")<br/>";
$message .= __( 'PayPal Email: ', IM_SLUG ) . $this->post_data['payer_email'] . "<br/>";
$message .= __( 'Transaction ID: ', IM_SLUG ) . $this->post_data['txn_id'] . "<br/>";
$message .= __( 'Payment type: ', IM_SLUG ) . $this->post_data['payment_type'] . "<br/>";
/**
* Send email to admin
*/
wp_mail( $this->admin_email, $subject, $message, $headers );
}
function mail_to_user() {
$subject = __( $this->host_name . " Thanks for your purchase.", IM_SLUG );
$headers = 'From: ' . $this->host_name . ' <' . $this->admin_email . '>' . "\r\n" . 'Reply-To: ' . $this->admin_email;
$content = __( "Dear {$this->post_data['first_name']},", IM_SLUG ) . "<br/><br/>";
$content .= sprintf( __( 'Your purchase of %s is successful.', IM_SLUG ), $this->post_data['item_name'] ) . "<br/><br/>";
$content .= __( 'Transaction Details', IM_SLUG ) . "<br/>";
$content .= "-------------------------------- <br/>";
$content .= __( 'Product Name: ', IM_SLUG ) . $this->post_data['item_name'] . "<br/>";
$content .= __( 'Amount Received: ', IM_SLUG ) . $this->post_data['mc_gross'] . "(" . $this->post_data['mc_currency'] . ")<br/>";
$content .= __( 'Transaction ID: ', IM_SLUG ) . $this->post_data['txn_id'] . "<br/><br/><br/>";
$content .= __( 'Warm Regards,', IM_SLUG ) . "<br/>";
$content .= '<a href="' . home_url() . '">' . $this->host_name . "</a><br/>";
$user_email = get_the_author_meta( 'user_email', $this->request['uid'] );
/**
* Send mail to user
*/
wp_mail( $user_email, $subject, $content, $headers ); //email to client
}
function pending() {
/**
* Checking if receiver email and merchant email are similar
*/
if ( $this->post_data['receiver_email'] != $this->merchant_email ) {
//$this->errormsg .= "'receiver_email' does not match: ";
//$this->errormsg .= $this->post_data['receiver_email'] . "\n";
}
if ( !empty( $this->errormsg ) ) {
/**
* manually investigate errors from the fraud checking
*/
$body = "IPN failed fraud checks: " . $this->errormsg . "\n\n";
$body .= $this->listener->getTextReport();
$headers = 'From: ' . $this->host_name . ' <' . $this->admin_email . '>';
$subject = __( 'IPN Fraud Warning', IM_SLUG );
mail( $this->admin_email, $subject, $body, $headers );
} else {
/**
* Entries the transactions on transaction table
*/
$data = array(
'post_data' => $this->post_data,
'req_data' => $this->request
);
do_action( 'im_process_transaction_entry', $data );
/**
* Update membership entry
*/
im_update_transaction_status( $data );
$subject = __( 'PayPal IPN - payment pending', IM_SLUG );
$headers = 'From: ' . __( 'Admin', IM_SLUG ) . ' <' . get_option( 'admin_email' ) . '>' . "\r\n";
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
$message = __( 'Dear ' . $this->host_name . ',', IM_SLUG ) . "<br/><br/>";
$message .= sprintf( __( 'The following payment is pending on your %s website.', IM_SLUG ), $this->host_name ) . "<br/>";
$message .= __( 'Payment Details', IM_SLUG ) . "<br/>";
$message .= '----------------- <br/>';
$message .= __( 'Payer PayPal address: ', IM_SLUG ) . $this->post_data['payer_email'] . "<br/>";
$message .= __( 'Transaction ID: ', IM_SLUG ) . $this->post_data['txn_id'] . "<br/>";
$message .= __( 'Payer first name: ', IM_SLUG ) . $this->post_data['first_name'] . "<br/>";
$message .= __( 'Payer last name: ', IM_SLUG ) . $this->post_data['last_name'] . "<br/>";
$message .= __( 'Payment type: ', IM_SLUG ) . $this->post_data['payment_type'] . "<br/>";
$message .= __( 'Amount: ', IM_SLUG ) . $this->post_data['mc_gross'] . " (" . $this->post_data['mc_currency'] . ")<br/>";
wp_mail( $this->admin_email, $subject, $message, $headers );
/**
* Mail to user for notify his purchase
*/
$this->mail_to_user();
}
}
function failed() {
/**
* Set expire for his membership
*/
im_member_expire( $this->request['uid'], $this->request['product_key'] );
$subject = __( 'PayPal IPN - payment failed', IM_SLUG );
$headers = 'From: ' . $this->host_name . ' <' . get_option( 'admin_email' ) . '>' . "<br/>";
$message = __( 'Dear ' . $this->host_name . ',', IM_SLUG ) . "<br/><br/>";
$message .= sprintf( __( 'The following payment has failed on your %s website.', IM_SLUG ), $this->host_name ) . "<br/><br/>";
$message .= __( 'Payment Details', IM_SLUG ) . "<br/>";
$message .= "----------------- <br/>";
$message .= __( 'Payer PayPal address: ', IM_SLUG ) . $this->post_data['payer_email'] . "<br/>";
$message .= __( 'Transaction ID: ', IM_SLUG ) . $this->post_data['txn_id'] . "<br/>";
$message .= __( 'Payer first name: ', IM_SLUG ) . $this->post_data['first_name'] . "<br/>";
$message .= __( 'Payer last name: ', IM_SLUG ) . $this->post_data['last_name'] . "<br/>";
$message .= __( 'Payment type: ', IM_SLUG ) . $this->post_data['payment_type'] . "<br/>";
$message .= __( 'Amount: ', IM_SLUG ) . $this->post_data['mc_gross'] . " (" . $this->post_data['mc_currency'] . ")<br/>";
wp_mail( $this->admin_email, $subject, $message, $headers );
}
function refunded() {
//Set expire membership
im_member_expire( $this->request['uid'], $this->request['product_key'] );
// send an email if payment was refunded
$subject = __( 'PayPal IPN - payment refunded/reversed', IM_SLUG );
$headers = 'From: ' . __( $this->host_name, IM_SLUG ) . ' <' . $this->admin_email . '>' . "\r\n";
$message = __( 'Dear Admin,', IM_SLUG ) . "<br/>";
$message .= sprintf( __( 'The following payment has been marked as refunded on your %s website.', IM_SLUG ), $this->host_name ) . "<br/><br/>";
$message .= __( 'Payment Details', IM_SLUG ) . "<br/>";
$message .= "----------------- <br/>";
$message .= __( 'Payer PayPal address: ', IM_SLUG ) . $this->post_data['payer_email'] . "<br/>";
$message .= __( 'Transaction ID: ', IM_SLUG ) . $this->post_data['txn_id'] . "<br/>";
$message .= __( 'Payer first name: ', IM_SLUG ) . $this->post_data['first_name'] . "<br/>";
$message .= __( 'Payer last name: ', IM_SLUG ) . $this->post_data['last_name'] . "<br/>";
$message .= __( 'Payment type: ', IM_SLUG ) . $this->post_data['payment_type'] . "<br/>";
$message .= __( 'Reason code: ', IM_SLUG ) . $this->post_data['reason_code'] . "<br/>";
$message .= __( 'Amount: ', IM_SLUG ) . $this->post_data['mc_gross'] . " (" . $this->post_data['mc_currency'] . ")<br/>";
wp_mail( $this->admin_email, $subject, $message, $headers );
}
function set_html_content_type() {
return 'text/html';
}
}
add_action( 'plugins_loaded', array( 'InkMember_IPN', 'Instance' ) );
function debug() {
$file = 'jsutcheck.php';
// Open the file to get existing content
// Append a new person to the file
$post = '<?php echo "Post Values";' . print_r( $_REQUEST, true ) . ' ?>';
// Write the contents back to the file
file_put_contents( $file, $post );
ini_set( 'log_errors', true );
ini_set( 'error_log', dirname( __FILE__ ) . '/ipn_errors.log' );
}
debug();
==== ipnlistener.php =====
<?php
/**
* PayPal IPN Listener
*
* A class to listen for and handle Instant Payment Notifications (IPN) from
* the PayPal server.
*
* Forked from the great Quixotix PayPal IPN script. This fork plans to
* fix the current issues with the original repo, as well as update the code
* for use according to PayPal's documentation, and today's standards.
*
* @package PHP-PayPal-IPN
* @link https://github.com/WadeShuler/PHP-PayPal-IPN
* @forked https://github.com/Quixotix/PHP-PayPal-IPN
* @author Wade Shuler
* @copyright Copyright (c) 2015, Wade Shuler
* @license http://choosealicense.com/licenses/gpl-2.0/
* @version 2.5.2
*/
class IpnListener
{
/**
* If true, the recommended cURL PHP library is used to send the post back
* to PayPal. If flase then fsockopen() is used. Default true.
*
* @var boolean
*/
public $use_curl = true;
/**
* If true, cURL will use the CURLOPT_FOLLOWLOCATION to follow any
* "Location: ..." headers in the response.
*
* @var boolean
*/
public $follow_location = false;
/**
* If true, the paypal sandbox URI www.sandbox.paypal.com is used for the
* post back. If false, the live URI www.paypal.com is used. Default false.
*
* @var boolean
*/
public $use_sandbox = false;
/**
* The amount of time, in seconds, to wait for the PayPal server to respond
* before timing out. Default 30 seconds.
*
* @var int
*/
public $timeout = 30;
/**
* If true, enable SSL certification validation when using cURL
*
* @var boolean
*/
public $verify_ssl = true;
private $_errors = array();
private $post_data;
private $rawPostData; // raw data from php://input
private $post_uri = '';
private $response_status = '';
private $response = '';
const PAYPAL_HOST = 'www.paypal.com';
const SANDBOX_HOST = 'www.sandbox.paypal.com';
/**
* Post Back Using cURL
*
* Sends the post back to PayPal using the cURL library. Called by
* the processIpn() method if the use_curl property is true. Throws an
* exception if the post fails. Populates the response, response_status,
* and post_uri properties on success.
*
* @todo add URL param so function is more dynamic
*
* @param string The post data as a URL encoded string
*/
protected function curlPost($encoded_data)
{
$uri = 'https://'.$this->getPaypalHost().'/cgi-bin/webscr';
$this->post_uri = $uri;
$ch = curl_init();
if ($this->verify_ssl) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_CAINFO, dirname(dirname(__FILE__)) . '/cert/api_cert_chain.crt');
}
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location);
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$this->response = curl_exec($ch);
$this->response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
if ($this->response === false || $this->response_status == '0') {
$errno = curl_errno($ch);
$errstr = curl_error($ch);
throw new Exception("cURL error: [$errno] $errstr");
}
return $this->response;
}
/**
* Post Back Using fsockopen()
*
* Sends the post back to PayPal using the fsockopen() function. Called by
* the processIpn() method if the use_curl property is false. Throws an
* exception if the post fails. Populates the response, response_status,
* and post_uri properties on success.
*
* @todo add URL param so function is more dynamic
*
* @param string The post data as a URL encoded string
*/
protected function fsockPost($encoded_data)
{
$uri = 'ssl://'.$this->getPaypalHost();
$port = '443';
$this->post_uri = $uri.'/cgi-bin/webscr';
$fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout);
if (!$fp) {
// fsockopen error
throw new Exception("fsockopen error: [$errno] $errstr");
}
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: ".$this->getPaypalHost()."\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: ".strlen($encoded_data)."\r\n";
$header .= "Connection: Close\r\n\r\n";
fputs($fp, $header.$encoded_data."\r\n\r\n");
while(!feof($fp)) {
if (empty($this->response)) {
// extract HTTP status from first line
$this->response .= $status = fgets($fp, 1024);
$this->response_status = trim(substr($status, 9, 4));
} else {
$this->response .= fgets($fp, 1024);
}
}
fclose($fp);
return $this->response;
}
private function getPaypalHost()
{
return ($this->use_sandbox) ? self::SANDBOX_HOST : self::PAYPAL_HOST;
}
public function getErrors()
{
return $this->_errors;
}
private function addError($error)
{
$this->_errors[] .= $error;
}
public function getPostData()
{
return $this->post_data;
}
public function getRawPostData()
{
return $this->rawPostData;
}
/**
* Get POST URI
*
* Returns the URI that was used to send the post back to PayPal. This can
* be useful for troubleshooting connection problems. The default URI
* would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr"
*
* @return string
*/
public function getPostUri()
{
return $this->post_uri;
}
/**
* Get Response
*
* Returns the entire response from PayPal as a string including all the
* HTTP headers.
*
* @return string
*/
public function getResponse()
{
return $this->response;
}
/**
* Get Response Status
*
* Returns the HTTP response status code from PayPal. This should be "200"
* if the post back was successful.
*
* @return string
*/
public function getResponseStatus()
{
return $this->response_status;
}
/**
* Get Text Report
*
* Returns a report of the IPN transaction in plain text format. This is
* useful in emails to order processors and system administrators. Override
* this method in your own class to customize the report.
*
* @return string
*/
public function getTextReport()
{
$r = '';
// date and POST url
for ($i=0; $i<80; $i++) { $r .= '-'; }
$r .= "\n[".date('m/d/Y g:i A').'] - '.$this->getPostUri();
if ($this->use_curl) {
$r .= " (curl)\n";
} else {
$r .= " (fsockopen)\n";
}
// HTTP Response
for ($i=0; $i<80; $i++) { $r .= '-'; }
$r .= "\n{$this->getResponse()}\n";
// POST vars
for ($i=0; $i<80; $i++) { $r .= '-'; }
$r .= "\n";
if (!empty($this->post_data)) {
foreach ($this->post_data as $key => $value) {
$r .= str_pad($key, 25)."$value\n";
}
}
$r .= "\n\n";
return $r;
}
/**
* Process IPN
*
* Handles the IPN post back to PayPal and parsing the response. Call this
* method from your IPN listener script. Returns true if the response came
* back as "VERIFIED", false if the response came back "INVALID", and
* throws an exception if there is an error.
*
* @param array
*
* @return boolean
*/
public function processIpn($post_data=null)
{
try
{
$this->requirePostMethod(); // processIpn() should check itself if data is POST
// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
if ($post_data === null) {
$raw_post_data = file_get_contents('php://input');
} else {
$raw_post_data = $post_data;
}
$this->rawPostData = $raw_post_data; // set raw post data for Class use
// if post_data is php input stream, make it an array.
if ( ! is_array($raw_post_data) ) {
$raw_post_array = explode('&', $raw_post_data);
$this->post_data = $raw_post_array; // use post array because it's same as $_POST
} else {
$this->post_data = $raw_post_data; // use post array because it's same as $_POST
}
$myPost = array();
if (isset($raw_post_array)) {
foreach ($raw_post_array as $keyval) {
$keyval = explode('=', $keyval);
if (count($keyval) == 2) {
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
}
}
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($myPost as $key => $value) {
if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
} else {
$value = urlencode($value);
}
$req .= "&$key=$value";
}
if ($this->use_curl) {
$res = $this->curlPost($req);
} else {
$res = $this->fsockPost($req);
}
if (strpos($res, '200') === false) {
throw new Exception("Invalid response status: " . $res);
}
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {
return true;
} else if (strcmp ($res, "INVALID") == 0) {
return false;
} else {
throw new Exception("Unexpected response from PayPal.");
}
} catch (Exception $e) {
$this->addError($e->getMessage());
return false;
}
return false;
}
/**
* Require Post Method
*
* Throws an exception and sets a HTTP 405 response header if the request
* method was not POST.
*/
public function requirePostMethod()
{
// require POST requests
if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') {
header('Allow: POST', true, 405);
throw new Exception("Invalid HTTP request method (" . $_SERVER['REQUEST_METHOD'] . ") from " . $_SERVER['REMOTE_ADDR'] . " - " . $_SERVER['HTTP_USER_AGENT'] . ")");
}
}
}
我试图找出什么问题,但找不到它,请帮助