- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 Wordpress 插件 Donate Plus,它已经有一段时间没有更新了,而且对于大多数用户来说都不能正常工作。所以我对代码做了一些修改,试图让它再次工作。除了在我的 PayPal 帐户的 IPN 历史记录中,所有交易都具有“正在重试”的传递状态和 HTTP 响应代码 404,我一切正常。
脚本中有一个 IPN 调试功能,它返回“已验证的 IPN 交易 [已完成]”,表明一切正常。但是,我收到多条调试消息、多条发送的感谢消息以及 MySQL 数据库中的多条条目,我认为所有这些都与“重试”问题有关。
我已经在 PayPal 中手动设置了通知 URL,因为我听说这可以解决一些问题。但是我仍然遇到同样的问题。
我知道脚本需要将完整的未更改的 IPN 消息发送回 PayPal;即消息必须包含相同顺序的相同字段,并以与原始消息相同的方式进行编码。但是,我不确定如何检查 $postipn 返回的内容,以检查这是否是问题所在。
我在下面包含了完整的 paypal.php 脚本,以防任何人发现问题所在:
<?php
/*
//************************************************************
//************************************************************
//** Bugs fixed by... **
//** **
//** Copyright Encentra 2011 **
//** www.encentra.se **
//** consultant: Johan Rufus Lagerström **
//************************************************************
//************************************************************
*/
#########################################################
# #
# File : PayPal.php #
# Version : 1.9 #
# Last Modified : 12/15/2005 #
# Copyright : This program is free software; you #
# can redistribute it and/or #modify it under the terms #
# of the GNU General Public License as published by the #
# Free Software Foundation #
# See the #GNU General Public License for more details. #
# DO NOT REMOVE LINK #
# Visit: http://www.belahost.com for updates/scripts #
#########################################################
# THIS SCRIPT IS FREEWARE AND IS NOT FOR RE-SALE #
#########################################################
require("../../../wp-blog-header.php");
global $wpdb;
$dplus = get_option('DonatePlus');
$email_IPN_results = $dplus['IPN_email'];
$tmp_nl = "\r\n";
if(class_exists('DonatePlus'))$donateplus = new DonatePlus();
#1 = Live on PayPal Network
#2 = Testing with www.BelaHost.com/pp
#3 = Testing with the PayPal Sandbox
$verifymode = $dplus['testing_mode']; # be sure to change value for testing/live!
# Send notifications to here
$send_mail_to = $dplus['paypal_email'];
# subject of messages
$sysname = "Donate Plus - Paypal IPN Transaction";
# Your primary PayPal e-mail address
//$paypal_email = $dplus['paypal_email'];
# Your sendmail path
//$mailpath = "/usr/sbin/sendmail -t";
#the name you wish to see the messages from
//$from_name = $dplus['ty_name'];
#the emails will be coming from
//$from_email = $dplus['ty_email'];
# Convert Super globals For backward compatibility
if(phpversion() <= "4.0.6") {$_POST=($HTTP_POST_VARS);}
# Check for IPN post if none then return 404 error.
if (!$_POST['txn_type']){
if( $email_IPN_results ) send_mail($send_mail_to,$sysname." [ERROR - 404]","IPN Fail: 404 error!","",__LINE__);
header("Status: 404 Not Found");
die();
}else{
header("Status: 200 OK");
}
# Now we Read the Posted IPN
$postvars = array();
//print_r($_POST);
foreach ($_POST as $ipnvars => $ipnvalue){
$postvars[] = $ipnvars; $postvals[] = $ipnvalue;
}
# Now we ADD "cmd=_notify-validate" for Post back Validation
$postipn = 'cmd=_notify-validate';
$orgipn = '<b>Posted IPN variables in order received:</b><br><br>';
# Prepare for validation
for($x=0; $x < count($postvars); $x++){
$y = $x+1;
$postkey = $postvars[$x];
$postval = $postvals[$x];
$postipn .= "&".$postkey."=".urlencode($postval);
$orgipn .= "<b>#".$y."</b> Key: ".$postkey." <b>=</b> ".$postval."<br>";
}
if($verifymode == 1){ //1 = Live on PayPal Network
## Verify Mode 1: This will post the IPN variables to the Paypal Network for Validation
$port = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
//$port = fsockopen ("paypal.com", 80, $errno, $errstr, 30);
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n".
"Host: www.paypal.com\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($postipn)."\r\n\r\n";
}elseif ($verifymode == 2){ //2 = Testing with www.BelaHost.com/pp
## Verify Mode 2: This will post the IPN variables to Belahost Test Script for validation
## Located at www.belahost.com/pp/index.php
$port = fsockopen ("www.belahost.com", 80, $errno, $errstr, 30);
$header = "POST /pp/ HTTP/1.0\r\n".
"Host: www.belahost.com\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($postipn)."\r\n\r\n";
}elseif ($verifymode == 3){ //3 = Testing with the PayPal Sandbox
$port = fsockopen ("ssl://www.sandbox.paypal.com", 443, $errno, $errstr, 30);
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n".
"Host: www.sandbox.paypal.com\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($postipn)."\r\n\r\n";
}else{
$error=1;
//echo "CheckMode: ".$verifymode." is invalid!";
if( $email_IPN_results ) send_mail($send_mail_to,$sysname." [ERROR - Misc]","Fail: CheckMode: ".$verifymode." is invalid!","",__LINE__);
die();
}
# Error at this point: If at this point you need to check your Firewall or your Port restrictions?
if (!$port && !$error){
//echo "Problem: Error Number: ".$errno." Error String: ".$errstr;
#Here is a small email notification so you know if your system ever fails
if( $email_IPN_results ) send_mail($send_mail_to,$sysname." [ERROR - Misc]","Your Paypal System failed due to $errno and string $errstr","",__LINE__);
die();
}else{
# If No Errors to this point then we proceed with the processing.
# Open port to paypal or test site and post Varibles.
fputs ($port, $header.$postipn);
while (!feof($port)){
$reply = fgets ($port, 1024);
$reply = trim ($reply);
}
# Prepare a Debug Report
$ipnreport = $orgipn."<br><b>"."IPN Reply: ".$reply."</b>";
# Buyer Information
$address_city = $_POST['address_city'];
$address_country = $_POST['address_country'];
$address_country_code = $_POST['address_country_code'];
$address_name = $_POST ['address_name'];
$address_state = $_POST['address_state'];
$address_status = $_POST['address_status'];
$address_street = $_POST['address_street'];
$address_zip = $_POST['address_zip'];
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$payer_business_name = $_POST['payer_business_name'];
$payer_email = $_POST['payer_email'];
$payer_id = $_POST['payer_id'];
$payer_status = $_POST['payer_status'];
$residence_country = $_POST['residence_country'];
# Below Instant BASIC Payment Notifiction Variables
$business = $_POST['business'];
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$quantity = $_POST['quantity'];
$receiver_email = $_POST['receiver_email'];
$receiver_id = $_POST['receiver_id'];
#Advanced and Customer information
$custom = $_POST['custom'];
$invoice = $_POST['invoice'];
$memo = $_POST['memo'];
$option_name1 = $_POST['option_name1']; //name
$option_name2 = $_POST['option_name2'];
$option_selection1 = $_POST['option_selection1']; //email
$option_selection2 = $_POST['option_selection2']; //comment
$tax = $_POST['tax'];
#Website Payment Pro and Other IPN Variables
$auth_id = $_POST['auth_id'];
$auth_exp = $_POST['auth_exp'];
$auth_amount = $_POST['auth_amount'];
$auth_status = $_POST['auth_status'];
# Shopping Cart Information
$mc_gross = $_POST['mc_gross'];
$mc_handling = $_POST['mc_handling'];
$mc_shipping = $_POST['mc_shipping'];
$num_cart_items = $_POST['num_cart_items'];
# Other Transaction Information
$parent_txn_id = $_POST['parent_txn_id'];
$payment_date = $_POST['payment_date'];
$payment_status = $_POST['payment_status'];
$payment_type = $_POST['payment_type'];
$pending_reason = $_POST['pending_reason'];
$reason_code = $_POST['reason_code'];
$remaining_settle = $_POST['remaining_settle'];
$transaction_entity = $_POST['transaction_entity'];
$txn_id = $_POST['txn_id'];
$txn_type = $_POST['txn_type'];
# Currency and Exchange Information
$exchange_rate = $_POST['exchange_rate'];
$mc_currency = $_POST['mc_currency'];
$mc_fee = $_POST['mc_fee'];
$payment_fee = $_POST['payment_fee'];
$payment_gross = $_POST['payment_gross'];
$settle_amount = $_POST['settle_amount'];
$settle_currency = $_POST['settle_currency'];
# Auction Information
$for_auction = $_POST['for_auction'];
$auction_buyer_id = $_POST['auction_buyer_id'];
$auction_closing_date = $_POST['auction_closing_date'];
$auction_multi_item = $_POST['auction_multi_item'];
# Below are Subscription - Instant Payment Notifiction Variables
$subscr_date = $_POST['subscr_date'];
$subscr_effective = $_POST['subscr_effective'];
$period1 = $_POST['period1'];
$period2 = $_POST['period2'];
$period3 = $_POST['period3'];
$amount1 = $_POST['amount1'];
$amount2 = $_POST['amount2'];
$amount3 = $_POST['amount3'];
$mc_amount1 = $_POST['mc_amount1'];
$mc_amount2 = $_POST['mc_amount2'];
$mc_amount3 = $_POST['mc_amount3'];
$recurring = $_POST['recurring'];
$reattempt = $_POST['reattempt'];
$retry_at = $_POST['retry_at'];
$recur_times = $_POST['recur_times'];
$username = $_POST['username'];
$password = $_POST['password'];
$subscr_id = $_POST['subscr_id'];
# Complaint Variables Used when paypal logs a complaint
$case_id = $_POST['case_id'];
$case_type = $_POST['case_type'];
$case_creation_date = $_POST['case_creation_date'];
#Last but not least
$notify_version = $_POST['notify_version'];
$verify_sign = $_POST['verify_sign'];
#There are certain variables that we will not store for cart since they are dynamic
#such as mc_gross_x as they will be forever changing/increasing your script must check these
#IPN was Confirmed as both Genuine and VERIFIED
if(!strcmp($reply, "VERIFIED")){
/* Now that IPN was VERIFIED below are a few things which you may want to do at this point.
1. Check that the "payment_status" variable is: "Completed"
2. If it is Pending you may want to wait or inform your customer?
3. You should Check your datebase to ensure this "txn_id" or "subscr_id" is not a duplicate. txn_id is not sent with subscriptions!
4. Check "payment_gross" or "mc_gross" matches match your prices!
5. You definately want to check the "receiver_email" or "business" is yours.
6. We have included an insert to database for table paypal_ipn
*/
$split = explode(':', $item_number);
$display = $split[0];
$uID = $split[1];
$url = 'http://'.str_replace('http://','',$option_name2);
if(!$mc_gross)$mc_gross = $payment_gross;
$table_name = $wpdb->prefix."donations";
//kontrollera om transaktionen redan finns sparad
$tmp_txn_id = $wpdb->escape($txn_id);
$tmp_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $table_name WHERE txn_id='$tmp_txn_id';"));
//if($payment_status == 'Completed'){
if($tmp_count == 0){
//all pin:s som kommer in tolkar vi som complete
$tmp_payment_status = "Completed";
$mc_net = $mc_gross - $mc_fee;
//USE SECURE INSERT!
$wpdb->query(
$wpdb->prepare("INSERT INTO $table_name
( name, email, url, comment, display, amount, charge, net, currency, date, user_id, status, txn_id )
VALUES ( %s, %s, %s, %s, %d, %s, %s, %s, %s, %s, %d, %s, %s )",
$option_name1, $option_selection1, $url, strip_tags($option_selection2), $display, $mc_gross, $mc_fee, $mc_net, $mc_currency, date('Y-m-d H:i:s'), $uID, $tmp_payment_status, $txn_id )
);
//send payer thank you email about where to download
global $currency;
$subject = stripslashes($dplus['ty_subject']);
$prefix = $currency[$mc_currency]['symbol'];
$amount = $prefix.$mc_gross.' '.$mc_currency;
$payer_msg = nl2br($donateplus->TagReplace(stripslashes($dplus['ty_emailmsg']), $option_name1, $amount));
//$payer_msg = utf8_encode($payer_msg);
//echo '<br />'.$payer_msg;
$headers = 'MIME-Version: 1.0'."\r\n";
//$headers .= 'Content-type: text/html; charset=iso-8859-1'."\r\n";
$headers .= 'Content-type: text/html; charset=utf-8'."\r\n";
$headers .= 'From: '.$dplus['ty_name'].' <'.$dplus['ty_email'].'>'."\r\n";
wp_mail($option_selection1, $subject, $payer_msg, $headers);
//wp_mail($notify_email, 'New Donation Recieved!', "Donation from $option_name1 for $payment_amount");
//echo $postquery;
if( $email_IPN_results ) send_mail($send_mail_to,$sysname." [PIN - Completed]","\n Verified IPN Transaction [Completed] \n \n$ipnreport\n","",__LINE__);
}else{
//not "Completed"
//tar bort nedan, annars trilalr det in 10 mail per donation
//send_mail($send_mail_to,$sysname." [PIN - $payment_status]","\n Verified IPN Transaction [$payment_status] \n \n$ipnreport\n","",__LINE__);
}
}elseif(!strcmp($reply, "INVALID")){ # IPN was Not Validated as Genuine and is INVALID
/* Now that IPN was INVALID below are a few things which you may want to do at this point.
1. Check your code for any post back Validation problems!
2. Investigate the Fact that this Could be an attack on your script IPN!
3. If updating your DB, Ensure this "txn_id" is Not a Duplicate!
*/
# Remove Echo line below when live
//echo $ipnreport;
if( $email_IPN_results ) send_mail($send_mail_to,$sysname." [ERROR - Invalid]","Invalid IPN Transaction".$tmp_nl.$tmp_nl.$ipnreport,"",__LINE__);
}else{ #ERROR
# If your script reaches this point there is a problem. Communication from your script to test/paypal pages could be 1 reason.
echo $ipnreport;
if( $email_IPN_results ) send_mail($send_mail_to,$sysname." [ERROR - Misc]","FATAL ERROR No Reply at all".$tmp_nl.$tmp_nl.$ipnreport,"",__LINE__);
}
#Terminate the Socket connection and Exit
fclose ($port);
die();
}
/* =================================
Below are functions
================================= */
# Email function
function send_mail($to, $subj, $body, $headers="",$tmp_line=0){
//global
global $tmp_nl;
//var_dump till en sträng
$posts = var_export($_POST, true);
//body
$tmp_body = "===================================".$tmp_nl.
$subj." [line: $tmp_line]".$tmp_nl.
"===================================".$tmp_nl.
$body.$tmp_nl.
$tmp_nl.
"===================================".$tmp_nl.
$posts;
//skickar mail
wp_mail($to, $subj, $tmp_body, $headers);
/*
global $from_name, $from_email, $mailpath;
# E-mail Configuration
$announce_subject = "$subj";
$announce_from_email = "$from_email";
$announce_from_name = "$from_name";
$announce_to_email = "$to";
$MP = "$mailpath";
$spec_envelope = 1;
# End email config
# Access Sendmail
# Conditionally match envelope address
if(isset($spec_envelope))
{
$MP .= " -f $announce_from_email";
}
$fd = popen($MP,"w");
fputs($fd, "To: $announce_to_email\n");
fputs($fd, "From: $announce_from_name <$announce_from_email>\n");
fputs($fd, "Subject: $announce_subject\n");
fputs($fd, "X-Mailer: MyPayPal_Mailer\n");
fputs($fd, "Content-Type: text/html\n");
fputs($fd, $body); # $body will be sent when the function is used
pclose($fd);
*/
}
?>
.htaccess 文件
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
<Files wp-cron.php>
allow from all
Satisfy Any
</Files>
AddType text/x-component .htc
最佳答案
对我来说,似乎只有几种可能性。
代码
if (!$_POST['txn_type']){
if( $email_IPN_results ) send_mail($send_mail_to,$sysname." [ERROR - 404]","IPN Fail: 404 error!","",__LINE__);
header("Status: 404 Not Found");
die();
}else{
header("Status: 200 OK");
}
显然是一个值得研究的部分,因为它输出 404。在我的 IPN 处理程序中,我使用 empty($_POST)
,您使用了 !$_POST['txn_type' ]
。您也可以尝试 !isset($_POST['txn_type'])
。 !$_POST['txn_type']
实际上是在评估 txn_type 是否等于 false,这不如专门检查该值是否一般存在那样可靠。我怀疑这是真正的问题,但值得关注。
404 的其他一些可能原因可能是:
我的钱会花在 htaccess 重定向问题上。我对重定向破坏我的表单发布太熟悉了。
编辑
您可以尝试制作一个简单的测试表单,完全跳过 paypal 来测试 IPN。简单到
<form method="post" action="IPN_URL">
<input type='hidden' name='txn_type' value='subscr_payment'>
<input type='submit' value='Test IPN'></form>
显然,用适当的 url 替换 IPN_URL。如果提交此内容不会对您造成 404,则该脚本设置 IPN URL 的方式可能有问题。
您还可以检查服务器日志是否有 404 错误,并将日志中缺失的 URL 与您希望看到的 URL 进行比较。
编辑 2
仅供引用,我对这个插件进行了测试,与您使用的版本相同,并且立即运行完美。我没有在 paypal 中设置 IPN URL。我将“测试模式”设置为“Live with Paypal”并填写了 PayPal 电子邮件地址字段,并将其他所有设置保留为默认值。我付款了,IPN 和其他一切都正常。我使用的是 3.4.1 版的普通 WP 设置(不是多站点)。
您在使用 WP 多站点吗?我知道在这些情况下设置页面中显示的 URL 可能是错误的。
看完http://wordpress.org/support/topic/plugin-donate-plus-ipn-not-working ,看起来这个插件实际上有一些问题。我快速环顾四周,http://wordpress.org/extend/plugins/paypal-donations/好像最近更新了一点,而且好像和另一个没有一样的怪癖。你可以阅读它here .最坏的情况,你可以切换到那个。
关于php - PayPal IPN 传递状态设置为 "Retrying",HTTP 响应代码为 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11776000/
我在 JavaScript 文件中运行 PHP,例如...... var = '';). 我需要使用 JavaScript 来扫描字符串中的 PHP 定界符(打开和关闭 PHP 的 )。 我已经知道使
我希望能够做这样的事情: php --determine-oldest-supported-php-version test.php 并得到这个输出: 7.2 也就是说,php 二进制检查 test.
我正在开发一个目前不使用任何框架的大型 php 站点。我的大问题是,随着时间的推移慢慢尝试将框架融入应用程序是否可取,例如在创建的新部件和更新的旧部件中? 比如所有的页面都是直接通过url服务的,有几
下面是我的源代码,我想在同一页面顶部的另一个 php 脚本中使用位于底部 php 脚本的变量 $r1。我需要一个简单的解决方案来解决这个问题。我想在代码中存在的更新查询中使用该变量。 $name)
我正在制作一个网站,根据不同的情况进行大量 PHP 重定向。就像这样...... header("Location: somesite.com/redirectedpage.php"); 为了安全起见
我有一个旧网站,我的 php 标签从 因为短标签已经显示出安全问题,并且在未来的版本中将不被支持。 关于php - 如何避免在 php 文件中写入
我有一个用 PHP 编写的配置文件,如下所示, 所以我想用PHP开发一个接口(interface),它可以编辑文件值,如$WEBPATH , $ACCOUNTPATH和 const值(value)观
我试图制作一个登录页面来学习基本的PHP,首先我希望我的独立PHP文件存储HTML文件的输入(带有表单),但是当我按下按钮时(触发POST到PHP脚本) )我一直收到令人不愉快的错误。 我已经搜索了S
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: What is the max key size for an array in PHP? 正如标题所说,我想知道
我正在寻找一种让 PHP 以一种形式打印任意数组的方法,我可以将该数组作为赋值包含在我的(测试)代码中。 print_r 产生例如: Array ( [0] => qsr-part:1285 [1]
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我在 MySQL 数据库中有一个表,其中存储餐厅在每个工作日和时段提供的菜单。 表结构如下: i_type i_name i_cost i_day i_start i_
我有两页。 test1.php 和 test2.php。 我想做的就是在 test1.php 上点击提交,并将 test2.php 显示在 div 中。这实际上工作正常,但我需要向 test2.php
我得到了这个代码。我想通过textarea更新mysql。我在textarea中回显我的MySQL,但我不知道如何更新它,我应该把所有东西都放进去吗,因为_GET模式没有给我任何东西,我也尝试_GET
首先,我是 php 的新手,所以我仍在努力学习。我在 Wordpress 上创建了一个表单,我想将值插入一个表(data_test 表,我已经管理了),然后从 data_test 表中获取所有列(id
我有以下函数可以清理用户或网址的输入: function SanitizeString($var) { $var=stripslashes($var); $va
我有一个 html 页面,它使用 php 文件查询数据库,然后让用户登录,否则拒绝访问。我遇到的问题是它只是重定向到 php 文件的 url,并且从不对发生的事情提供反馈。这是我第一次使用 html、
我有一个页面充满了指向 pdf 的链接,我想跟踪哪些链接被单击。我以为我可以做如下的事情,但遇到了问题: query($sql); if($result){
我正在使用 从外部文本文件加载 HTML/PHP 代码 $f = fopen($filename, "r"); while ($line = fgets($f, 4096)) { print $l
我是一名优秀的程序员,十分优秀!