【问题标题】:Paypal IPN and Golang integration on GAEGAE 上的 Paypal IPN 和 Golang 集成
【发布时间】:2014-01-14 06:23:01
【问题描述】:

我正在编写一个监听器来处理 Paypal IPN 消息和响应。

根据 Paypal IPN 要求,侦听器必须以相同的顺序将从 Paypal 接收到的值发回,并在值列表的前面插入一个新参数“cmd=_notify-validate”。

您的侦听器 HTTP 将完整的、未更改的消息发送回 PayPal。 注意:此消息必须包含与来自 PayPal 的原始 IPN 相同的字段,以相同的顺序,都以 cmd=_notify-validate 开头。此外,此消息必须使用与原始消息相同的编码。

但是,Go 的 url.Values 变量是在 map 数据结构中实现的,每次迭代时不保证值的顺序相同。

...在使用范围循环对地图进行迭代时,未指定迭代顺序,并且不保证从一次迭代到下一次迭代顺序相同”

并且当调用url.Values编码方法时,会按键排序

Encode 将值编码为按键排序的“URL 编码”形式(“bar=baz&foo=quux”)。

监听器在 GAE 上运行,因此我使用“appengine/urlfetch”的 PostForm 函数,该函数将 url.Values 作为第二个参数

c := appengine.NewContext(r)
client := urlfetch.Client(c)
resp, err := client.PostForm("https://www.sandbox.paypal.com/cgi-bin/webscr", r.Form)

由于 url.Values 是一个 map,所以不保证 map 中值的顺序是有序的。如何通过 GAE urlfetch 服务以从 Paypal IPN 收到的相同顺序将参数值传递回 Paypal?

【问题讨论】:

    标签: google-app-engine map paypal go


    【解决方案1】:

    使用Post 而不是PostForm。您可能可以使用请求中的正文:

    var buf bytes.Buffer
    buf.WriteString("cmd=_notify-validate&")
    io.Copy(&buf, r.Body)
    
    client.Post("http://localhost", "application/x-www-form-urlencoded", &buf)
    

    【讨论】:

    • 这可行,但在 io.Copy(&buf, r.Body) 行之后,我尝试运行 r.ParseForm()。它没有错误,因为我有它的错误处理程序。但是,我在 r.Form 中没有任何价值。好像 io.Copy 对 r.Body 做了什么?而且我不能在 io.Copy(&buf, r.Body) 之前运行 parseForm() 因为它以某种方式改变了身体。你有什么想法吗?
    • 或者我是否必须按值复制 r.Body 才能单独运行 io.Copy(&buf, r.Body)?
    • 是的,抱歉,使用io.Copy 消耗身体将使其无法用于ParseForm。 (反之亦然)您可以将 Body 替换为 TeeReader: golang.org/pkg/io/#TeeReader。因此,不要使用io.Copy,而是使用r.Body = io.TeeReader(r.Body, &buf),然后调用:r.ParseForm()
    • 天哪。现在我在调用client.Post(.., .., tt) 后遇到http: invalid Read on closed Body。调用 io.TeeReader() 后如何保持正文打开? (我使用了一个新变量tt := io.TeeReader(r.Body, &buf),因为 TeeReader 返回的 Reader 没有实现更接近)
    • 抱歉没有注意到。您必须创建自己的支持关闭的TeeReader。这实际上并不难,因为TeeReader 的代码很简单:golang.org/src/pkg/io/io.go?s=15125:15166#L465。这是一个未经测试的示例:play.golang.org/p/-0qsJrkw_x。然后你会使用r.Body = TeeReadCloser(r.Body, &buf)
    猜你喜欢
    • 2011-09-01
    • 2012-04-08
    • 2017-12-26
    • 2014-07-31
    • 2011-08-19
    • 2013-02-06
    • 2018-04-12
    • 2016-06-08
    • 2013-07-28
    相关资源
    最近更新 更多