返回商家后,Paypal ipn的定期付款没有响应

时间:2019-11-30 06:32:59

标签: php paypal paypal-ipn

===== 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&amp;product_key={$order_val['product_key']}&amp;member_key={$order_val['member_key']}&amp;uid={$order_val['user_id']}";
        $cancel_url = site_url('/') . "?notify=paypalnotify&amp;product_key={$order_val['product_key']}&amp;member_key={$order_val['member_key']}&amp;uid={$order_val['user_id']}"; 
         $return_url = "{$return_url}notify=return&amp;product_key={$order_val['product_key']}&amp;member_key={$order_val['member_key']}&amp;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'] . ")");
        }
    }

}

我试图找出什么问题,但找不到它,请帮助

0 个答案:

没有答案