Я пишу плагин WordPress, который обрабатывает платежи через PayPal. У меня есть сценарий IPN PayPal, который отправляет уведомление по электронной почте (в дополнение к уведомлению по электронной почте PayPal), когда платеж будет успешным. Некоторые пользователи моего плагина сообщают, что они получают несколько копий этого уведомления по электронной почте в течение нескольких дней.PayPal IPN работает повторно
Я обнаружил эту проблему на ранней стадии, когда я разрабатывал плагин, и решение, которое я нашел, это немедленно отправить PayPal на 200 ответов. (Ниже приведено обсуждение проблемы: https://www.paypal-community.com/t5/About-Settings-Archive/Paypal-repeats-identical-IPN-posts/td-p/465559). Кажется, что это работает на моем тестовом сайте, но, очевидно, не работает для всех моих пользователей.
Когда я использую симулятор IPN PayPal, он не дает мне никаких сообщений об ошибках.
Помимо отправки ответа от 200 сразу, есть ли что-нибудь, что я могу сделать, чтобы остановить повторение запроса IPN от PayPal?
Вот мой код:
<?php
// Create a query var so PayPal has somewhere to go
// https://willnorris.com/2009/06/wordpress-plugin-pet-peeve-2-direct-calls-to-plugin-files
function cdashmm_register_query_var($vars) {
$vars[] = 'cdash-member-manager';
return $vars;
}
add_filter('query_vars', 'cdashmm_register_query_var');
// If PayPal has gone to our query var, check that it is correct and process the payment
function cdashmm_parse_paypal_ipn_request($wp) {
// only process requests with "cdash-member-manager=paypal-ipn"
if (array_key_exists('cdash-member-manager', $wp->query_vars) && $wp->query_vars['cdash-member-manager'] == 'paypal-ipn') {
if(!isset($_POST['txn_id'])) {
// send a 200 message to PayPal IPN so it knows this happened
header('HTTP/1.1 200 OK');
// POST data isn't there, so we aren't going to do anything else
} else {
// we have valid POST, so we're going to do stuff with it
// send a 200 message to PayPal IPN so it knows this happened
header('HTTP/1.1 200 OK');
// process the request.
$req = 'cmd=_notify-validate';
foreach($_POST as $key => $value) :
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
endforeach;
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www.paypal.com\r\n";
$header .= "Connection: close\r\n\r\n";
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
if(!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while(!feof($fp)) {
$res = fgets ($fp, 1024);
$fh = fopen('result.txt', 'w');
fwrite($fh, $res);
fclose($fh);
if (strcmp (trim($res), "VERIFIED") == 0) {
/* Do a bunch of WordPress stuff - create some posts, send some emails */
}
elseif(strcmp (trim($res), "INVALID") == 0) {
// probably ought to do something here
}
}
fclose ($fp);
}
}
}
}
add_action('parse_request', 'cdashmm_parse_paypal_ipn_request');
?>
Спасибо! Я на самом деле уже храню идентификатор транзакции, поэтому я могу использовать некоторые запросы WordPress, чтобы убедиться, что он уже существует. – Gwendydd