使用 Google Apps 脚本管理 Paypal IPN

Manage Paypal IPN with Google Apps Script

管理 IPN 有 4 个步骤:

  1. 通过 post 接收 Paypal 付款请求信息
  2. Return HTTP 200 响应
  3. Return 完成未更改的消息到 paypal
  4. 3 天后收到来自 Paypal 的验证或无效

要做到这一点,有一个例子 here。 我根据自己的需要对 Romain 脚本进行了一些定制,但理念是相同的,我知道 Romain 与 IPN 有同样的问题(我正在与他联系)。

问题是:我们无法验证 IPN 流程。 HTTP 响应代码的状态为 405。

我发现在 romain 脚本中,我们在第 2 步之前执行第 3 步。所以我进行了更改,现在脚本 return 是一个空答案:

return ContentService.createTextOutput('');

在发回完整的未更改的 paypal 消息之前,我设置了一个触发器,它会在 30 秒后向 paypal 发送消息:

var params = {
    method: "post"
  }
  var req = messge from paypal;
  var resp = UrlFetchApp.fetch("https://www.paypal.com/cgi-bin/webscr?"+req,params);

此代码与 Romain 不同,但我很好地收到了来自 Paypal 的 "VERIFIED" 答复。

所以现在我认为问题是 HTTP 200 响应发送回 paypal,第 2 步。 我所做的是,通过向应用程序脚本发送我自己的 post 请求来检查内容中的数据、header 和响应代码。结果如下:

[15-03-25 22:50:29:753 CET] code : 200

[15-03-25 22:50:29:754 CET] content :

[15-03-25 22:50:29:756 CET] hearder : ({'X-XSS-Protection':"1; mode=block", Expires:"Fri, 01 Jan 1990 00:00:00 GMT", 'Alternate-Protocol':"443:quic,p=0.5", 'Set-Cookie':"NID=67=hlLDTKuNN7fjl66UwT9e2_BV0xw_dd67lZ9R337Zm2K8RYNAMzF0FjnEt0uhE0cxCzymgsH-1ehuGOgZ7pHynjWRkM1Y6n0PxXp8RAdyPKgfr-Y4cUrBqoDZdUib9zWo;Domain=.googleusercontent.com;Path=/;Expires=Thu, 24-Sep-2015 21:50:29 GMT;HttpOnly", Server:"GSE", 'Cache-Control':"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", 'X-Content-Type-Options':"nosniff", 'X-Frame-Options':"SAMEORIGIN", 'Transfer-Encoding':"chunked", Date:"Wed, 25 Mar 2015 21:50:29 GMT", 'Access-Control-Allow-Origin':"*", P3P:"CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"", 'Content-Type':"text/plain; charset=utf-8"})

我在 Whosebug 上找到了这条关于 HTTP 响应状态 405 的消息和要做的测试:()。

header 在 dopost() 请求后用 appscript 发回似乎格式不正确。我不确定,但现在我没有其他想法。

如果有人有想法? 我认为可能会在 doPost() 的末尾发送带有特定 header 的自定义答案,但不知道该怎么做?

编辑

在 Kristoffer 发表评论后,如果您使用 createHtmlOutputFromFile(),它将 return 一个没有重定向的页面,并且在此 Paypal 中将获得 200 ok 代码。 所以在你的脚本中你可以 return :

HtmlService.createHtmlOutputFromFile('test').setSandboxMode(HtmlService.SandboxMode.IFRAME);

其中测试是 HTML 没有内容的文件。

上一个回答

终于找到解决办法了。这个问题似乎真的是因为 Paypal IPN 不遵循重定向。 在 hurl.it 上进行的测试表明,当您不遵循重定向时,POST 请求 appsscript return 一个 302 Moved Temporary 和一个 200 如果您遵循重定向。

为了解决这个问题,我的想法是创建一个简单的脚本,将 post 请求转发到我的应用程序脚本,但 return 对 paypal 的 200 ok 响应。

我用 PHP 制作了这个脚本,因为我可以很容易地托管它,而且我不是一个大开发者我想可以在 App Engine 上完成这个而无需通过免费计划。

所以如果你在这里有一个博客我使用的代码。

<?php
$url = 'https://script.google.com/macros/s/ID_OF_THE_SCRIPT/exec';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
$response = curl_exec($ch);
curl_close($ch);
?>

这在我的 Paypal 控制台上工作正常,我有一个 200 响应代码,状态已发送,我的脚本在我发回消息时收到来自 PayPal 的 VERFIFIED 时工作。

如果可以改进代码,我很感兴趣,但目前它正在按照我的意愿完成工作。

一个简单的解决方案是为此使用 HtmlService, not ContentService, to return. As noted in the comments, it is the redirect that creates the error - there is an issue 归档。 HtmlService 没有这个问题,因为所有 Paypal IPN 都需要一个 HTTP 200,所以你 return 并不重要。

解决方案: 变化

return ContentService.createTextOutput('');

return HtmlService.createHtmlOutput('').setSandboxMode(HtmlService.SandboxMode.IFRAME);

我遇到了类似的问题,但也以 302 重定向结束。如果您遇到此类问题,请确保:

a) 您遵循 Kristoffer 和 St3ph 的说明。他们确实有效。

b)(我的问题)部署网络应用程序时,选择运行应用程序作为"me",而不是 "User accessing the web app",如图所示。

如果不这样做,您将出于身份验证原因获得 302 重定向。