微信小程序> java实现微信小程序支付功能-微信小程序实现微信支付功能-微信小程序支付代码

java实现微信小程序支付功能-微信小程序实现微信支付功能-微信小程序支付代码

浏览量:1776 时间: 来源:No-way
1.

1.准备好小程序的appid,mch_id和key(注意这里的key是api秘钥,不是小程序秘钥,不是小程序秘钥,不是小程序秘钥)

2.

2.java的后台支付代码:小程序的支付是需要获取用户的openid

3.

3.直接上代码:

4.

controller发起支付的代码如下:

5.

/***@Description:发起微信支付*@paramopenid*@paramrequest*@author:wcf*@date:2018年7月17日*/@RequestMapping("wxrPay")@ResponseBodypublicMapString,ObjectwxrPay(HttpServletRequestrequest){MapString,ObjectmapnewHashMap();mapwxroutineService.paywxr(request);returnmap;}

6.

controlle回调方法的代码如下:

7.

/***@Description:微信支付*@return*@throwsException*/@RequestMapping("wxNotify")@ResponseBodypublicvoidwxNotify(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{System.out.println("-------------------------------------------------------进入回调");BufferedReaderbrnewBufferedReader(newInputStreamReader((ServletInputStream)request.getInputStream()));Stringlinenull;StringBuildersbnewStringBuilder();while((linebr.readLine())!null){sb.append(line);}br.close();//sb为微信返回的xmlStringnotityXmlsb.toString();StringresXml"";System.out.println("接收到的报文:"+notityXml);MapmapPayUtilrou.doXMLParse(notityXml);StringreturnCode(String)map.get("return_code");if("SUCCESS".equals(returnCode)){//验证签名是否正确MapString,StringvalidParamsPayUtilrou.paraFilter(map);//回调验签时需要去除sign和空值参数StringvalidStrPayUtilrou.createLinkString(validParams);//把数组所有元素,按照“参数参数值”的模式用“”字符拼接成字符串StringsignPayUtilrou.sign(validStr,WxPayConfig.key,"utf-8").toUpperCase();//拼装生成服务器端验证的签名//根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等if(sign.equals(map.get("sign"))){/**此处添加自己的业务逻辑代码start**/StringorderNumber(String)map.get("out_trade_no");//订单号Stringamount(String)map.get("total_fee");//价格IntegertotalPriceInteger.valueOf(amount);//服务器这边记录的是钱的分if(orderNumber.length()20){payService.updateRechargeStatus(orderNumber,totalPrice);}/**此处添加自己的业务逻辑代码end**///通知微信服务器已经支付成功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";}System.out.println(resXml);System.out.println("微信支付回调数据结束");BufferedOutputStreamoutnewBufferedOutputStream(response.getOutputStream());out.write(resXml.getBytes());out.flush();out.close();}

8.

service代码如下:

9.

MapString,Objectpaywxr(HttpServletRequestrequest);

10.

serviceImpl代码:

11.

@OverridepublicMapString,Objectpaywxr(HttpServletRequestrequest,StringorderId,Stringtemp){try{//生成的随机字符串Stringnonce_strPaytool.getRandomStringByLength(32);//商品名称Stringbody"肉品会";//获取客户端的ip地址Stringspbill_create_ipPayUtil.getRemoteAddrIp(request);//获得终端IPStringopenidrequest.getParameter("openId");floatpriceFloat.parseFloat(temp);intprice1(int)(price*100);Stringpprice1+"";//组装参数,用户生成统一下单接口的签名MapString,StringpackageParamsnewHashMapString,String();packageParams.put("appid",WxPayConfig.appid);packageParams.put("mch_id",WxPayConfig.mch_id);packageParams.put("nonce_str",nonce_str);packageParams.put("body",body);packageParams.put("out_trade_no",orderId);//商户订单号packageParams.put("total_fee",p);//支付金额,这边需要转成字符串类型,否则后面的签名会失败packageParams.put("spbill_create_ip",spbill_create_ip);packageParams.put("notify_url",WxPayConfig.notify_url);//支付成功后的回调地址packageParams.put("trade_type",WxPayConfig.TRADETYPE);//支付方式packageParams.put("openid",openid);StringprestrPayUtilrou.createLinkString(packageParams);//把数组所有元素,按照“参数参数值”的模式用“”字符拼接成字符串//MD5运算生成签名,这里是第一次签名,用于调用统一下单接口StringsignPayUtilrou.sign(prestr,WxPayConfig.key,"utf-8").toUpperCase();//拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去Stringxml"xml"+"appid"+WxPayConfig.appid+"/appid"+"body![CDATA["+body+"]]/body"+"mch_id"+WxPayConfig.mch_id+"/mch_id"+"nonce_str"+nonce_str+"/nonce_str"+"notify_url"+WxPayConfig.notify_url+"/notify_url"+"openid"+openid+"/openid"+"out_trade_no"+orderId+"/out_trade_no"+"spbill_create_ip"+spbill_create_ip+"/spbill_create_ip"+"total_fee"+p+"/total_fee"+"trade_type"+WxPayConfig.TRADETYPE+"/trade_type"+"sign"+sign+"/sign"+"/xml";System.out.println("调试模式_统一下单接口请求XML数据:"+xml);//调用统一下单接口,并接受返回的结果StringresultPayUtilrou.httpRequest(WxPayConfig.pay_url,"POST",xml);System.out.println("调试模式_统一下单接口返回XML数据:"+result);//将解析结果存储在HashMap中MapmapPayUtilrou.doXMLParse(result);Stringreturn_code(String)map.get("return_code");//返回状态码MapString,ObjectresponsenewHashMapString,Object();//返回给小程序端需要的参数if(return_code.equals("SUCCESS")){Stringprepay_id(String)map.get("prepay_id");//返回的预付单信息response.put("nonceStr",nonce_str);response.put("package","prepay_id"+prepay_id);LongtimeStampSystem.currentTimeMillis()/1000;response.put("timeStamp",timeStamp+"");//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误//拼接签名需要的参数StringstringSignTemp"appId"+WxPayConfig.appid+"nonceStr"+nonce_str+"packageprepay_id"+prepay_id+"signTypeMD5timeStamp"+timeStamp;//再次签名,这个签名用于小程序端调用wx.requesetPayment方法StringpaySignPayUtilrou.sign(stringSignTemp,WxPayConfig.key,"utf-8").toUpperCase();response.put("paySign",paySign);}response.put("appid",WxPayConfig.appid);//写支付前的业务代码returnresponse;}catch(Exceptione){e.printStackTrace();}returnnull;}

12.

下面就是用到的一些工具类:

13.

生成字符串:

14.

publicclassPaytool{/***StringUtils工具类方法*获取一定长度的随机字符串,范围0-9,a-z*@paramlength:指定字符串长度*@return一定长度的随机字符串*/publicstaticStringgetRandomStringByLength(intlength){Stringbase"abcdefghijklmnopqrstuvwxyz0123456789";RandomrandomnewRandom();StringBuffersbnewStringBuffer();for(inti0;ilength;i++){intnumberrandom.nextInt(base.length());sb.append(base.charAt(number));}returnsb.toString();}

15.

}

16.

其他的一些处理数据的工具类:

17.

publicclassPayUtilrou{/***签名字符串*@paramtext需要签名的字符串*@paramkey密钥*@paraminput_charset编码格式*@return签名结果*/publicstaticStringsign(Stringtext,Stringkey,Stringinput_charset){texttext+"key"+key;returnDigestUtils.md5Hex(getContentBytes(text,input_charset));}/***签名字符串*@paramtext需要签名的字符串*@paramsign签名结果*@paramkey密钥*@paraminput_charset编码格式*@return签名结果*/publicstaticbooleanverify(Stringtext,Stringsign,Stringkey,Stringinput_charset){texttext+key;StringmysignDigestUtils.md5Hex(getContentBytes(text,input_charset));if(mysign.equals(sign)){returntrue;}else{returnfalse;}}/***@paramcontent*@paramcharset*@return*@throwsSignatureException*@throwsUnsupportedEncodingException*/publicstaticbyte[]getContentBytes(Stringcontent,Stringcharset){if(charsetnull||"".equals(charset)){returncontent.getBytes();}try{returncontent.getBytes(charset);}catch(UnsupportedEncodingExceptione){thrownewRuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:"+charset);}}privatestaticbooleanisValidChar(charch){if((ch'0'ch'9')||(ch'A'ch'Z')||(ch'a'ch'z'))returntrue;if((ch0x4e00ch0x7fff)||(ch0x8000ch0x952f))returntrue;//简体中文汉字编码returnfalse;}/***除去数组中的空值和签名参数*@paramsArray签名参数组*@return去掉空值与签名参数后的新签名参数组*/publicstaticMapString,StringparaFilter(MapString,StringsArray){MapString,StringresultnewHashMapString,String();if(sArraynull||sArray.size()0){returnresult;}for(Stringkey:sArray.keySet()){StringvaluesArray.get(key);if(valuenull||value.equals("")||key.equalsIgnoreCase("sign")||key.equalsIgnoreCase("sign_type")){continue;}result.put(key,value);}returnresult;}/***把数组所有元素排序,并按照“参数参数值”的模式用“”字符拼接成字符串*@paramparams需要排序并参与字符拼接的参数组*@return拼接后字符串*/publicstaticStringcreateLinkString(MapString,Stringparams){ListStringkeysnewArrayListString(params.keySet());Collections.sort(keys);Stringprestr"";for(inti0;ikeys.size();i++){Stringkeykeys.get(i);Stringvalueparams.get(key);if(ikeys.size()-1){//拼接时,不包括最后一个字符prestrprestr+key+""+value;}else{prestrprestr+key+""+value+"";}}returnprestr;}/****@paramrequestUrl请求地址*@paramrequestMethod请求方法*@paramoutputStr参数*/publicstaticStringhttpRequest(StringrequestUrl,StringrequestMethod,StringoutputStr){//创建SSLContextStringBufferbuffernull;try{URLurlnewURL(requestUrl);HttpURLConnectionconn(HttpURLConnection)url.openConnection();conn.setRequestMethod(requestMethod);conn.setDoOutput(true);conn.setDoInput(true);conn.connect();//往服务器端写内容if(null!outputStr){OutputStreamosconn.getOutputStream();os.write(outputStr.getBytes("utf-8"));os.close();}//读取服务器端返回的内容InputStreamisconn.getInputStream();InputStreamReaderisrnewInputStreamReader(is,"utf-8");BufferedReaderbrnewBufferedReader(isr);buffernewStringBuffer();Stringlinenull;while((linebr.readLine())!null){buffer.append(line);}br.close();}catch(Exceptione){e.printStackTrace();}returnbuffer.toString();}publicstaticStringurlEncodeUTF8(Stringsource){Stringresultsource;try{resultjava.net.URLEncoder.encode(source,"UTF-8");}catch(UnsupportedEncodingExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}returnresult;}/***解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。*@paramstrxml*@return*@throwsJDOMException*@throwsIOException*/publicstaticMapdoXMLParse(Stringstrxml)throwsException{if(nullstrxml||"".equals(strxml)){returnnull;}/*!!!!注意,修复了微信官方反馈的漏洞,更新于2018-10-16*/try{MapString,StringdatanewHashMapString,String();//TODO在这里更换DocumentBuilderFactorydocumentBuilderFactoryDocumentBuilderFactory.newInstance();documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities",false);documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities",false);documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,true);documentBuilderFactory.setXIncludeAware(false);documentBuilderFactory.setExpandEntityReferences(false);InputStreamstreamnewByteArrayInputStream(strxml.getBytes("UTF-8"));org.w3c.dom.DocumentdocdocumentBuilderFactory.newDocumentBuilder().parse(stream);doc.getDocumentElement().normalize();NodeListnodeListdoc.getDocumentElement().getChildNodes();for(intidx0;idxnodeList.getLength();++idx){NodenodenodeList.item(idx);if(node.getNodeType()Node.ELEMENT_NODE){org.w3c.dom.Elementelement(org.w3c.dom.Element)node;data.put(element.getNodeName(),element.getTextContent());}}try{stream.close();}catch(Exceptionex){//donothing}returndata;}catch(Exceptionex){throwex;}}/***获取子结点的xml*@paramchildren*@returnString*/publicstaticStringgetChildrenText(Listchildren){StringBuffersbnewStringBuffer();if(!children.isEmpty()){Iteratoritchildren.iterator();while(it.hasNext()){Elemente(Element)it.next();Stringnamee.getName();Stringvaluee.getTextNormalize();Listliste.getChildren();sb.append(""+name+"");if(!list.isEmpty()){sb.append(getChildrenText(list));}sb.append(value);sb.append("/"+name+"");}}returnsb.toString();}publicstaticInputStreamString2Inputstream(Stringstr){returnnewByteArrayInputStream(str.getBytes());}

18.

}

19.

自己项目的一些配置参数:

20.

publicclassWxPayConfig{//小程序appidpublicstaticfinalStringappid"xxxxx";//微信支付的商户idpublicstaticfinalStringmch_id"xxxxx";//微信支付的商户密钥publicstaticfinalStringkey"xxxxx";//支付成功后的服务器回调urlpublicstaticfinalStringnotify_url"http://ip/xx/xx/wxNotify";//签名方式,固定值publicstaticfinalStringSIGNTYPE"MD5";//交易类型,小程序支付的固定值为JSAPIpublicstaticfinalStringTRADETYPE"JSAPI";//微信统一下单接口地址publicstaticfinalStringpay_url"https://api.mch.weixin.qq.com/pay/unifiedorder";

21.

}

22.

到这里,就可以成功进行小程序支付了!!!

23.

参考文章:https://blog.csdn.net/zhourenfei17/article/details/77765585

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

最新资讯

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎