2010-03-12 149 views
21

我想在我的網站上創建一個簡單的交易,在交易完成後,我希望貝寶將用戶重定向到我的網站上的某個地方,並且我希望貝寶爲我提供我與細節,所以我可以使用PHP來解析它,並通過電子郵件發送鏈接到他們的購買。我不確定notify_url的作用是什麼?謝謝交易後從貝寶獲取信息

回答

55

貝寶是這樣工作的:

你有一個「購買」按鈕的形式。點擊時,它會向貝寶發送信息(產品,價格,您的帳戶名稱等)。

然後買家同意支付給您,當交易完成後,PayPal向您的通知URL發送「IPN」(即時付款通知) - 它將POST數據發送到該URL以供您的服務器處理。您回覆PayPal詢問他們是否發送了POST數據(而不是冒名頂替者),如果他們回答說這是真實的交易,您可以將產品發佈給客戶。請注意,這一切都發生在後臺,而您的買家仍然在PayPal網站上。

有一個最後的可選階段,即PayPal將買方退還給您的網站。在這種情況下,他們會將買方發回您的「返回」網址,並且他們可以(可選地)再次傳回交易數據(他們稱之爲PDT)。如果這是一個有效的交易並且提供下載等,那麼您可以再次使用Paypal進行檢查。

沒有人解釋的最困難的一點是買方沒有被重定向到您的通知URL。即您的網站通知網址的「訪問者」是貝寶,而非買家,所以這不會作爲買方會話的一部分發生。如果您希望在此過程的三個部分中持續進行會話,則需要創建一種跟蹤表單中買方的方法,然後將其傳遞到PayPal中名爲「custom」的字段中。這些數據通過IPN和PDT數據傳回給您,您可以使用此數據與原始用戶會話重新建立連接。

您確實需要實施IPN和PDT - 如果IPN電子郵件失敗,那麼您將PDT作爲備份。如果用戶在重定向到您的PDT頁面之前關閉了瀏覽器,那麼您已經發送了一封IPN電子郵件作爲備份。

在IPN和PDT上搜索,你會發現很多信息。 PayPal也有完整的文檔和示例腳本。

+0

也許我是誤解,但我認爲它不是/或。我認爲你可以在商戶檔案或IPN上使用PDT,但不能同時使用兩者。你能告訴我如何同時設置PDT和IPN嗎? – Volomike 2011-10-03 19:30:57

+0

@Volomike:閱讀最後兩段[這裏(paypal)](https://cms.paypal.com/uk/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro)和其他SO答案,如[this一個](http://stackoverflow.com/questions/2836779/paypal-ipn-vs-pdt) – 2011-10-09 12:30:30

+0

@JasonWilliams鏈接似乎破了。 – 2015-02-08 06:51:19

6

通知URL應該導致對保存來自貝寶返回的數據,如腳本:

/** Fetch order from PayPal (IPN reply) 
    * @return int received ID of inserted row if received correctly, 0 otherwise 
    */ 
    function FetchOrder() 
    { 
    $transactionID=$_POST["txn_id"]; 
    $item=$_POST["item_name"]; 
    $amount=$_POST["mc_gross"]; 
    $currency=$_POST["mc_currency"]; 
    $datefields=explode(" ",$_POST["payment_date"]); 
    $time=$datefields[0]; 
    $date=str_replace(",","",$datefields[2])." ".$datefields[1]." ".$datefields[3]; 
    $timestamp=strtotime($date." ".$time); 
    $status=$_POST["payment_status"]; 
    $firstname=$_POST["first_name"]; 
    $lastname=$_POST["last_name"]; 
    $email=$_POST["payer_email"]; 
    $custom=$_POST["option_selection1"]; 
    if ($transactionID AND $amount) 
     { 
     // query to save data 
     return $this->insertID; 
     } 
    else 
     { 
     return 0; 
     } 
    } 

您也可以選擇稍後驗證順序:

/** Verify PayPal order (IPN) 
    * PayPal returns VERIFIED or INVALID on request 
    * @return bool verified 1 if verified, 0 if invalid 
    */ 
    function VerifyOrder() 
    { 
    $_POST["cmd"]="_notify-validate"; 
    $ch=curl_init(); 
    curl_setopt($ch,CURLOPT_HEADER,0); 
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
    curl_setopt($ch,CURLOPT_USERAGENT,"your agent - replace"); 
    curl_setopt($ch,CURLOPT_URL,"https://www.paypal.com/cgi-bin/webscr"); 
    curl_setopt($ch,CURLOPT_POST, 1); 
    foreach ($_POST as $key=>$value) 
     { 
     $string.="&".$key."=".urlencode(stripslashes($value)); 
     } 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $string); 
    $result=curl_exec($ch); 
    if ($result=="VERIFIED") return 1; 
    else return 0; 
    } 
2
$tx=$_REQUEST['tx']; 

$paypal_url='https://www.paypal.com/cgi-bin/webscr?cmd=_notify-synch&tx='.$tx.'&at=token here'; 

$curl = curl_init($paypal_url); 

$data = array(

"cmd" => "_notify-synch", 

"tx" => $tx, 

"at" => "token here" 


);                  

$data_string = json_encode($data); 

curl_setopt ($curl, CURLOPT_HEADER, 0); 

curl_setopt ($curl, CURLOPT_POST, 1); 

curl_setopt ($curl, CURLOPT_POSTFIELDS, $data_string); 

curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0); 

curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1); 

curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, 1); 

$headers = array (

'Content-Type: application/x-www-form-urlencoded', 

'Host: www.paypal.com', 

'Connection: close' 

); 

curl_setopt ($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 

curl_setopt ($curl, CURLOPT_HTTPHEADER, $headers); 

$response = curl_exec($curl); 

$lines = explode("\n", $response); 

$keyarray = array(); 

if (strcmp ($lines[0], "SUCCESS") == 0) { 

for ($i=1; $i<count($lines);$i++){ 

list($key,$val) = explode("=", $lines[$i]); 

$keyarray[urldecode($key)] = urldecode($val); 

} 


$first_name=$keyarray['first_name']; 

$last_name=$keyarray['last_name']; 

$payment_status=$keyarray['payment_status']; 

$business=$keyarray['business']; 

$payer_email=$keyarray['payer_email']; 

$payment_gross=$keyarray['payment_gross']; 

$mc_currency=$keyarray['mc_currency']; 

} 
0

解析PDT響應時,我使用parse_str。由於響應主體是URL編碼,它只是一個根據不同的應用,你甚至可以離開了第二個參數($這個 - >詳細信息與ampersands-替換換行符這樣

$result = curl_exec($ch);  
//replace the breaks with '&' 
$r_string = str_replace("\n", "&", $result); 
//parse the response into a key->value array 
        parse_str($r_string, $this->details); 
        if(!isset($this->details['SUCCESS'])){ 
       //the "SUCCESS" or "FAIL" response is the first key 
    return FALSE; 
        } 
        else{ 
//the values of the response are now in an array 
         return TRUE; 

        } 

的事)並將值設置爲全局變量。