②准备好11个模块JSAPI缴付形式

1 实用性QQ网络平台

①实用性QQ社会公众网络平台

登入QQ社会公众网络平台=》社会公众号增设=》机能增设=》页面许可搜索引擎

程序语言同时实现QQ缴付机能(附源代码)插图
程序语言同时实现QQ缴付机能(附源代码)插图1

②实用性QQ店家网络平台

程序语言同时实现QQ缴付机能(附源代码)插图2

①先去非官方浏览SDK,并导进工程项目中

程序语言同时实现QQ缴付机能(附源代码)插图3

2 前台标识符的同时实现

JSAPI非官方文件格式:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

①先去非官方浏览SDK,并导进工程项目中

地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

程序语言同时实现QQ缴付机能(附源代码)插图4

②准备好11个模块

appid:店家网络平台ID。在QQ的网络平台上有body:商品描述。mch_id:商户ID。在QQ的网络平台上有nonce_str:随机字符串,UUID就好了。openid:用户标识。因为这边是用户已经登入成功了。所以在session中就能拿到。out_trade_no:商户订单号spbill_create_ip:终端IP。这个可以从请求头中拿到total_fee:缴付金额。单位是分。trade_type:交易类型。这里我填JSAPInotify_url:通知地址。就是用户缴付成功之后,QQ访问你的哪个接口,跟你传递缴付成功的相关信息。

sign:签名。这个签名它是由上面的10个模块计算得出的。

③源标识符sendPay类:

import java.io.IOException;import java.io.InputStream;import java.math.BigDecimal;import java.net.URLEncoder;import java.util.HashMap;import java.util.Map;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.http.auth.AUTH;import org.hamcrest.core.Is;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import com.jc.util.wxPay.WXPayUtil;import com.sun.xml.internal.fastinfoset.Encoder;import controller.AuthUtil;import net.sf.json.JSONObject;@Controller@RequestMapping(“/pay”)public class sendPay { /** * @Description QQ浏览器内QQ缴付/社会公众号缴付(JSAPI) * @param request * @param code * @returnMap */ @RequestMapping(value =“orders”) public @ResponseBody Map orders(HttpServletRequest request, HttpServletResponse response) { try { String openId =“用户的openid”; // 拼接统一下单地址模块 Map paraMap = new HashMap(); // 获取请求ip地址 String ip = request.getHeader(“x-forwarded-for”);if(ip == null || ip.length() ==0||“unknown”.equalsIgnoreCase(ip)) { ip = request.getHeader(“Proxy-Client-IP”); }if(ip == null || ip.length() ==0||“unknown”.equalsIgnoreCase(ip)) { ip = request.getHeader(“WL-Proxy-Client-IP”); }if(ip == null || ip.length() ==0||“unknown”.equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); }if(ip.indexOf(“,”) !=-1) { String[] ips = ip.split(“,”); ip = ips[0].trim(); } paraMap.put(“appid”, AuthUtil.APPID); // 店家网络平台ID paraMap.put(“body”,“纯情小店铺-薯条”); // 店家名称-销售商品类目、String(128) paraMap.put(“mch_id”, AuthUtil.MCHID); // 商户ID paraMap.put(“nonce_str”, WXPayUtil.generateNonceStr()); // UUID paraMap.put(“openid”, openId); paraMap.put(“out_trade_no”, UUID.randomUUID().toString().replaceAll(“-“,“”));// 订单号,每次都不同 paraMap.put(“spbill_create_ip”, ip); paraMap.put(“total_fee”,“1”); // 缴付金额,单位分 paraMap.put(“trade_type”,“JSAPI”); // 缴付类型 paraMap.put(“notify_url”,“用户缴付完成后,你想QQ调你的哪个接口”);// 此路径是QQ服务器调用缴付结果通知路径随意写 String sign = WXPayUtil.generateSignature(paraMap, AuthUtil.PATERNERKEY); paraMap.put(“sign”, sign); String xml = WXPayUtil.mapToXml(paraMap);// 将所有模块(map)转xml格式 // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder String unifiedorder_url =“https://api.mch.weixin.qq.com/pay/unifiedorder”; System.out.println(“xml为:”+ xml); // String xmlStr = HttpRequest.sendPost(unifiedorder_url, // xml);//发送post请求“统一下单接口”返回预缴付id:prepay_id String xmlStr = HttpRequest.httpsRequest(unifiedorder_url,“POST”, xml); System.out.println(“xmlStr为:”+ xmlStr); // 以下内容是返回前端页面的json数据 String prepay_id =“”;// 预缴付idif(xmlStr.indexOf(“SUCCESS”) !=-1) { Map map = WXPayUtil.xmlToMap(xmlStr); prepay_id = (String) map.get(“prepay_id”); } Map payMap = new HashMap(); payMap.put(“appId”, AuthUtil.APPID); payMap.put(“timeStamp”, WXPayUtil.getCurrentTimestamp() +“”); payMap.put(“nonceStr”, WXPayUtil.generateNonceStr()); payMap.put(“signType”,“MD5”); payMap.put(“package”,“prepay_id=”+ prepay_id); String paySign = WXPayUtil.generateSignature(payMap, AuthUtil.PATERNERKEY); payMap.put(“paySign”, paySign); //将这个6个模块传给前端returnpayMap; } catch (Exception e) { e.printStackTrace(); }returnnull; } /** * @Title: callBack * @Description: 缴付完成的回调函数 * @param: * @return: */ @RequestMapping(“/notify”) public String callBack(HttpServletRequest request, HttpServletResponse response) { // System.out.println(“QQ缴付成功,QQ发送的callback信息,请注意修改订单信息”); InputStream is = null; try { is = request.getInputStream();// 获取请求的流信息(这里是QQ发的xml格式所有只能使用流来读) String xml = WXPayUtil.InputStream2String(is); Map notifyMap = WXPayUtil.xmlToMap(xml);// 将QQ发的xml转map System.out.println(“QQ返回给回调函数的信息为:”+xml);if(notifyMap.get(“result_code”).equals(“SUCCESS”)) { String ordersSn = notifyMap.get(“out_trade_no”);// 商户订单号 String amountpaid = notifyMap.get(“total_fee”);// 实际缴付的订单金额:单位 分 BigDecimal amountPay = (new BigDecimal(amountpaid).divide(new BigDecimal(“100”))).setScale(2);// 将分转换成元-实际缴付金额:元 /* * 以下是自己的业务处理——仅做参考 更新order对应字段/已缴付金额/状态码 */ System.out.println(“===notify===回调方法已经被调!!!”); } // 告诉QQ服务器收到信息了,不要在调用回调action了========这里很重要回复QQ服务器信息用流发送一个xml即可 response.getWriter().write(“”); } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; }}

HttpRequest类:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.URL;import java.net.URLConnection;import java.util.List;import java.util.Map;import javax.net.ssl.HttpsURLConnection;public class HttpRequest { /** * 向指定URL发送GET方法的请求 * * @param url * 发送请求的URL * @param param * 请求模块,请求模块应该是 name1=value1&name2=value2 的形式。 * @returnURL 所代表远程资源的响应结果 */ public static String sendGet(String url, String param) { String result =“”; BufferedReaderin= null; try { String urlNameString = url +“?”+ param; System.out.println(urlNameString); URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 增设通用的请求属性 connection.setRequestProperty(“accept”,“*/*”); connection.setRequestProperty(“connection”,“Keep-Alive”); connection.setRequestProperty(“user-agent”,“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)”); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Mapfor(String key : map.keySet()) { System.out.println(key +“—>”+ map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应in= new BufferedReader(new InputStreamReader(connection.getInputStream())); String line;while((line =in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println(“发送GET请求出现异常!”+ e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try {if(in!= null) {in.close(); } } catch (Exception e2) { e2.printStackTrace(); } }returnresult; } /** * 向指定 URL 发送POST方法的请求 * * @param url * 发送请求的 URL * @param param * 请求模块,请求模块应该是 name1=value1&name2=value2 的形式。 * @return所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReaderin= null; String result =“”; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 增设通用的请求属性 conn.setRequestProperty(“accept”,“*/*”); conn.setRequestProperty(“connection”,“Keep-Alive”); conn.setRequestProperty(“user-agent”,“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)”); // 发送POST请求必须增设如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求模块 out.print(param); //flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应in= new BufferedReader(new InputStreamReader(conn.getInputStream(),“UTF-8”)); String line;while((line =in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println(“发送 POST 请求出现异常!”+ e); e.printStackTrace(); } // 使用finally块来关闭输出流、输入流 finally { try {if(out != null) { out.close(); }if(in!= null) {in.close(); } } catch (IOException ex) { ex.printStackTrace(); } }returnresult; } /** * post请求并得到返回结果 * * @param requestUrl * @param requestMethod * @paramoutput* @return*/ public static String httpsRequest(String requestUrl, String requestMethod, Stringoutput) { try { URL url = new URL(requestUrl); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setRequestMethod(requestMethod);if(null !=output) { OutputStream outputStream = connection.getOutputStream(); outputStream.write(output.getBytes(“UTF-8”)); outputStream.close(); } // 从输入流读取返回内容 InputStream inputStream = connection.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream,“utf-8”); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer();while((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; connection.disconnect();returnbuffer.toString(); } catch (Exception ex) { ex.printStackTrace(); }return“”; }}

AuthUtil类

importjava.io.IOException;importorg.apache.http.HttpEntity;importorg.apache.http.HttpResponse;importorg.apache.http.client.ClientProtocolException;importorg.apache.http.client.methods.HttpGet;importorg.apache.http.impl.client.DefaultHttpClient;importorg.apache.http.util.EntityUtils;importnet.sf.json.JSONObject;publicclassAuthUtil{publicstaticfinalString APPID =“网络平台ID”;publicstaticfinalString APPSECRET =“网络平台密钥”;publicstaticfinalString MCHID =“店家ID”;publicstaticfinalString PATERNERKEY =“店家密钥”;publicstaticJSONObjectdoGetJson(String url)throwsClientProtocolException, IOException{ JSONObject jsonObject =null;// 首先初始化HttpClient对象 DefaultHttpClient client = new DefaultHttpClient(); // 通过get形式进行提交 HttpGet httpGet = new HttpGet(url); // 通过HTTPclient的execute方法进行发送请求 HttpResponse response = client.execute(httpGet); // 从response里面拿自己想要的结果 HttpEntity entity = response.getEntity(); if (entity != null) { String result = EntityUtils.toString(entity, “UTF-8”); jsonObject = jsonObject.fromObject(result); } // 把链接释放掉 httpGet.releaseConnection(); return jsonObject; }}

2.3 前端的同时实现

这是只用一个jsp页面来做测试

<%@ page language=“java”contentType=“text/html; charset=UTF-8”pageEncoding=“UTF-8”%>”-//W3C//DTD HTML 4.01 Transitional//EN”“http://www.w3.org/TR/html4/loose.dtd”> “text/html; charset=UTF-8”>type=“text/javascript”src=“./js/jquery-1.11.0.min.js”>QQ缴付JSP <inputtype=“button”value=“进行QQ缴付”id=“payId”> type=“text/javascript”> $(function(){ var appId,timeStamp,nonceStr,package,signType,paySign; $(“payId”).click(function(){ pay(); }); //去前台拿六个模块functionpay(){ var url =“http://localhost:8082/WeChat/pay/orders”; $.get(url,function(result){ appId = result.appId; timeStamp = result.timeStamp; nonceStr = result.nonceStr;package= result.package; signType = result.signType; paySign = result.paySign;if(typeof WeixinJSBridge ==“undefined”) {if(document.addEventListener) { document.addEventListener(WeixinJSBridgeReady, onBridgeReady,false); }elseif(document.attachEvent) { document.attachEvent(WeixinJSBridgeReady, onBridgeReady); document.attachEvent(onWeixinJSBridgeReady, onBridgeReady); } alert(“请在QQ上进行缴付操作!”); onBridgeReady(); }else{ onBridgeReady(); } }); } //去QQ那边发起缴付请求functiononBridgeReady(){ alert(“appId:”+appId+” “+“timeStamp:”+timeStamp+” “+“nonceStr:”+nonceStr+” “+“package:”+package+” “+“signType:”+signType+” “+“paySign:”+paySign+” “); WeixinJSBridge.invoke(getBrandWCPayRequest, {“appId”:appId, //社会公众号名称,由商户传入“timeStamp”:timeStamp, //时间戳,自1970年以来的秒数“nonceStr”:nonceStr, //随机串“package”:package,“signType”:signType, //QQ签名形式:“paySign”:paySign //QQ签名 },function(res){if(res.err_msg ==“get_brand_wcpay_request:ok”) { //alert(缴付成功); console.log(“缴付成功”); //缴付成功后跳转的页面 }elseif(res.err_msg ==“get_brand_wcpay_request:cancel”){ alert(缴付取消); }elseif(res.err_msg ==“get_brand_wcpay_request:fail”){ alert(缴付失败); alert(JSON.stringify(res)); WeixinJSBridge.call(closeWindow); } //使用以上形式判断前端返回,QQ团队郑重提示:res.err_msg将在用户缴付成功后返回ok,但并不保证它绝对可靠。 }); } })

三,总结

虽然次看非官方文件格式很乱,信息量很多,但仔细总结一下,其实下面这点流程而已。

再记录点,以防有用:

url urlencode

publicstaticStringinputStream2String(InputStream inStream, String encoding){ String result =null; ByteArrayOutputStream outStream =null;try{if(inStream !=null){ outStream =newByteArrayOutputStream();byte[] tempBytes =newbyte[1024];intcount =0;while((count = inStream.read(tempBytes)) !=-1){ outStream.write(tempBytes,0, count); } tempBytes =null; outStream.flush(); result =newString(outStream.toByteArray(), encoding); outStream.close(); } }catch(Exception e) { result =null; }returnresult; }

转载:

https://blog.csdn.net/daotiao0199/article/details/85284038

https://blog.csdn.net/javaYouCome/article/details/79473743

程序语言同时实现QQ缴付机能(附源代码)插图5

作者 nasiapp

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

选择聊天工具: