IPN 验证返回 INVALID,因为 PayPal 在 POST 中向 IPN 侦听器发送了不正确的字符集

Posted

技术标签:

【中文标题】IPN 验证返回 INVALID,因为 PayPal 在 POST 中向 IPN 侦听器发送了不正确的字符集【英文标题】:IPN verification returns INVALID as PayPal is sending incorrect charset in POST to IPN Listener 【发布时间】:2014-12-24 13:05:16 【问题描述】:

以下所有内容都在 PayPal 沙箱中:

我有一个 PayPal 订阅/定期付款设置,它使用 IPN 侦听器作为在我的网站数据库中创建或更新用户订阅的最后一步。但是,当我从 paypal 收到 POST 数据并将其发回以进行验证时,我收到的唯一响应是“INVALID”。

我知道我的代码正确地将 POST 数据发送回 PayPal,因为当我通过使用“IPN 消息”值对 POST 数据字符串进行硬编码来模仿正确的 POST 给我的听众时,我得到了一个“已验证”响应,如上所示PayPal 的 IPN 历史页面。

因此,我的代码将 POST 数据发送回 PayPal 以进行最终验证,并且我的 IPN 侦听器正在接收交易的 POST 变量。我的 IPN 侦听器创建的用于发送回 PayPal 的 POST 数据字符串与 PayPal 期望接收的 POST 数据字符串存在差异。

PayPal 声明 IPN 侦听器必须使用与 PayPal 发送数据相同的值、顺序和编码发回它接收到的 POST 数据。

我认为问题是编码问题,因为在我的听众的 PayPal POST 中,“charset”的值“windows-1252”应该是“UTF-8”。但是,“form_charset”的正确值是“UTF-8”。

我已在卖家 PayPal 个人资料的两个输入字段中将编码设置为 UTF-8,并在初始 PayPal 表单/按钮中隐藏了一个输入,名称为“charset”,值为“UTF-8”。请告诉我是否还有其他方法可以设置我错过的编码。

PayPal 声称要发送的部分 POST 数据字符串包括“&notify_version=3.8”,后跟更多变量。当我手动插入此字符串以测试我的代码时,“&not”在打印到页面时转换为“¬”,据我了解,这意味着正在使用的字符编码是“windows-1252”,因为“¬”在windows-1252字符集,但“¬”不在UTF-8字符集中,所以如果使用UTF-8,“&not”不会这样转换。

如何让 PayPal 使用 UTF-8 字符编码将数据实际发布到我的 IPN 侦听器?请记住,这是一项定期付款,因此某些方面可能会有所不同。

我不认为问题出在我身上,因为我尝试了不同的方法、不同的编码/解码发布数据的方式、外部库、cUrl/sockets、不同版本的 SSL、不同的标头、重新启动服务器,重新创建购买等。 所以 Paypal 向我发送了错误的 POST 数据,或者我错误地形成了 post 字符串。后者是可能的,但我已经尝试了所有我能找到的用于形成帖子字符串的方法,但都没有奏效。

我已经解决这个问题好几天了,所以任何帮助或指点都将非常感激。

PS: 一些可能相关或不相关的注释:

这个订阅系统是几个月前创建的,只是在过去几周的某个时候莫名其妙地停止了工作。那时 AFAIK 没有更改相关代码。

开始调试这个问题的第一天,沙盒的卖家账号数据完全不正确,本来应该是企业账号,却被列为个人账号,也就是说没有设置IPN可用的。第二天,同一个帐户莫名其妙地工作并显示为商业帐户,因为它本来应该有。我不知道我的任何行为导致了这种变化。也许贝宝发送错误的字符编码是一个类似的问题? cron作业上的一些缓存系统?我现在只是猜测,我真的没有头绪。

关于我的最后一点,登录卖家沙盒帐户非常不可靠。有时我尝试在会话超时后重新登录并收到一个错误代码,该代码仅在注册新帐户的情况下才有意义。其他时候登录不起作用,结果是我在会话超时后尝试登录的一小部分,我必须清除我的 cookie 才能重新登录。

【问题讨论】:

您是否尝试在此处更改沙箱中的编码格式sandbox.paypal.com/cgi-bin/… @Eshan 是的,它没有修复它。 当您访问上述链接时,您是否点击了“更多选项”链接,因为它还会为您提供设置 IPN 编码的选项? @Eshan 是的,两个输入都设置为“UTF-8”。我不清楚,这就是我的意思是“我已在卖家 PayPal 个人资料的两个输入字段中将编码设置为 UTF-8” @Sha 我刚刚为你回答了我自己的问题;基本上这只是 Paypal 的一个错误,您必须同时使用 IPN 和 PDT 才能绕过它。 【参考方案1】:

这是一个 tldr;

根据 Miles 的经验,PayPal 沙盒中似乎存在一个错误,这意味着字符集设置无效。

我发现这个bug已经解决了。

在您的 PayPal 设置中更改字符集

登录您的商家帐户 点击个人资料 在销售偏好下单击语言编码 按“更多选项”按钮

选择您网站的编码并将使用相同设置按钮保留为是

保存您的设置。

【讨论】:

【参考方案2】:

解决方案最终是同时使用 IPN 侦听器和 PDT,只需确保两个脚本都检查以验证交易尚未收到,这样交易不会被多次收到。

因此,只需跟踪数据库中的贝宝交易,并在 IPN 侦听器和 PDT 脚本中检查该数据库。

【讨论】:

感谢您的回复。我最终将对 PayPal 的请求编码为 UTF-8。在沙盒模式下,我总是得到(获取)Windows-1252,导致请求失败。我确实将 PayPal Sandbox 仪表板中的设置更改为 UTF-8 - 同样的问题。从沙盒切换到生产模式解决了这个问题(当然,在 PayPal 生产仪表板中具有正确的 UTF-8 编码设置)。在我看来,这就像 PayPal 沙盒没有保存编码设置的错误。在这个上浪费了几个小时。

以上是关于IPN 验证返回 INVALID,因为 PayPal 在 POST 中向 IPN 侦听器发送了不正确的字符集的主要内容,如果未能解决你的问题,请参考以下文章

IPN 验证 ipnSimulator INVALID

Paypal ipn 未验证:无效

Paypal 沙盒 IPN 返回无效

Paypal SandBox IPN 总是返回 INVALID

Paypal IPN 现在返回 INVALID - PHP 代码以前工作正常

Rails 监听器 Paypal IPN 总是返回 INVALID