Java调用微信支付功能的方法示例代码
Java使用微信支付
前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用。
因为涉及二维码的前端显示,所以有前端的内容
一.准备工作
所需微信公众号信息配置
- APPID:绑定支付的APPID(必须配置)
- MCHID:商户号(必须配置)
- KEY:商户支付密钥,参考开户邮件设置(必须配置)
- APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置)
我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供
二.构建项目架构
1.新建maven项目
2.导入依赖
org.springframework.boot spring-boot-starter-parent 2.2.1.RELEASE org.springframework.boot spring-boot-starter-web com.github.wxpay wxpay-sdk 0.0.3 org.apache.httpcomponents httpclient org.springframework.boot spring-boot-starter-freemarker
3.编写配置文件application.properties
#服务端口 server.port=8081 #微信开放平台appid wx.pay.app_id= #商户号 wx.pay.partner= #商户key wx.pay.partnerkey= #回调地址 wx.pay.notifyurl: spring.freemarker.tempalte-loader-path=classpath:/templates #关闭缓存,及时刷新,上线生产环境需要修改为true spring.freemarker.cache=false spring.freemarker.charset=UTF-8 spring.freemarker.check-template-location=true spring.freemarker.content-type=text/html spring.freemarker.expose-request-attributes=true spring.freemarker.expose-session-attributes=true spring.freemarker.request-context-attribute=request spring.freemarker.suffix=.ftl spring.mvc.static-path-pattern:/static/**
4.编写启动类
@SpringBootApplication @ComponentScan(basePackages={"com.haiyang.wxpay"}) publicclassApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(Application.class,args); } }
5.创建常用包controller,service,impl,utils
6.创建两个前端需要的文件夹static和templates
三.代码实现
1.创建工具类读取配置文件的参数
@Component publicclassWxPayUtilsimplementsInitializingBean{ @Value("${wx.pay.app_id}") privateStringappId; @Value("${wx.pay.partner}") privateStringpartner; @Value("${wx.pay.partnerkey}") privateStringpartnerKey; @Value("${wx.pay.notifyurl}") privateStringnotifyUrl; publicstaticStringWX_PAY_APP_ID; publicstaticStringWX_PAY_PARTNER; publicstaticStringWX_PAY_PARTNER_KEY; publicstaticStringWX_OPEN_NOTIFY_URL; @Override publicvoidafterPropertiesSet()throwsException{ WX_PAY_APP_ID=appId; WX_PAY_PARTNER=partner; WX_PAY_PARTNER_KEY=partnerKey; WX_OPEN_NOTIFY_URL=notifyUrl; } }
2.构建工具类发送http请求
/** *http请求客户端 * *@authorqy * */ publicclassHttpClient{ privateStringurl; privateMapparam; privateintstatusCode; privateStringcontent; privateStringxmlParam; privatebooleanisHttps; publicbooleanisHttps(){ returnisHttps; } publicvoidsetHttps(booleanisHttps){ this.isHttps=isHttps; } publicStringgetXmlParam(){ returnxmlParam; } publicvoidsetXmlParam(StringxmlParam){ this.xmlParam=xmlParam; } publicHttpClient(Stringurl,Map param){ this.url=url; this.param=param; } publicHttpClient(Stringurl){ this.url=url; } publicvoidsetParameter(Map map){ param=map; } publicvoidaddParameter(Stringkey,Stringvalue){ if(param==null) param=newHashMap (); param.put(key,value); } publicvoidpost()throwsClientProtocolException,IOException{ HttpPosthttp=newHttpPost(url); setEntity(http); execute(http); } publicvoidput()throwsClientProtocolException,IOException{ HttpPuthttp=newHttpPut(url); setEntity(http); execute(http); } publicvoidget()throwsClientProtocolException,IOException{ if(param!=null){ StringBuilderurl=newStringBuilder(this.url); booleanisFirst=true; for(Stringkey:param.keySet()){ if(isFirst) url.append("?"); else url.append("&"); url.append(key).append("=").append(param.get(key)); } this.url=url.toString(); } HttpGethttp=newHttpGet(url); execute(http); } /** *sethttppost,putparam */ privatevoidsetEntity(HttpEntityEnclosingRequestBasehttp){ if(param!=null){ List nvps=newLinkedList (); for(Stringkey:param.keySet()) nvps.add(newBasicNameValuePair(key,param.get(key)));//参数 http.setEntity(newUrlEncodedFormEntity(nvps,Consts.UTF_8));//设置参数 } if(xmlParam!=null){ http.setEntity(newStringEntity(xmlParam,Consts.UTF_8)); } } privatevoidexecute(HttpUriRequesthttp)throwsClientProtocolException, IOException{ CloseableHttpClienthttpClient=null; try{ if(isHttps){ SSLContextsslContext=newSSLContextBuilder() .loadTrustMaterial(null,newTrustStrategy(){ //信任所有 publicbooleanisTrusted(X509Certificate[]chain, StringauthType) throwsCertificateException{ returntrue; } }).build(); SSLConnectionSocketFactorysslsf=newSSLConnectionSocketFactory( sslContext); httpClient=HttpClients.custom().setSSLSocketFactory(sslsf) .build(); }else{ httpClient=HttpClients.createDefault(); } CloseableHttpResponseresponse=httpClient.execute(http); try{ if(response!=null){ if(response.getStatusLine()!=null) statusCode=response.getStatusLine().getStatusCode(); HttpEntityentity=response.getEntity(); //响应内容 content=EntityUtils.toString(entity,Consts.UTF_8); } }finally{ response.close(); } }catch(Exceptione){ e.printStackTrace(); }finally{ httpClient.close(); } } publicintgetStatusCode(){ returnstatusCode; } publicStringgetContent()throwsParseException,IOException{ returncontent; } }
额~有点长就不放图片了代码都一样
3.新建controller
@Controller @RequestMapping("/wxpay") publicclassWxPayController{ @RequestMapping("/pay") publicStringcreatePayQRcode(Modelmodel)throwsException{ Stringprice="0.01"; Stringno=getOrderNo(); Mapm=newHashMap(); m.put("appid",WxPayUtils.WX_PAY_APP_ID); m.put("mch_id",WxPayUtils.WX_PAY_PARTNER); m.put("nonce_str",WXPayUtil.generateNonceStr()); m.put("body","微信支付测试");//主体信息 m.put("out_trade_no",no);//订单唯一标识 m.put("total_fee",getMoney(price));//金额 m.put("spbill_create_ip","127.0.0.1");//项目的域名 m.put("notify_url",WxPayUtils.WX_OPEN_NOTIFY_URL);//回调地址 m.put("trade_type","NATIVE");//生成二维码的类型 //3发送httpclient请求,传递参数xml格式,微信支付提供的固定的地址 HttpClientclient=newHttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder"); //设置xml格式的参数 //把xml格式的数据加密 client.setXmlParam(WXPayUtil.generateSignedXml(m,WxPayUtils.WX_PAY_PARTNER_KEY)); client.setHttps(true); //执行post请求发送 client.post(); //4得到发送请求返回结果 //返回内容,是使用xml格式返回 Stringxml=client.getContent(); //把xml格式转换map集合,把map集合返回 MapresultMap=WXPayUtil.xmlToMap(xml); //最终返回数据的封装 Mapmap=newHashMap(); map.put("no",no); map.put("price",price); map.put("result_code",resultMap.get("result_code")); map.put("code_url",resultMap.get("code_url")); model.addAttribute("map",map); return"pay"; } @GetMapping("queryorder/{no}") @ResponseBody publicStringqueryPayStatus(@PathVariableStringno)throwsException{ //1、封装参数 Mapm=newHashMap<>(); m.put("appid",WxPayUtils.WX_PAY_APP_ID); m.put("mch_id",WxPayUtils.WX_PAY_PARTNER); m.put("out_trade_no",no); m.put("nonce_str",WXPayUtil.generateNonceStr()); //2发送httpclient HttpClientclient=newHttpClient("https://api.mch.weixin.qq.com/pay/orderquery"); client.setXmlParam(WXPayUtil.generateSignedXml(m,WxPayUtils.WX_PAY_PARTNER_KEY)); client.setHttps(true); client.post(); //3.得到订单数据 Stringxml=client.getContent(); Map resultMap=WXPayUtil.xmlToMap(xml); //4.判断是否支付成功 if(resultMap.get("trade_state").equals("SUCCESS")){ /* 改变数据库中的数据等操作 */ return"支付成功"; } return"支付中"; } @GetMapping("success") publicStringsuccess(){ return"success"; } @RequestMapping("test") publicStringtest(){ return"pay"; } /** *生成订单号 *@return */ publicstaticStringgetOrderNo(){ SimpleDateFormatsdf=newSimpleDateFormat("yyyyMMddHHmmss"); StringnewDate=sdf.format(newDate()); Stringresult=""; Randomrandom=newRandom(); for(inti=0;i<3;i++){ result+=random.nextInt(10); } returnnewDate+result; } /** *元转换成分 *@paramamount *@return */ publicstaticStringgetMoney(Stringamount){ if(amount==null){ return""; } //金额转化为分为单位 //处理包含,¥或者$的金额 Stringcurrency=amount.replaceAll("\\$|\\¥|\\,",""); intindex=currency.indexOf("."); intlength=currency.length(); LongamLong=0l; if(index==-1){ amLong=Long.valueOf(currency+"00"); }elseif(length-index>=3){ amLong=Long.valueOf((currency.substring(0,index+3)).replace(".","")); }elseif(length-index==2){ amLong=Long.valueOf((currency.substring(0,index+2)).replace(".","")+0); }else{ amLong=Long.valueOf((currency.substring(0,index+1)).replace(".","")+"00"); } returnamLong.toString(); } }
4.在templates文件中新建订单支付页面(二维码生成的页面)
注意:文件名必须和生成二维码方法中返回的字符串名称一样我这里叫pay
先新建html页面,然后再将后缀改成ftl(freemarker模板引擎的后缀名)
Title