捕获 PayPal 订阅取消
我在尝试捕获订阅取消时遇到很多问题。这是我从 Paypal 代码示例页面获得的 IPN。我添加了 mySQL 脚本,以便在用户结束订阅时减去 4000 个积分。当我用另一个 paypal 帐户测试代码时,一旦我取消订阅,4000 积分就不会被扣除。
是 paypal IPN 错误还是按钮错误还是什么!?
<?php
session_start();
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
//////////////////////////////////////////////I added this here also. Check if its canceled
if("subscr_cancel" = $_POST['txn_type']){
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment
/////I added this mysql
$password = secret
$username = secret
$websites= "websites";
$database = "k29803_1";
mysql_connect("localhost", $username, $password) or die(mysql_error());
mysql_select_db($database);
$query = "SELECT * FROM users WHERE username= '$_SESSION[username]' AND password = '$_SESSION[password]'";
$results = mysql_query($query)or die(mysql_error());
if(mysql_num_rows($results)==1){
$add_credits = "UPDATE users SET credits = credits +1000
WHERE username= '$_SESSION[username]' AND password = '$_SESSION[password]'";
mysql_query($add_credits) or die(mysql_error());
}
}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
}
?>
该按钮看起来像这样,
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="NQMGM2LCZUQRE">
<input type="hidden" name="item_name" value="1" />
<input type="hidden" name="item_number" value="01" />
<input type="hidden" name="amount" value="1.99" />
<input type="hidden" name="currency_code" value="USD" />
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
我被重定向到此页面,但我只是没有减去 MYSQL 值
I am having a lot of problems trying to capture the subscription cancellation. This is the IPN Im using which I got from Paypal's code sample page. I added the mySQL script to subtract 4000 credits when the user ends subscription. When I test the code with another paypal account, the 4000 credits are not subtracted once i cancel the subscription.
Is the paypal IPN wrong or is the button wrong or WHAT!?
<?php
session_start();
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
//////////////////////////////////////////////I added this here also. Check if its canceled
if("subscr_cancel" = $_POST['txn_type']){
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment
/////I added this mysql
$password = secret
$username = secret
$websites= "websites";
$database = "k29803_1";
mysql_connect("localhost", $username, $password) or die(mysql_error());
mysql_select_db($database);
$query = "SELECT * FROM users WHERE username= '$_SESSION[username]' AND password = '$_SESSION[password]'";
$results = mysql_query($query)or die(mysql_error());
if(mysql_num_rows($results)==1){
$add_credits = "UPDATE users SET credits = credits +1000
WHERE username= '$_SESSION[username]' AND password = '$_SESSION[password]'";
mysql_query($add_credits) or die(mysql_error());
}
}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
}
?>
The button looks like this
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="NQMGM2LCZUQRE">
<input type="hidden" name="item_name" value="1" />
<input type="hidden" name="item_number" value="01" />
<input type="hidden" name="amount" value="1.99" />
<input type="hidden" name="currency_code" value="USD" />
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
I get redirected to this page, but I just dont get the MYSQL values subtracted
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我看到的主要问题是您正在使用会话变量。请注意,命中您的 PHP 代码的请求将直接来自 PayPal 服务器,与当前登录的用户无关。
您需要将用户信息传递给 PayPal,以便 PayPal 可以将其作为 IPN 请求的一部分传递回您的服务器。您可以做的另一件事是检查 IPN 中的一些值,例如付款人的电子邮件地址 (
payer_email
) 或parent_txn_id
或payer_id
。我不确定订阅的情况,但退款和取消 IPN 将包含一个
parent_txn_id
,它提供原始购买的 txn_id,因此您可以使用它来查找用户的帐户。您需要做的是确保在购买时保存 IPN 中的所有信息,并通过 txn_id 或类似的用户帐户将其绑定。当取消到来时,使用
parent_txn_id
或您用来在数据库中查找帐户的任何值,然后将更改应用到用户的帐户。我发现上面的代码还存在许多其他问题。
您需要对添加到查询中的所有变量使用mysql_real_escape_string。您应该这样做:
其次,数组引用应该在键名称周围使用引号:
第三,您可能应该通过用户表中的行 ID 在数据库中定位用户(您确实将“id”的主键设置为自动递增,对吧?)而不是他们的用户名和密码。对用户进行身份验证后,您确实不应该将其密码保存在会话变量中。
The main problem I see is that you are using session variables. Please note that the request that hits your PHP code will be coming directly from the PayPal server and has nothing to do with the currently logged in user.
You need to pass the user information to PayPal so that PayPal can pass it back to your server as part of the IPN request. The other thing you can do is check some of the values coming in the IPN, for example, the payer's email address (
payer_email
) or theparent_txn_id
, orpayer_id
.I'm not sure about subscriptions, but refund and cancellation IPNs will include a
parent_txn_id
that provides the txn_id of the original purchase, so you can use that to locate the user's account.What you need to do is make sure that when a purchase is made that you're saving all the information from the IPN and tying that by the txn_id or similar to the user's account. When the cancelation comes in, use the
parent_txn_id
or whatever value you use to locate the account in the database and then apply the change to the user's account.I see a number of other issues with the code above.
You need to use mysql_real_escape_string on all variables that you add into a query. You should do this:
Second, array references should use quotes around the key name:
Third, you should probably be locating the user in the database by their row ID in the users table (you do have a primary key of "id" set as auto-increment, right?) instead of their username and password. After you authenticate a user, you really shouldn't be keeping their password in a session variable.
你的代码在这里有一个错误:
看看比较:
Your code have a bug here:
Look the comparation: