我想在我的网站上创建一个简单的交易,在该人的交易完成后,我希望paypal重定向用户去我网站上的某个地方,我希望PayPal向我提供详细信息,以便我可以使用PHP解析它并通过电子邮件发送给他们购买的链接。我不确定notify_url是做什么的?感谢
答案 0 :(得分:58)
PayPal的工作原理如下:
您的表单中有“购买”按钮。点击后,它会向PayPal发送信息(产品,价格,您的帐户名称等)。
买方同意向您付款,交易完成后,PayPal会向您的通知网址发送“IPN”(即时付款通知) - 它会将POST数据发送到该网址,供服务器处理。您回复PayPal询问他们是否发送了POST数据(而不是冒名顶替者),如果他们回答这是真实交易,您可以将产品发布给客户。请注意,这一切都发生在后台,而您的买家仍然在PayPal网站上。
最后一个可选阶段是PayPal将买家退回到您的网站。在这种情况下,他们将买家发送回您的“返回”网址,他们可以(可选)再次传回交易数据(他们称之为PDT)。如果这是一个有效的交易,您可以再次使用Paypal进行检查,并在此时提供下载等。
没有人解释的最困难的一点是买家没有被重定向到您的通知网址。即,您网站的通知URL的“访问者”是PayPal,不是买方,因此这不会作为买方会话的一部分发生。如果您希望在此过程的三个部分中保持会话,则需要创建一种在表单中跟踪买方的方法,并将其传递给名为“custom”的字段中的PayPal。此数据将在IPN和PDT数据中传回给您,您可以使用此数据重新建立与原始用户会话的连接。
您确实需要同时实施IPN和PDT - 如果IPN电子邮件失败,那么您将PDT作为备份。如果用户在将Web浏览器重定向回PDT页面之前将其关闭,那么您已发送IPN电子邮件作为备份。
搜索IPN和PDT,你会发现很多信息。 PayPal还有完整的文档和示例脚本。
答案 1 :(得分:6)
通知URL应该指向保存PayPal返回数据的脚本,例如:
/** 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 :(得分: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'];
}
答案 3 :(得分:0)
使用parse_str解析PDT响应时。由于响应的主体是url编码的,所以只需用&符号替换换行符就像这样
$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;
}
取决于应用程序,您甚至可以省略第二个参数( $ this-&gt; details ),并将值设置为全局变量。