本文共 4895 字,大约阅读时间需要 16 分钟。
1. 先看看微信开放平台的官方开发文档:
如图:
官方的微信登录和微信支付的API,给定的参数很详细。
2. 微信支付API的文档链接:
微信登录API的文档链接:
3. http的几种请求方式
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。
Get 和Post区别:
简单说:Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求。
Get是获取信息,而不是修改信息,类似数据库查询功能一样,数据不会被修改。Get请求的参数会跟在url后进行传递,请求的数据会附在URL之后,以?分割URL和传输数据,参数之间以&相连,%XX中的XX为该符号以16进制表示的ASCII,如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密。Get传输的数据有大小限制,因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了,不同的浏览器对URL的长度的限制是不同的。
Post请求则作为http消息的实际内容发送给web服务器,数据放置在HTML Header内提交,Post没有限制提交的数据。Post比Get安全,当数据是中文或者不敏感的数据,则用get,因为使用get,参数会显示在地址,对于敏感数据和不是中文字符的数据,则用post。
从底层说:
GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
这里主要用到的是两种,微信登录用的是 get 请求方式,带上参数请求token,
而微信支付用的post 请求方式,将XML数据post给服务器。
4.具体demo:
微信登录:
1. 服务端通过客户端获取的code去向微信开发平台请求,获取token :
2. 以上demo是url所带的参数,注意:url和传输数据之间要用?分割 ,请求方式是get,最后加上自己的异步回调函数,带着token 再去授权:
3. 授权之后再去获取个人信息:
至此微信登录就完成了。因为微信平台回复的都是json字符串,很好解析,就不详细说了。
下面重点说的是:微信支付
微信支付,从下单开始:
1. 服务端向微信请求预支付订单号,再发给前端。
这里官方要的是XML数据,所以用post方式将XML数据发给微信的服务器。Erlang中封装xml的方式,最简单暴力的就是将XML数据封装成一个字符串,发过去就可以,实践证明可行的:
fun_http:async_http_request(post,{Url,[],"text/xml",Data},{?MODULE, getPrepayIdCb,{TradeId,Price}}).
如上demo 可以看到,先将需要发送的参数,拼一起成strA,再strA++"&key=rtyuiophjklyhjkyhjkjkljk"= StrSignTemp,再将这个字符串先MD5加密,再执行一次转换大写的操作,签名就生成了。这时候再将这些参数按照标签的形式<appid>"++?AppId++"</appid>" 拼一起,最后封装成一个XML数据的字符串data,再向官方的Url postdata.这时候请求就成功了。注意:Data中的每一个参数和上面生成签名的每一个同名参数得一致,签名不能错误,方式是post data.这些都正确就可以收到微信回复的XML数据,得到预支付订单号prepay_id。。
2. Erlang中xmerl的方法可以解析XML,但网上少有可以完成解析XML的demo.下面是自己解析的方法(究其原理,就是一层一层的将节点剥离出来,最后得到其中的一层的某个字段):
如上,需要定义三个record。字段可以自己命名,Body就是解析http请求回复的数据,然后先将binary文件转化成list, 再通过xmerl_scan:string(Str)方法,提取出XML的节点元素。再通过xmerl_xpath:string("/xml", XmlElt)方法,提取出XML节点下的所有数据。 再通过下面的[#xmlElement{content=Content}]=xmerl_xpath:string("/xml/prepay_id", Item)
方法,找到prepay_id 这个标签的节点数据,和#xmlElement 匹配,其中的content就是我们要的,而content去和xmlText 记录匹配,其中的value字段就是我们要的prepay_id的值。其他字段同理可以获得。
注意:只要理解了erlang的匹配原理,record对应的字段都是自己命名,自己可以任意取出来的。
如客户端支付成功后,服务端去验证是否成功,需要获取的字段trade_state的值是否为SUCCESS
转自:Zmyths 链接地址 https://blog.csdn.net/zcyzsy/article/details/70256149