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,Mapparam){
this.url=url;
this.param=param;
}
publicHttpClient(Stringurl){
this.url=url;
}
publicvoidsetParameter(Mapmap){
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){
Listnvps=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();
MapresultMap=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