Paypal ipn返回403在最近一个月与php代码



上个月我的pal整合返回错误,我认为是paypal的政策发生了变化。这是错误:

[08/12/2021 11:59 AM] - FAIL: IPN Validation Failed.
IPN Response from Paypal Server:
HTTP/1.1 403 Forbidden
Content-Type: text/html
Content-Length: 38
Connection: close
DC: phx-origin-www-1.paypal.com
Strict-Transport-Security: max-age=31536000; includeSubDomains
<html><body>403 Forbidde</body></html>

上个月就开始了。这是我使用的API url:

https://api-3t.paypal.com/nvp

这是paypal类

<?php
class paypal_class {
var $last_error;                 // holds the last error encountered
var $ipn_log;                    // bool: log IPN results to text file?
var $ipn_log_file;               // filename of the IPN log
var $ipn_response;               // holds the IPN response from paypal   
var $ipn_data = array();         // array contains the POST values for IPN
var $fields = array();           // array holds the fields to submit to paypal
function __construct() {
// initialization constructor.  Called when class is created.
$this->paypal_url = 'https://ipnpb.paypal.com/cgi-bin/webscr';
$this->api_url = 'https://api-3t.paypal.com/nvp';
$this->last_error = '';
$this->ipn_log_file = 'ipn_log.txt';
$this->ipn_log = true;
$this->ipn_response = '';
// populate $fields array with a few default values.  See the paypal
// documentation for a list of fields and their data types. These defaul
// values can be overwritten by the calling script.
// Return method = POST
$this->add_field('cmd', '_cart');
}
function add_field($field, $value) {
// adds a key=>value pair to the fields array, which is what will be 
// sent to paypal as POST variables.  If the value is already in the 
// array, it will be overwritten.
$this->fields["$field"] = $value;
}
function submit_paypal_post($type = false) {
// this function actually generates an entire HTML page consisting of
// a form with hidden elements which is submitted to paypal via the 
// BODY element's onLoad attribute.  We do this so that you can validate
// any POST vars from you custom form before submitting to paypal.  So 
// basically, you'll have your own form which is submitted to your script
// to validate the data, which in turn calls this function to create
// another hidden form and submit to paypal.
// The user will briefly see a message on the screen that reads:
// "Please wait, your order is being processed..." and then immediately
// is redirected to paypal.
$form = array();
$output = "<html>n";
$output .= "<head><title>טוען תשלום...</title></head>n";
$output .= "<body onLoad="document.form.submit();">n";
$output .= "<form method="post" name="form" action="" . $this->paypal_url . "">n";
foreach ($this->fields as $name => $value) {
$output .= "<input type="hidden" name="$name" value="$value">";
$form[] = array(
"name" => $name,
"value" => $value,
"type" => "hidden"
);
}
$output .= "</form>n";
$output .= "</body></html>n";
if ($type)
return array("form" => $form, "action" => $this->paypal_url);
return $output;
}
function validate_ipn() {
// parse the paypal URL
$url_parsed = parse_url($this->paypal_url);
// generate the post string from the _POST vars aswell as load the
// _POST vars into an arry so we can play with them from the calling
// script.
$post_string = '';
foreach ($_POST as $field => $value) {
$this->ipn_data[$field] = $value;
$post_string .= $field . '=' . urlencode($value) . '&';
}
$post_string.="cmd=_notify-validate"; // append ipn command
// open the connection to paypal
$fp = fsockopen("ssl://" . $url_parsed["host"], 443, $err_num, $err_str, 30);
if (!$fp) {
$this->last_error = "fsockopen error no. $errnum: $errstr";
$this->log_ipn_results(false);
return false;
} else {
// Post the data back to paypal
fputs($fp, "POST {$url_parsed["path"]} HTTP/1.1rn");
fputs($fp, "Host: {$url_parsed["host"]}rn");
fputs($fp, "Content-type: application/x-www-form-urlencodedrn");
fputs($fp, "Content-length: " . strlen($post_string) . "rn");
fputs($fp, "Connection: closernrn");
fputs($fp, $post_string . "rnrn");
// loop through the response from the server and append to variable
while (!feof($fp)) {
$this->ipn_response .= fgets($fp, 1024);
}
fclose($fp); // close connection
}
if (preg_match("/VERIFIED/i", $this->ipn_response)) {
// Valid IPN transaction.
$this->log_ipn_results(true);
return true;
} else {
// Invalid IPN transaction.  Check the log for details.
$this->last_error = 'IPN Validation Failed.';
$this->log_ipn_results(false);
return false;
}
}
function log_ipn_results($success) {
if (!$this->ipn_log)
return;  // is logging turned off?
// Timestamp
$text = '[' . date('m/d/Y g:i A') . '] - ';
// Success or failure being logged?
if ($success)
$text .= "SUCCESS!n";
else
$text .= 'FAIL: ' . $this->last_error . "n";
// Log the POST variables
$text .= "IPN POST Vars from Paypal:n";
foreach ($this->ipn_data as $key => $value) {
$text .= "$key=$value, ";
}
// Log the response from the paypal server
$text .= "nIPN Response from Paypal Server:n " . $this->ipn_response;
// Write to log
$fp = fopen($this->ipn_log_file, 'a');
fwrite($fp, $text . "nn");
fclose($fp);  // close file
}
function dump_fields() {
// Used for debugging, this function will output all the field/value pairs
// that are currently defined in the instance of the class using the
// add_field() function.
echo "<h3>paypal_class->dump_fields() Output:</h3>";
echo "<table width="95%" border="1" cellpadding="2" cellspacing="0">
<tr>
<td bgcolor="black"><b><font color="white">Field Name</font></b></td>
<td bgcolor="black"><b><font color="white">Value</font></b></td>
</tr>";
ksort($this->fields);
foreach ($this->fields as $key => $value) {
echo "<tr><td>$key</td><td>" . urldecode($value) . "&nbsp;</td></tr>";
}
echo "</table><br>";
}
public function pay($username, $password, $signature, $email, $amount, $note = "Instant Payment") {
$version = urlencode("51.0");
$api = $this->api_url;
$type = urlencode("EmailAddress");
$currency = urlencode("USD");
$subject = urlencode("Instant Paypal Payment");

$string = "&EMAILSUBJECT=" . $subject . "&RECEIVERTYPE=" . $type . "&CURRENCYCODE=" . $currency;
$string .= "&L_EMAIL0=" . urlencode($email) . "&L_Amt0=" . urlencode($amount) . "&L_NOTE0=" . urlencode($note);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$request = "METHOD=MassPay&VERSION=" . $version . "&PWD=" . $password . "&USER=" . $username . "&SIGNATURE=" . $signature . "$string";
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
$httpResponse = curl_exec($ch);
if (!$httpResponse) {
exit("MassPay failed: " . curl_error($ch) . '(' . curl_errno($ch) . ')');
}
$httpResponseArray = explode("&", $httpResponse);
$httpParsedResponse = array();
foreach ($httpResponseArray as $i => $value) {
$tempArray = explode("=", $value);
if (sizeof($tempArray) > 1) {
$httpParsedResponse[$tempArray[0]] = $tempArray[1];
}
}
if ((0 == sizeof($httpParsedResponse)) || !array_key_exists('ACK', $httpParsedResponse)) {
exit("Invalid HTTP Response for POST request($request) to " . $api);
}
return $httpParsedResponse;
}
}

我能做什么?我试着在谷歌上搜索任何政策更新,但没有运气。tnx

正如IPN集成指南中提到的,确保在请求头中包含User-Agent:字段,其值为任意字符串>7个字符左右

对于实时IPN验证,您还应该使用域ipnpb.paypal.com而不是www.paypal.com

相关内容

最新更新