PayPal IPN with CodeIgniter

2020-05-28 00:37发布

问题:

I am trying to implement a membership subscription service on a website built in CodeIgniter. I wish to use PayPal to manage payments, and am having a very hard time implementing this.

What I am trying to achieve is:

  1. User fills in a membership form with personal details
  2. User selects a subscription option (1 of 8 choices - each different price) and submits form
  3. User is sent to PayPal to pay
  4. User is returned to site upon successful payment and personal details are stored in database which creates user account (membership).

There is also the addition of form validation, I use the form_validation helper in CodeIgniter, but this needs to be done before PayPal payment can commence.

I have attempted to implement the PayPal_Lib from Ran Aroussi, but I feel it has not enough clear documentation or guidance on it. Any implemented examples or advice would be much appreciated.

Lucas

回答1:

I found Ran's library a little hard to use too so I've written a replacement - which also has the benefit of performing more checks on the transaction, and logging the IPN call and the order details in your database. Here's the library on GitHub, I hope you find it useful:

https://github.com/orderly/codeigniter-paypal-ipn



回答2:

Here's a paypal library from Jamie Rumbelow that I've been using with minor tweaks:

http://bitbucket.org/jamierumbelow/codeigniter-paypal/src



回答3:

Below is the unmodified code that i used with Ran's library. Hope it helps.

<?php
/**
 * PayPal_Lib Controller Class (Paypal IPN Class)
 *
 * Paypal controller that provides functionality to the creation for PayPal forms, 
 * submissions, success and cancel requests, as well as IPN responses.
 *
 * The class requires the use of the PayPal_Lib library and config files.
 *
 * @package     CodeIgniter
 * @subpackage  Libraries
 * @category    Commerce
 * @author      Ran Aroussi <ran@aroussi.com>
 * @copyright   Copyright (c) 2006, http://aroussi.com/ci/
 *
 */

class Paypal extends Controller 
{

    function Paypal()
    {
        parent::Controller();
        $this->load->library('Paypal_Lib');
    }

    function index()
    {
        $this->form();
    }

    function form()
    {

        $this->paypal_lib->add_field('business', 'herrka_1245670546_biz@pandorascode.com');
        $this->paypal_lib->add_field('return',          site_url('paypal/success') );
        $this->paypal_lib->add_field('cancel_return',   site_url('paypal/cancel') );
        $this->paypal_lib->add_field('notify_url',      site_url('paypal/ipn') ); // <-- IPN url
        $this->paypal_lib->add_field('custom', '470874552'); // <-- Verify return

        $this->paypal_lib->add_field('item_name', 'Paypal Test Transaction');
        $this->paypal_lib->add_field('item_number', '5');
        $this->paypal_lib->add_field('amount', '9.95');

        // if you want an image button use this:
        $this->paypal_lib->image('button_03.gif');

        // otherwise, don't write anything or (if you want to 
        // change the default button text), write this:
        // $this->paypal_lib->button('Click to Pay!');

        $data['paypal_form'] = $this->paypal_lib->paypal_form();

        $this->load->view('paypal/form', $data);

    }

    function cancel()
    {
        $this->load->view('paypal/cancel');
    }

    function success()
    {
        //$data['pp_info'] = $this->input->post();
        $data['pp_info'] = $_POST; //FIX?
        $this->load->view('paypal/success', $data);
    }

    function ipn()
    {

        $ipn_valid = $this->paypal_lib->validate_ipn();
        if ( $ipn_valid == TRUE )
        {


            /**
                Log IPN
                TODO: bunu daha guzel gozukecek sekilde yapayim ilerde.
            **/
            date_default_timezone_set('Europe/Istanbul');
            $this->load->helper('date');

            $raw = '';
            foreach ($this->paypal_lib->ipn_data as $key=>$value)
            {
                $raw .= "\n$key: $value";
            }

            $this->load->model('model_paypal');

            $data_ipn['user_id']            = $this->paypal_lib->ipn_data['custom']; /* get USER_ID from custom field. */
            $data_ipn['txn_id']             = $this->paypal_lib->ipn_data['txn_id'];
            $data_ipn['payment_status']     = $this->paypal_lib->ipn_data['payment_status'];
            $data_ipn['mc_gross']           = $this->paypal_lib->ipn_data['mc_gross'];
            $data_ipn['mc_fee']             = $this->paypal_lib->ipn_data['mc_fee'];
            $data_ipn['mc_currency']        = $this->paypal_lib->ipn_data['mc_currency'];
            $data_ipn['item_number']        = $this->paypal_lib->ipn_data['item_number'];
            $data_ipn['datetime']           = mdate( "%Y-%m-%d %H:%i:%s" );
            $data_ipn['status']             = IPN_ENTRY_AWAITING;
            $data_ipn['raw']                = $raw;

            $this->model_paypal->ipn_entry_add ( $data_ipn );



            $ipn_payment_status = $this->paypal_lib->ipn_data['payment_status'];
            if ( strtolower($ipn_payment_status) == 'pending' )
            {


                log_message('debug', 'payment status TAMAM');
                $this->load->model('model_user_premium');


                $ipn_item_number    = $this->paypal_lib->ipn_data['item_number'];
                $item_info          = $this->model_user_premium->Premium_item_info ( $ipn_item_number );

                $ipn_mc_gross       = $this->paypal_lib->ipn_data['mc_gross'];

                log_message('debug', 'Item fee: '. $item_info['item_fee'] );                

                if ( $item_info['item_fee'] == $ipn_mc_gross ) 
                {

                    log_message('debug', 'fee ile gross TAMAM');



                    $data_account['user_id']        = $data_ipn['user_id'];
                    $data_account['type']           = $item_info['item_type'];
                    $data_account['date_expire']    = date("Y-m-d", mktime(0, 0, 0, date("m") + $item_info['date_extender'], date("d"), date("y") ) ); 


                    log_message('debug', 'UserID: '.    $data_account['user_id']        );
                    log_message('debug', 'Type:'.       $data_account['type']           );
                    log_message('debug', 'Expire:'.     $data_account['date_expire']    );


                    $this->model_user_premium->Premium_membership_change( $data_ipn['user_id'], $data_account );

                }
                else
                {

                    //TODO: report eksik transaction.

                }

            }



        }
        elseif ( $ipn_valid == FALSE )
        {

            $this->load->library('email');
            $this->email->to( 'demo@demo.com' );
            $this->email->subject('IPN - FAILED');
            $this->email->from( 'notify@bulusturx.com', 'PAYPAL' );
            $this->email->message('or 4 life'); 

            $this->email->send();

        }


    }

    function ipn_list()
    {
        //TODO: admin check
        $this->load->helper('form');
        $this->load->model('model_theme');

        switch ( $_SERVER['REQUEST_METHOD'] ) 
        {

            case 'GET':

                /* Theme System with Reference Variable ( first param ) */
                $this->model_theme->Theme_returnThemeInfo( $data, 'paypal' );
                $this->load->view( $data['theme_folder_vault'] . 'master-ipn_list', $data );


            break;

            case 'POST':

                $this->load->model('model_paypal');
                $user_id    = $this->input->post('user_id');
                $txn_id     = $this->input->post('txn_id');

                $list_ipn = $this->model_paypal->ipn_entry_list ( $user_id, $txn_id );

                echo '<pre>';
                print_r( $list_ipn );
                echo '</pre>';


            break;


            default:
            break;
        }


    }


    function ipn_test()
    {

        $this->load->model('model_user_premium');

        $data_account['user_id']        = 123;
        $data_account['type']           = 4;
        $data_account['date_expire']    = date("Y-m-d", mktime(0, 0, 0, date("m") + 12, date("d"), date("y") ) );

        echo '<pre>';
        print_r( $data_account );
        echo '</pre>';


        $this->model_user_premium->Premium_membership_change( 123, $data_account );

    }

}

?>