java微信支付功能实现源码
提示:仅微信支付功能模块类,可供参考,可点赞
一、java后台实现源码
packagecn.xydx.crowdfunding.controller;
importcn.xydx.crowdfunding.util.HttpRequest;
importcn.xydx.crowdfunding.util.WXPayUtil;
importorg.json.JSONObject;
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.CrossOrigin;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestMethod;
importorg.springframework.web.bind.annotation.ResponseBody;
importjavax.servlet.http.HttpServletRequest;
importjava.text.DateFormat;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.Random;
importstaticcn.xydx.crowdfunding.util.WXPayConfig.appid;
importstaticcn.xydx.crowdfunding.util.WXPayConfig.appsecret;
importstaticcn.xydx.crowdfunding.util.WXPayConfig.mch_id;
importstaticcn.xydx.crowdfunding.util.WXPayConfig.key;
@Controller
@RequestMapping(value="WeixinService")
@CrossOrigin
publicclassWeixinPayController{
/**
*@paramrequest
*@paramcode
*@returnMap
*@Description微信浏览器内微信支付/公众号支付(JSAPI)
*/
@RequestMapping(value="orders",method=RequestMethod.GET)
@ResponseBody
publicMaporders(HttpServletRequestrequest,Stringcode){
try{
//页面获取openId接口
Stringgetopenid_url="https://api.weixin.qq.com/sns/oauth2/access_token";
Stringparam="appid="+appid+"&secret="+appsecret+"&code="+code+"&grant_type=authorization_code";
//向微信服务器发送get请求获取openIdStr
StringopenIdStr=HttpRequest.sendGet(getopenid_url,param);
//JSONObjectjson=JSONObject.parseObject(openIdStr);//转成Json格式
JSONObjectjson=newJSONObject(openIdStr);
StringopenId=json.getString("openid");//获取openId
//拼接统一下单地址参数
MapparaMap=newHashMap();
//获取请求ip地址
Stringip=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",appid);
paraMap.put("mch_id",mch_id);
paraMap.put("nonce_str",WXPayUtil.generateNonceStr());
paraMap.put("body","CrowdFund");
paraMap.put("out_trade_no",getOrderSn());//订单号
paraMap.put("total_fee","1");
paraMap.put("spbill_create_ip",ip);
paraMap.put("notify_url","http://******/index.html");//此路径是微信服务器调用支付结果通知路径随意写
paraMap.put("trade_type","JSAPI");
paraMap.put("openid",openId);
Stringsign=WXPayUtil.generateSignature(paraMap,key);
paraMap.put("sign",sign);
Stringxml=WXPayUtil.mapToXml(paraMap);//将所有参数(map)转xml格式
//System.out.println("xml="+xml);
//统一下单
Stringunifiedorder_url="https://api.mch.weixin.qq.com/pay/unifiedorder";
StringxmlStr=HttpRequest.sendPost(unifiedorder_url,xml);//发送post请求"统一下单接口"返回预支付id:prepay_id
System.out.println(xmlStr);
//以下内容是返回前端页面的json数据
Stringprepay_id="";//预支付id
if(xmlStr.indexOf("SUCCESS")!=-1){
Mapmap=WXPayUtil.xmlToMap(xmlStr);
prepay_id=(String)map.get("prepay_id");
}
MappayMap=newHashMap();
payMap.put("appId",appid);
payMap.put("timeStamp",WXPayUtil.getCurrentTimestamp()+"");
payMap.put("nonceStr",WXPayUtil.generateNonceStr());
payMap.put("signType","MD5");
payMap.put("package","prepay_id="+prepay_id);
StringpaySign=WXPayUtil.generateSignature(payMap,key);
payMap.put("paySign",paySign);
//System.out.println("code="+code);
System.out.println("openIdStr="+openIdStr);
returnpayMap;
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
publicStringgetOrderSn(){
//创建不同的日期格式
DateFormatdf=newSimpleDateFormat("yyyyMMddHHmmss");
Randomrm=newRandom();
//获得随机数
doublepross=(1+rm.nextDouble())*Math.pow(10,6);
//将获得的获得随机数转化为字符串
StringfixLenthString=String.valueOf(pross);
StringdateNum=df.format(newDate())+"WX"+fixLenthString.substring(1,7);
returndateNum;
}
@RequestMapping(value="orderquery",method=RequestMethod.GET)
@ResponseBody
publicStringorderquery(){
try{
MapreqMap=newHashMap();
reqMap.put("appid",appid);
reqMap.put("mch_id",mch_id);
reqMap.put("nonce_str",WXPayUtil.generateNonceStr());
reqMap.put("out_trade_no",getOrderSn());//商户系统内部的订单号,
Stringsign=WXPayUtil.generateSignature(reqMap,key);
reqMap.put("sign",sign);
StringreqXmlStr=WXPayUtil.mapToXml(reqMap);//将所有参数(map)转xml格式
//System.out.println("xml="+reqXmlStr);
//查询订单https://api.mch.weixin.qq.com/pay/orderquery
Stringorderquery="https://api.mch.weixin.qq.com/pay/orderquery";
StringxmlStr=HttpRequest.sendPost(orderquery,reqXmlStr);
returnxmlStr;
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
}
HttpRequest类
packagecn.xydx.crowdfunding.util;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.URL;
importjava.net.URLConnection;
importjava.util.List;
importjava.util.Map;
publicclassHttpUtil{
/**
*向指定URL发送GET方法的请求
*
*@paramurl发送请求的URL
*//@paramparam请求参数,请求参数应该是name1=value1&name2=value2的形式。
*@returnURL所代表远程资源的响应结果
*/
publicstaticStringsendGet(Stringurl){
Stringresult="";
BufferedReaderin=null;
try{
StringurlNameString=url;
URLrealUrl=newURL(urlNameString);
//打开和URL之间的连接
URLConnectionconnection=realUrl.openConnection();
//设置通用的请求属性
connection.setRequestProperty("accept","*/*");
connection.setRequestProperty("connection","Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");
//建立实际的连接
connection.connect();
//获取所有响应头字段
Map>map=connection.getHeaderFields();
//遍历所有的响应头字段
for(Stringkey:map.keySet()){
System.out.println(key+"--->"+map.get(key));
}
//定义BufferedReader输入流来读取URL的响应
in=newBufferedReader(newInputStreamReader(
connection.getInputStream()));
Stringline;
while((line=in.readLine())!=null){
result+=line;
}
}catch(Exceptione){
System.out.println("发送GET请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输入流
finally{
try{
if(in!=null){
in.close();
}
}catch(Exceptione2){
e2.printStackTrace();
}
}
returnresult;
}
/**
*向指定URL发送POST方法的请求
*
*@paramurl发送请求的URL
*@paramparam请求参数,请求参数应该是name1=value1&name2=value2的形式。
*@return所代表远程资源的响应结果
*/
publicstaticStringsendPost(Stringurl,Stringparam){
PrintWriterout=null;
BufferedReaderin=null;
Stringresult="";
try{
URLrealUrl=newURL(url);
//打开和URL之间的连接
URLConnectionconn=realUrl.openConnection();
//设置通用的请求属性
conn.setRequestProperty("accept","*/*");
conn.setRequestProperty("connection","Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");
//发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
//获取URLConnection对象对应的输出流
out=newPrintWriter(conn.getOutputStream());
//发送请求参数
out.print(param);
//flush输出流的缓冲
out.flush();
//定义BufferedReader输入流来读取URL的响应
in=newBufferedReader(
newInputStreamReader(conn.getInputStream()));
Stringline;
while((line=in.readLine())!=null){
result+=line;
}
}catch(Exceptione){
System.out.println("发送POST请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}catch(IOExceptionex){
ex.printStackTrace();
}
}
returnresult;
}
}
WXPayUtil类
packagecn.xydx.crowdfunding.util;
importcn.xydx.crowdfunding.util.WXPayConstants.SignType;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.w3c.dom.Node;
importorg.w3c.dom.NodeList;
importjavax.crypto.Mac;
importjavax.crypto.spec.SecretKeySpec;
importjavax.xml.parsers.DocumentBuilder;
importjavax.xml.transform.OutputKeys;
importjavax.xml.transform.Transformer;
importjavax.xml.transform.TransformerFactory;
importjavax.xml.transform.dom.DOMSource;
importjavax.xml.transform.stream.StreamResult;
importjava.io.ByteArrayInputStream;
importjava.io.InputStream;
importjava.io.StringWriter;
importjava.security.MessageDigest;
importjava.security.SecureRandom;
importjava.util.*;
publicclassWXPayUtil{
privatestaticfinalStringSYMBOLS="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
privatestaticfinalRandomRANDOM=newSecureRandom();
/**
*XML格式字符串转换为Map
*
*@paramstrXMLXML字符串
*@returnXML数据转换后的Map
*@throwsException
*/
publicstaticMapxmlToMap(StringstrXML)throwsException{
try{
Mapdata=newHashMap();
DocumentBuilderdocumentBuilder=WXPayXmlUtil.newDocumentBuilder();
InputStreamstream=newByteArrayInputStream(strXML.getBytes("UTF-8"));
org.w3c.dom.Documentdoc=documentBuilder.parse(stream);
doc.getDocumentElement().normalize();
NodeListnodeList=doc.getDocumentElement().getChildNodes();
for(intidx=0;idxdata)throwsException{
org.w3c.dom.Documentdocument=WXPayXmlUtil.newDocument();
org.w3c.dom.Elementroot=document.createElement("xml");
document.appendChild(root);
for(Stringkey:data.keySet()){
Stringvalue=data.get(key);
if(value==null){
value="";
}
value=value.trim();
org.w3c.dom.Elementfiled=document.createElement(key);
filed.appendChild(document.createTextNode(value));
root.appendChild(filed);
}
TransformerFactorytf=TransformerFactory.newInstance();
Transformertransformer=tf.newTransformer();
DOMSourcesource=newDOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT,"yes");
StringWriterwriter=newStringWriter();
StreamResultresult=newStreamResult(writer);
transformer.transform(source,result);
Stringoutput=writer.getBuffer().toString();//.replaceAll("\n|\r","");
try{
writer.close();
}
catch(Exceptionex){
}
returnoutput;
}
/**
*生成带有sign的XML格式字符串
*
*@paramdataMap类型数据
*@paramkeyAPI密钥
*@return含有sign字段的XML
*/
publicstaticStringgenerateSignedXml(finalMapdata,Stringkey)throwsException{
returngenerateSignedXml(data,key,SignType.MD5);
}
/**
*生成带有sign的XML格式字符串
*
*@paramdataMap类型数据
*@paramkeyAPI密钥
*@paramsignType签名类型
*@return含有sign字段的XML
*/
publicstaticStringgenerateSignedXml(finalMapdata,Stringkey,SignTypesignType)throwsException{
Stringsign=generateSignature(data,key,signType);
data.put(WXPayConstants.FIELD_SIGN,sign);
returnmapToXml(data);
}
/**
*判断签名是否正确
*
*@paramxmlStrXML格式数据
*@paramkeyAPI密钥
*@return签名是否正确
*@throwsException
*/
publicstaticbooleanisSignatureValid(StringxmlStr,Stringkey)throwsException{
Mapdata=xmlToMap(xmlStr);
if(!data.containsKey(WXPayConstants.FIELD_SIGN)){
returnfalse;
}
Stringsign=data.get(WXPayConstants.FIELD_SIGN);
returngenerateSignature(data,key).equals(sign);
}
/**
*判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
*
*@paramdataMap类型数据
*@paramkeyAPI密钥
*@return签名是否正确
*@throwsException
*/
publicstaticbooleanisSignatureValid(Mapdata,Stringkey)throwsException{
returnisSignatureValid(data,key,SignType.MD5);
}
/**
*判断签名是否正确,必须包含sign字段,否则返回false。
*
*@paramdataMap类型数据
*@paramkeyAPI密钥
*@paramsignType签名方式
*@return签名是否正确
*@throwsException
*/
publicstaticbooleanisSignatureValid(Mapdata,Stringkey,SignTypesignType)throwsException{
if(!data.containsKey(WXPayConstants.FIELD_SIGN)){
returnfalse;
}
Stringsign=data.get(WXPayConstants.FIELD_SIGN);
returngenerateSignature(data,key,signType).equals(sign);
}
/**
*生成签名
*
*@paramdata待签名数据
*@paramkeyAPI密钥
*@return签名
*/
publicstaticStringgenerateSignature(finalMapdata,Stringkey)throwsException{
returngenerateSignature(data,key,SignType.MD5);
}
/**
*生成签名.注意,若含有sign_type字段,必须和signType参数保持一致。
*
*@paramdata待签名数据
*@paramkeyAPI密钥
*@paramsignType签名方式
*@return签名
*/
publicstaticStringgenerateSignature(finalMapdata,Stringkey,SignTypesignType)throwsException{
SetkeySet=data.keySet();
String[]keyArray=keySet.toArray(newString[keySet.size()]);
Arrays.sort(keyArray);
StringBuildersb=newStringBuilder();
for(Stringk:keyArray){
if(k.equals(WXPayConstants.FIELD_SIGN)){
continue;
}
if(data.get(k).trim().length()>0)//参数值为空,则不参与签名
sb.append(k).append("=").append(data.get(k).trim()).append("&");
}
sb.append("key=").append(key);
if(SignType.MD5.equals(signType)){
returnMD5(sb.toString()).toUpperCase();
}
elseif(SignType.HMACSHA256.equals(signType)){
returnHMACSHA256(sb.toString(),key);
}
else{
thrownewException(String.format("Invalidsign_type:%s",signType));
}
}
/**
*获取随机字符串NonceStr
*
*@returnString随机字符串
*/
publicstaticStringgenerateNonceStr(){
char[]nonceChars=newchar[32];
for(intindex=0;index
二、前端支付关键模块
立即订购
需要上面的连接获取code
//获取code
functiongetQueryString(name){
varreg=newRegExp("(^|&)"+name+"=([^&]*)(&|$)","i");
varr=window.location.search.substr(1).match(reg);
if(r!=null)returnunescape(r[2]);returnnull;
}
varcode=getQueryString("code");
if(code){
varurl="http://******/WeixinService/orders?code="+code+"";
$.get(url,function(data){
varappid=data.appId;
vartimeStamp=data.timeStamp;
varnonceStr=data.nonceStr;
varpackage=data.package;
varsignType=data.signType;
varpaySign=data.paySign;
if(typeofWeixinJSBridge=="undefined"){
if(document.addEventListener){
document.addEventListener('WeixinJSBridgeReady',
onBridgeReady,false);
}elseif(document.attachEvent){
document.attachEvent('WeixinJSBridgeReady',
onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady',
onBridgeReady);
}
}else{
//onBridgeReady();
WeixinJSBridge.invoke('getBrandWCPayRequest',{
"appId":appid,//公众号名称,由商户传入
"timeStamp":timeStamp,//时间戳,自1970年以来的秒数
"nonceStr":nonceStr,//随机串
"package":package,
"signType":signType,//微信签名方式:
"paySign":paySign//微信签名
},
function(res){
if(res.err_msg=="get_brand_wcpay_request:ok"){
//console.log('支付成功');
//支付成功后比如新增数据
$.post("http://******/saveUser",{
userName:$('#inputName').val(),
userIdentity:$('#inputIdentity').val(),
companyName:$('#inputCompany').val(),
userPhone:$('#inputPhone').val()
},
function(data,status){
alert("数据:\n你好!"+$('#inputName').val()+"\n状态:"+status);
},
"json"
);
//支付成功后跳转的页面
alert("支付成功!将返回首页!请分享******!");
window.history.go(-1);
}elseif(res.err_msg=="get_brand_wcpay_request:cancel"){
//console.log('支付取消');
alert("支付取消!保证数据安全重新参加订购!");
//WeixinJSBridge.call('closeWindow');
window.history.go(-1);
}elseif(res.err_msg=="get_brand_wcpay_request:fail"){
//console.log('支付失败');
alert("支付失败!重复支付,建议稍后参加订购");
WeixinJSBridge.call('closeWindow');
}//使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
});
}
},"json")
}else{
alert("服务器异常")
}
提示:前端关键通过http连接生成code。后端最后获取reqXmlStr若不成功,可重置商户秘钥key。
总结
到此这篇关于java微信支付功能实现源码的文章就介绍到这了,更多相关java微信支付功能源码内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!