2010-10-20 217 views
6

我想在CodeIgniter中構建的網站上實現會員訂閱服務。我希望使用PayPal來管理付款,並且很難實現這一點。PayPal IPN與CodeIgniter

我想實現的是:在會員的形式

  1. 用戶填寫與 個人信息
  2. 用戶選擇 訂閱選項(共8個選擇1 - 每個不同的價格),並提交形式
  3. 用戶被髮送到貝寶支付
  4. 用戶成功付款後返回網站,個人詳細信息存儲在創建用戶帳戶(成員資格)的數據庫中。

此外還有表單驗證,我使用CodeIgniter中的form_validation助手,但這需要在PayPal付款開始前完成。

我試圖從Ran Aroussi實施PayPal_Lib,但我覺得它沒有足夠清晰的文檔或指導。任何實施的例子或建議將不勝感激。

盧卡斯

+0

貝寶是一個比較硬的API來使用。我會親自使用像DPS這樣的服務。 http://www.paymentexpress.com/ – Petah 2010-10-20 14:14:07

+0

如果你改變「if($ this-> CI-> input-> post())」爲「if(isset($ _ POST))」,那麼lib工作正常。你得到什麼錯誤? – stef 2010-10-21 08:50:32

回答

1

以下是我與阿蘭的庫中使用未經修改的代碼。 希望它有幫助。

<?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 <[email protected]> 
* @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', '[email protected]'); 
     $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('[email protected]'); 
      $this->email->subject('IPN - FAILED'); 
      $this->email->from('[email protected]', '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); 

    } 

} 

?> 
2

我發現阿蘭的圖書館有點難以用太多,所以我寫了一個替代 - 這也對交易進行更多的檢查,並記錄IPN電話和訂單詳細信息在你的數據庫的好處。下面是在GitHub上圖書館,我希望你覺得它有用:

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

+1

在這個亞歷克斯工作很好。但是,你有一個不需要教條的版本嗎? – BrynJ 2011-03-02 13:13:47

+0

嗨BrynJ,是的 - 現在有一個版本不需要Doctrine – 2011-07-08 11:35:38

+0

真棒。謝謝! – Jake 2012-08-06 03:22:22