Python网络连接QQ小流程-登入+支付完备业务流程两栖作战(环境构筑+源代码)插图

如下表所示如是说两个可运转的QQ小销售业务流程发送信息+缴付的demo。碰触了小销售业务流程固定式讲义的,总之都晓得他们必定有他们的前台应用服务工程项目器,来处置他们他们的销售业务方法论、允诺QQ服务工程项目顺利完成很大的机能。在此,他们的前台选用java自然环境,责任编辑将具体来说如是说自然环境构筑的操作过程,随即如是说发送信息+缴付的销售业务流程及标识符。

一、前台web服务工程项目自然环境构筑

1.加装jdk、tomcat,ICP登记的搜索引擎预备。

Linux加装jdk: 历经icp登记的搜索引擎,请另行预备。

2.实用性https

虽然小销售业务流程允诺url要是https,故要实用性全力支持https允诺。生前选用的是在阿里云买回的搜索引擎,故选用的合格证书也是阿里云聚合的ssl合格证书,可参照如下表所示三篇昌明进行实用性。总之,你也能透过其它形式聚合合格证书,更或是透过nginx作逆向全权到你的服务工程项目器。

与此同时,亦须将您的小销售业务流程搜索引擎存取在小销售业务流程后端。发送信息小销售业务流程前台,【增设】-【合作开发增设】-【服务工程项目器搜索引擎】

3.布署web服务工程项目

如上三步顺利完成后,请亦须证实透过你的搜索引擎()能展现tomcat的默认页后,已经开始布署他们的web服务工程项目。在此,单纯蛮横的在webapps下创建小销售业务流程的根产品目录,我重新命名为wechatserver,在此产品目录下,创建WEB-INFO,上面的产品目录内部结构如下表所示:

classes放置他们写的类的classes文档,lib放置他们工程项目倚赖的jar包,logs用作放置他们的笔记输入,web.xml是他们这个工程项目的实用性。demo中,他们多于两个servlet转交小销售业务流程后端允诺,web.xml中增加实用性如下表所示:

WechatServletcom.icbc.servlet.WechatServletWechatServlet/servlet/WechatServlet

4. log4j 应用

在合作开发调试中,他们免不了需要透过打印笔记进行调试,因此在此增加了笔记的使用。web.xml中增加实用性:

log4jConfigLocationclasses/log4j.properties

在classes增加文档,log4j.properties,内容如下表所示:

log4j.rootLogger = INFO,toConsole,D,Elog4j.appender.toConsole=org.apache.log4j.ConsoleAppenderlog4j.appender.toConsole.Target=System.outlog4j.appender.toConsole.layout=org.apache.log4j.PatternLayoutlog4j.appender.toConsole.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%nlog4j.appender.D = org.apache.log4j.DailyRollingFileAppenderlog4j.appender.D.file = 你的产品目录/common.loglog4j.appender.D.Append =truelog4j.appender.D.Threshold = infolog4j.appender.D.layout = org.apache.log4j.PatternLayoutlog4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] – [ %p ] %m%nlog4j.appender.D.DatePattern=.yyyy-MM-dd.loglog4j.appender.E = org.apache.log4j.DailyRollingFileAppenderlog4j.appender.E.file = 你的产品目录/error.loglog4j.appender.E.Append =truelog4j.appender.E.Threshold = ERRORlog4j.appender.E.layout = org.apache.log4j.PatternLayoutlog4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] – [ %p ] %m%nlog4j.appender.D.DatePattern=.yyyy-MM-dd.log

二、QQ小销售业务流程发送信息+缴付

1. 小销售业务流程后端产品目录预备

基于QQ小销售业务流程工具聚合的默认hello world销售业务流程,pages下先创建产品目录order,随即在order产品目录聚合两个新的page,重新命名为order,内部结构如下表所示图:

在index中增加按钮,进入order。index.wxml

url=“/pages/order/order”>进入商城

order.xml中描述商品信息,增加缴付按钮 order.js 缴付事件处置。

2. 发送信息+缴付 code

销售业务流程大概分为几步:1)发送信息,获取code(两个code只能用一次) 2)透过code获取openid(透过允诺服务工程项目器,由服务工程项目器允诺QQ获取并返回小销售业务流程)。QQ发送信息+获取openid接口

3)小销售业务流程允诺服务工程项目器进行预下单,上送商品详情、金额、openid。4)服务工程项目器端转交允诺,根据允诺订单数据、聚合第三方订单号,调用QQ的统一下单接口。5)服务工程项目器收到预下单信息后,签名并组装缴付数据,返回给小销售业务流程。所需数据见:小销售业务流程缴付接口 6)小销售业务流程后端发起缴付,并缴付顺利完成 7)服务工程项目器收到回调。

2.1 发送信息,获取code

onLoad:function(options) {// 发送信息wx.login({success:function(res) {// 发送 res.code 到前台换取 openId, sessionKey, unionIdvar that = this;if(res.code) {console.log(获取用户发送信息态success!+ res.code)app.globalData.code = res.code}else{console.log(获取用户发送信息态失败!+ res.errMsg)}}})},

2.2 透过code 获取openid(后端)

getOpenId:function(that, code){console.log(code);letoperFlag =“getOpenid”;console.log(operFlag);wx.request({url:data: {code:code,operFlag:operFlag},header: {content-type:application/json},success:function(res) {console.log(res);var openid = res.data.openid;console.log(openid);that.paypay(that, openid); //预下单并缴付},fail:function(res) {console.log(res.data.errmsg);console.log(res.data.errcode);},complete:function(res){}})},

2.3 服务工程项目器端servlet(复写HttpServlet的doGet doPost函数)doPost的标识符片段:

paypay:function(that, openid) {letoperFlag =pay;wx.request({url:,data: {openid: openid,operFlag: operFlag},header: {content-type:application/json},success:function(res) {console.log(res);wx.requestPayment({timeStamp: res.data.timeStamp,nonceStr: res.data.nonceStr,package: res.data.package,signType:MD5,paySign: res.data.sign,success:function(res) {if(res.errMsg ==“requestPayment:ok”) {wx.showToast({title:缴付成功})}},fail:function(res) {}})},fail:function(res) {console.log(res.data.errmsg);console.log(res.data.errcode);},complete:function(res) {}})},

2.4 后端上送订单信息、openid允诺预下单(在此,为方便,订单信息直接写死在服务工程项目器端了),若成功,则根据服务工程项目器端返回数据发起缴付。

paypay:function(that, openid) {letoperFlag =pay;wx.request({url:data: {openid: openid,operFlag: operFlag},header: {content-type:application/json},success:function(res) {console.log(res);wx.requestPayment({timeStamp: res.data.timeStamp,nonceStr: res.data.nonceStr,package: res.data.package,signType:MD5,paySign: res.data.sign,success:function(res) {if(res.errMsg ==“requestPayment:ok”) {wx.showToast({title:缴付成功})}},fail:function(res) {}})},fail:function(res) {console.log(res.data.errmsg);console.log(res.data.errcode);},complete:function(res) {}})},

2.5 服务工程项目器端预下单,2.6并签名返回缴付允诺数据

if(“pay”.equals(operFlag)){String openid = request.getParameter(“openid”);logger.info(“openid = “+ openid);String url =;String reqStr = getReqStr(openid); //组装预下单的允诺数据logger.info(“reqStr=”+ reqStr);results = sendPost(url,reqStr);//发送post数据到QQ预下单logger.info(“prepay from weixin: \n “+ results);Map return_data = null;try {return_data = WXPayUtil.xmlToMap(results);//QQ的两个工具类} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();logger.error(e.getMessage());}String return_code = return_data.get(“return_code”);logger.info(“return_code=”+ return_code);if(“SUCCESS”.equals(return_code)){String prepay_id = return_data.get(“prepay_id”);results = conPayParam(prepay_id); //组装返回数据}else{results =“{\”return_code\”:\”fail\”}”;}}

附函数

//组装预下单的允诺数据public static String getReqStr(String openid){Map data = new HashMap();String out_trade_no = setTradeNo();////data.put(“appid”, appid);data.put(“mch_id”,mer_id);data.put(“nonce_str”, WXPayUtil.generateUUID());data.put(“sign_type”,“MD5”);data.put(“body”,“spy test”);data.put(“out_trade_no”, out_trade_no);data.put(“device_info”,“”);data.put(“fee_type”,“CNY”);data.put(“total_fee”,“1”);//1分钱data.put(“spbill_create_ip”,“123.12.12.123”);data.put(“notify_url”,“”);data.put(“trade_type”,“JSAPI”);data.put(“product_id”,“12”);data.put(“openid”, openid);try {String sign = WXPayUtil.generateSignature(data, merKey, SignType.MD5);data.put(“sign”, sign);} catch (Exception e) {e.printStackTrace();logger.error(“sign error”);}String reqBody = null;try {reqBody = WXPayUtil.mapToXml(data);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}returnreqBody;}//保证唯一public static StringsetTradeNo(){String orderid =“20211909105011”+ getRandom(6);logger.info(“orderid = “+ orderid);returnorderid;}//组装返回客户端的允诺数据public static String conPayParam(String prepayid){logger.info(“根据当前的prepayid构造返回参数= “+ prepayid);String results =“”;Map map = new HashMap();map.put(“appId”, appid);LocalDateTime time = LocalDateTime.now();map.put(“timeStamp”, WXPayUtil.getCurrentTimestamp()+“”);map.put(“nonceStr”, WXPayUtil.generateUUID() );map.put(“package”,“prepay_id=”+ prepayid);map.put(“signType”,“MD5”);String sign;try {sign = WXPayUtil.generateSignature(map, merKey, SignType.MD5);map.put(“sign”, sign);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();logger.error(e.getMessage());}returnJSON.toJSONString(map);}

2.6 服务工程项目器端返回数据到QQ小销售业务流程客户端后,发起QQ缴付,标识符在2.3章节已附。2.8 服务工程项目器端收到QQ的缴付成功通知(省略)

三、两栖作战中遇到的问题

1.预下单和缴付允诺中,签名的密钥使用的是商户密钥,但是用code获取openid是使用小销售业务流程对应的secret key,这个能在小销售业务流程的前台看到。

2.QQ小销售业务流程后端发起post允诺到服务工程项目器端时,服务工程项目器端收不到允诺参数。原因是:QQAPI接口wx.request中:a) 对于 GET 方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)

b) 对于 POST 方法且 header[‘content-type’] 为 application/json 的数据,会对数据进行 JSON 序列化

c) 对于 POST 方法且 header[‘content-type’] 为 application/x-www-form-urlencoded 的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)

所以,如果post允诺,为省去服务工程项目器端反序列化的操作时,可使用header[‘content-type’] 为 application/x-www-form-urlencoded 的数据。

3.如果布署了servlet后,tomcat重启后,需要等几分钟才能生效(原因是我的机器内存比较小,而tomcat又很占用内存资源),待熟悉tomcat 调优。

举报/反馈

作者 nasiapp

在线客服
官方客服
我们将24小时内回复。
12:01
您好,有任何疑问请与我们联系!

选择聊天工具: