700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 微信小程序+java后台实现支付(java操作)

微信小程序+java后台实现支付(java操作)

时间:2019-05-04 07:21:48

相关推荐

微信小程序+java后台实现支付(java操作)

支付,在微信小程序上面称为当一个用户使用该小程序,当进入到支付环节,我们需要调用微信支付接口过程,进行一系列的操作,并记录下来。

微信小程序与java接口实现支付操作,大致思路如下:

1.微信小程序调用Java后台方法获取参数,

2.java 后台设置参数等并且传递参数返回给微信小程序,

3.微信小程序支付成功,

4.调用设置的回调地址(订单存入数据库),

5.最后调用微信小程序的success方法。

对应代码如下:

1.微信小程序调用支付

//得到openid(微信用户唯一的openid)//该步骤忽略。。。//得到价钱(自定义)String price = httpRequest.getParameter("price");int fee = 0;if (null != price) {fee = Integer.parseInt(price.toString());}//得到商品的ID(自定义)String goodsid=httpRequest.getParameter("goodsid");//订单标题(自定义)String title = httpRequest.getParameter("title");//时间戳String times = System.currentTimeMillis() + "";//订单编号(自定义 这里以时间戳+随机数)Random random = new Random();String did = times+random.nextInt(1000);SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();packageParams.put("appid",MapUtils.getString(configProperties, "appId"));//微信小程序IDpackageParams.put("mch_id", MapUtils.getString(configProperties, "mch_id"));//商户IDpackageParams.put("nonce_str", times);//随机字符串(32位以内) 这里使用时间戳packageParams.put("body", title);//支付主体名称 自定义packageParams.put("out_trade_no", did+goodsid);//编号 自定义以随机数+商品IDpackageParams.put("total_fee", PayUtil.getMoney(price));//价格 自定义//packageParams.put("spbill_create_ip", remoteAddr);packageParams.put("notify_url", "https://xxx.xx.xx.xx/xxxxx/buy.do");//支付返回地址要外网访问的到, localhost不行,调用下面buy方法。(订单存入数据库)packageParams.put("trade_type", "JSAPI");//这个api有,固定的packageParams.put("openid", openid);//用户的openid 可以要 可以不要//获取sign(第一次签名)String sign = PayUtil.createSign("UTF-8", packageParams, MapUtils.getString(configProperties, "mah_password"));//最后这个是自己在微信商户设置的32位密钥/*String mapStr = PayUtil.createLinkString(packageParams);String key = MapUtils.getString(configProperties, "mah_password");//MD5生成运算签名String sign = PayUtil.sign(mapStr,key,"utf-8").toUpperCase();*/packageParams.put("sign", sign);System.out.println(sign);//转成XMLString requestXML = PayUtil.getRequestXml(packageParams);System.out.println(requestXML);//得到含有prepay_id的XMLString resXml = HttpUtils.postData("https://api.mch./pay/unifiedorder", requestXML);System.out.println(resXml);//解析XML存入MapMap map2 = null;try {map2 = XmlUtil.doXMLParse(resXml);} catch (Exception e) {e.printStackTrace();}System.out.println(map2);String return_code = (String) map2.get("return_code");//得到prepay_id 进行二次签名SortedMap<Object, Object> packageP = new TreeMap<Object, Object>();try{if(return_code.equals("SUCCESS")){//获取数据//List<PayInfo> payInfoList = payService.selectPayInfoByOpenId(openid);//如果等于空,说明为第一次支付/*if(CollectionUtils.isEmpty(payInfoList)){PayInfo payInfo = new PayInfo();payInfo.setPayId(did+goodsid);//设置openidpayInfo.setOpenId(openid);//设置金额payInfo.setAmount(fee);//设置说明payInfo.setTitle(title);//设置支付状态payInfo.setPayStatus("0");//插入数据int count = payService.insertPayInfo(payInfo);//判断if(count==1){log.info("新增支付信息成功");}}else{//判断是否为第一条if(payInfoList.size() == 1){PayInfo payInfo = payInfoList.get(0);//更新该条的金额payInfo.setAmount(fee+payInfo.getAmount());//更新数据int count = payService.updateByPayInfo(payInfo);//判断if (count==1){log.info("修改支付信息成功");}}}*/PayInfo payInfo = new PayInfo();payInfo.setPayId(did+goodsid);//设置openidpayInfo.setOpenId(openid);//设置金额payInfo.setAmount(fee);//设置说明payInfo.setTitle(title);//设置支付状态payInfo.setPayStatus("0");//插入数据int count = payService.insertPayInfo(payInfo);//判断if(count==1){log.info("新增支付信息成功");}String prepay_id = (String) map2.get("prepay_id");//packageP = new TreeMap<Object, Object>();packageP.put("appId", MapUtils.getString(configProperties, "appId"));//!!!注意,这里是appId,上面是appidpackageP.put("nonceStr", times);//时间戳packageP.put("package", "prepay_id=" + prepay_id);//必须把package写成 "prepay_id="+prepay_id这种形式packageP.put("signType", "MD5");//paySign加密packageP.put("timeStamp", (System.currentTimeMillis() / 1000) + "");//得到paySign 用于请求微信/*String payStr = PayUtil.createLinkString(packageP);String paySign = PayUtil.sign(payStr,key,"utf-8").toUpperCase();*/String paySign = PayUtil.createSign("UTF-8", packageP, MapUtils.getString(configProperties, "mah_password"));packageP.put("paySign", paySign);packageP.put("success", true);}else{packageP.put("success",false);}}catch (Exception e){e.printStackTrace();log.info("接口异常");}//将package 返回给小程序return packageP;

2.微信小程序支付成功后的回调(notify_url 写的地址)

log.info("进入buy方法");BufferedReader br = new BufferedReader(new InputStreamReader(httpRequest.getInputStream()));String line = null;StringBuilder sb = new StringBuilder();while((line = br.readLine()) != null){sb.append(line);}br.close();//sb为微信返回的xmlString notityXml = sb.toString();String resXml = "";Map map = XmlUtil.doXMLParse(notityXml);System.out.println("map = " + map);String returnCode = (String) map.get("return_code");try{if("SUCCESS".equals(returnCode)){ //判断是否处理过//进行签名验证,看是否是从微信发送过来的,防止资金被盗SortedMap stringStringMap = PayUtil.paraFilter(map);String signMy = PayUtil.createSign("utf-8", stringStringMap, MapUtils.getString(configProperties, "mah_password"));System.out.println("signMy = " + signMy);System.out.println("flag = " + map.get("sign"));if(signMy.equals(map.get("sign"))){String out_trade_no=(String) map.get("out_trade_no");/** 存入数据库的逻辑*/resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";}else {resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";}BufferedOutputStream out = new BufferedOutputStream(httpResponse.getOutputStream());out.write(resXml.getBytes()); //告诉微信服务器,我收到了,不要再回调action方法了out.flush();out.close();}}catch (Exception e){e.printStackTrace();}

PayUtil工具类:

/*** 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。* @return boolean*/public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = packageParams.entrySet();Iterator it = es.iterator();while(it.hasNext()) {Map.Entry entry = (Map.Entry)it.next();String k = (String)entry.getKey();String v = (String)entry.getValue();if(!"sign".equals(k) && null != v && !"".equals(v)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);//算出摘要String mysign = MD5.MD5Encode(sb.toString(), characterEncoding).toLowerCase();String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();//System.out.println(tenpaySign + " " + mysign);return tenpaySign.equals(mysign);}/*** @author* @Description:sign签名* @param characterEncoding* 编码格式* 请求参数* @return*/public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {StringBuffer sb = new StringBuffer();Set es = packageParams.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = entry.getKey().toString();String v = entry.getValue().toString();if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {sb.append(k + "=" + v + "&");}}sb.append("key=" + API_KEY);String sign = MD5.MD5Encode(sb.toString(), characterEncoding).toUpperCase();return sign;}/*** 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串* @param params 需要排序并参与字符拼接的参数组* @return 拼接后字符串*/public static String createLinkString(Map<Object, Object> params) {List<String> keys = new ArrayList<String>();Collections.sort(keys);String prestr = "";for (int i = 0; i < keys.size(); i++) {String key = keys.get(i);Object value = params.get(key);if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符prestr = prestr + key + "=" + value;} else {prestr = prestr + key + "=" + value + "&";}}return prestr;}/*** @author* @Description:将请求参数转换为xml格式的string* @param parameters* 请求参数* @return*/public static String getRequestXml(SortedMap<Object, Object> parameters) {StringBuffer sb = new StringBuffer();sb.append("<xml>");Set es = parameters.entrySet();Iterator it = es.iterator();while (it.hasNext()) {Map.Entry entry = (Map.Entry) it.next();String k = entry.getKey().toString();String v = entry.getValue().toString();if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {sb.append("<" + k + ">" + v + "</" + k + ">");} else {sb.append("<" + k + ">" + v + "</" + k + ">");}}sb.append("</xml>");return sb.toString();}/*** 验证签名,判断是否是从微信发过来* 验证方法:接收微信服务器回调我们url的时候传递的xml中的参数 然后再次加密,看是否与传递过来的sign签名相同* @param map* @return*/public static boolean verifyWeixinNotify(Map<Object, Object> map,String key) {//根据微信服务端传来的各项参数 进行再一次加密后 与传过来的 sign 签名对比String mapStr = createLinkString(map);String signOwn = PayUtil.sign(mapStr, key, "utf-8").toUpperCase(); //根据微信端参数进行加密的签名String signWx = (String) map.get("sign");//微信端传过来的签名if(signOwn.equals(signWx)){//如果两个签名一致,验证成功return true;}return false;}/*** 签名字符串* @param text 需要签名的字符串* @param sign 签名结果* @param key 密钥* @param input_charset 编码格式* @return 签名结果*/public static boolean verify(String text, String sign, String key, String input_charset) {text = text +"&key="+ key;String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));System.out.println("mysign = " + mysign);if (mysign.equals(sign)) {return true;} else {return false;}}/*** 元转换成分* @param amount* @return*/public static String getMoney(String amount) {if(amount==null){return "";}// 金额转化为分为单位String currency = amount.replaceAll("\\$|\\¥|\\,", ""); //处理包含, ¥ 或者$的金额int index = currency.indexOf(".");int length = currency.length();Long amLong = 0l;if(index == -1){amLong = Long.valueOf(currency+"00");}else if(length - index >= 3){amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));}else if(length - index == 2){amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);}else{amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");}return amLong.toString();}/*** 获取随机字符串 (采用截取8位当前日期数 + 4位随机整数)* @return*/public static String getNonceStr() {//获得当前日期Date now = new Date();SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");String currTime = outFormat.format(now);//截取8位String strTime = currTime.substring(8, currTime.length());//得到4位随机整数int num = 1;double random = Math.random();if (random < 0.1) {random = random + 0.1;}for (int i = 0; i < 4; i++) {num = num * 10;}num = (int)random * num;return strTime + num;}/*** MD5 加密,转为指定类型* @param text* @param key* @param input_charset* @return*/public static String sign(String text, String key, String input_charset) {text = text + key;return DigestUtils.md5Hex(getContentBytes(text, input_charset));}public static byte[] getContentBytes(String content, String charset) {if (charset == null || "".equals(charset)) {return content.getBytes();}try {return content.getBytes(charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);}}/*** 除去数组中的空值和签名参数* @param sArray 签名参数组* @return 去掉空值与签名参数后的新签名参数组*/public static SortedMap<Object, Object> paraFilter(Map<String, String> sArray) {SortedMap<Object, Object> result = new TreeMap<Object, Object>();if (sArray == null || sArray.size() <= 0) {return result;}for (String key : sArray.keySet()) {String value = sArray.get(key);if (value == null || value.equals("") || key.equalsIgnoreCase("sign")|| key.equalsIgnoreCase("sign_type")) {continue;}result.put(key, value);}return result;}

支付就可以实现了,如果大家有什么问题,可以随时留言。。。

觉得棒的话,赶紧打赏小编吧!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。