Paypal IPN和Golang在GAE上的集成

时间:2013-12-26 15:51:41

标签: google-app-engine map paypal go

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

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

  

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

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

  
    

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

  

当调用url.Values编码方法时,它将按键排序

  
    

将值编码为按URL排序的“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是一张地图,因此不保证地图中值的顺序是有序的。如何以Paypal IPN收到的相同顺序将参数值传回Paypal并使用GAE urlfetch服务?

1 个答案:

答案 0 :(得分:4)

使用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)