2013-04-06 44 views
0

我使用CodeIgniter創建一個頁面,用戶可以註冊一個慈善循環,我的俱樂部正在組織。PayPal IPN:(PHP)發送自定義字段沒有<form>

註冊頁面接受名稱/ dob /電話號碼等信息,並詢問用戶是否想在線付款或當天付款。點擊提交按鈕將信息發送到同一頁面,運行表單驗證,將信息插入數據庫(包括時間戳),並檢查用戶是否選擇在線支付。如果是這樣,用戶被重定向到PayPal捐贈按鈕URL完成付款。

我的問題是,如何通過URL發送PayPal自定義字段?我嘗試追加& custom =無論按鈕的URL,(其中'無論'是新的數據庫行ID和時間戳),但這完成後用沙箱帳戶捐贈無效。

IPN:註冊頁面提交時發送

public function ipn() 
{ 
    // STEP 1: Read POST data 

    // reading posted data from directly from $_POST causes serialization 
    // issues with array data in POST 
    // reading raw POST data from input stream instead. 
    $raw_post_data = file_get_contents('php://input'); 
    $raw_post_array = explode('&', $raw_post_data); 
    $myPost = 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'; 
    if(function_exists('get_magic_quotes_gpc')) 
    { 
     $get_magic_quotes_exists = true; 
    } 
    foreach($myPost as $key => $value) 
    {   
     if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) 
     { 
      $value = urlencode(stripslashes($value)); 
     } 
     else 
     { 
      $value = urlencode($value); 
     } 
     $req .= "&$key=$value"; 
    } 


    // STEP 2: Post IPN data back to paypal to validate 

    $ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr'); 
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $req); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
    curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); 

    // In wamp like environments that do not come bundled with root authority certificates, 
    // please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path 
    // of the certificate as shown below. 
    // curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); 
    if(!($res = curl_exec($ch))) 
    { 
     // error_log("Got " . curl_error($ch) . " when processing IPN data"); 
     curl_close($ch); 
     exit; 
    } 
    curl_close($ch); 


    // STEP 3: Inspect IPN validation result and act accordingly  

    if(strcmp($res, "VERIFIED") == 0) 
    { 
     // PAYMENT VALIDATED & VERIFIED! 
     $custom = explode('_', $_POST['custom']); 
     $reg_id = $custom[0]; 
     $date_registered = $custom[1]; 

     $query = $this->db->query('SELECT date_registered FROM registrations WHERE id=' . $reg_id); 
     $array = $query->result_array(); 
     if($array['date_registered'] == $date_registered) 
     { 
      $data = array(
       'has_payed' => 1 
      ); 
      $this->db->where('id', $reg_id); 
      $this->db->update('registrations', $data);  
     }   
    } 
    elseif(strcmp($res, "INVALID") == 0) 
    { 
     // do whatever 
    }   
} 

請注意,我需要這個工作,更新數據庫,這需要行ID的「has_payed」字段。

註冊控制器:

// check payment online 
if($this->input->post('pay_online') == 1) 
{ 
    // redirect to paypal depending on route 
    switch($route) 
    { 
     case '80': 
     case '40': 
      // €20 for over 16s 
      if($age >= 16) 
      { 
       redirect('https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=H3PFP5GGN2X5J&custom=' . urlencode($reg_id . '_' . $sql['date_registered'])); 
      } 
      // €10 for anyone under 16 
      else 
      { 
       redirect('a different button URL'); 
      } 
      break; 
     case '15': 
      // €15 for family 
      redirect('a different button URL'); 
      break; 
    } 
} 

上面的代碼是否正常工作,如在,我被重定向到URL按鈕時我提交表單用適當的值(即,執行80公里或40公里路線,並超過16yo)。當我在PayPal頁面完成付款時,數據庫中的'has_payed'字段不會按原樣更新(請參閱IPN頁面)。

另外,請注意,我確實在我的沙盒賣家帳戶中啓用了IPN。

我已經搜索瞭解決這個問題的小時,但找不到任何東西。也許我忽略了一些簡單的東西!我會很感激任何幫助。

謝謝!


UPDATE

而是將用戶重定向到PayPal按鈕URL的,我現在將其重定向到一個HTML頁面就可以了<form>代碼和JavaScript代碼在自動提交當他們加載頁面時形成。這工作正常,但數據庫字段仍然沒有更新時,用戶已捐贈。

<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" id="paypal_form" method="post" target="_top"> 
    <input type="hidden" name="cmd" value="_s-xclick"> 
    <input type="hidden" name="hosted_button_id" value="H3PFP5GGN2X5J"> 
    <input type="hidden" name="notify_url" value="#IPN URL#" /> 
    <input type="hidden" name="custom" value="<?php echo urlencode($reg_id . '_' . $sql['date_registered']); ?>"> 
    <input type="image" src="https://www.sandbox.paypal.com/en_US/GB/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal – The safer, easier way to pay online."> 
    <img alt="" border="0" src="https://www.sandbox.paypal.com/en_GB/i/scr/pixel.gif" width="1" height="1"> 
</form> 

回答

0

這個問題當然很簡單。

CSRF保護是啓用在config.php,導致IPN不起作用。禁用它可以解決問題。

0

您可以將您發送到PayPal的按鈕代碼中的變量「custom」傳遞給您。這將通過IPN POST發送回您的系統。然後,您應該能夠從那裏抓取它並執行您需要的操作。

+0

你是如何在按鈕代碼中傳遞變量的? – Kieran 2013-04-09 13:32:08

+0

如果您使用的是基本的PayPal網站付款標準按鈕,它只是添加到您的代碼中的另一行。 2013-04-09 16:05:26

+0

很抱歉,您顯然沒有完全閱讀我原來的帖子。我沒有使用表單,我使用PHP重定向到按鈕URL,因此我無法POST表單數據。 – Kieran 2013-04-09 17:22:30