简介:
首先,对接微信支付要知道需要什么参数,然后等我们拿到这些需要的参数。就要开始怎么去做。微信有专门的支付dome,可惜我才疏学浅,没怎么看懂(哭泣~)。不过里面的有一些工具类是我们所需要的。
这里我们可以看到所需的参数:
公众账号ID appid:这个是从商户公众号后台里面获取的
商户号 mch_id:这个也是从商户后台获取的,申请退款的时候这商户号就是退款证书的AES加解密算法的key
随机字符串 nonce_str:这个可以在微信官网的dome里面使用工具类
终端IP spbill_create_ip:官网的dome中获得
通知地址 notify_url:比如下单成功之后的回调地址。通知url必须为外网可访问的url,不能携带参数
用户标识 openid:trade_type=JSAPI时(即JSAPI支付),此参数必传,此参数为微信用户在商户对应appid下的唯一标识
交易类型 trade_type:JSAPI -JSAPI支付 NATIVE -Native支付 APP -APP支付
签名 sign:通过签名算法计算得出的签名值,详见签名生成算法
这里我们所作的是JSAPI支付方式,所以这里的openid必需要获得:如何获得,该怎么获得。
首先,要知道我们使用的是微信里面自带的浏览器,我们通过微信浏览器给当前用户进行用户授权。看JS 代码
var code = "";
$(function(){
/**
如果你之前从上一个页面已经获得code,你可以直接从url带过来
这个code是从微信浏览器获得的,随后通过这个code去后台请求微信端
获取openid
*/
code=getUrlParam("code");
if(code==undefined || code==""){
if(is_weixn()){
$(location).attr("href","https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxx&redirect_uri=xxx&response_type=code&scope=snsapi_base&state=1#wechat_redirect");
}else{
//跳转让他关注公众号
//Alert3('不是微信浏览器');
$(location).attr("href","#");
}
}
})
/**
*判断是否微信浏览器
*/
function is_weixn(){
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
return true;
} else {
return false;
}
}
/**
*获取url中的参数
*/
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
这里有几个参数需要注意以下:
获取code 的请求地址:https://open.weixin.qq.com/connect/oauth2/authorize?
后面带参数appid=商户后台获取的appid
redirect_uri=当前需要支付授权的页面的完整地址(跳转回调redirect_uri,应当使用https链接来确保授权code的安全性。),需要https,需要对地址进行urlEncode处理,需要注意参数顺序。
后面参数固定不变。
这个code 在前端获取之后就有这个值,需请求后台即可拿到openid
订单支付
/**
*微信支付
*/
$("#wxpay").click(function(){
var parameter={};
if(code !=null && code!=undefined && code!=""){
parameter["code"]=code;
}else{
Alert3('微信授权失败,无法支付');
return;
}
//支付方式0/1、wx/zfb
parameter["payMethod"]="0";
parameter["amount"]=价格;
var data=getData2(parameter);
var requestDate=ajax(url + "/xxx",data);
if(requestDate["code"]==10000){
res(requestDate["prepayId"]); //prepayId微信支付成功的返回参数,需要带到前台
}else{
alert(requestDate["msg"]);
}
})
function getData2(parameter){
var data={};
data["parameter"]=parameter;
return JSON.stringify(data);
}
/**
*支付标识验证
*/
function res(prepayId){
var appId="xxx";//商户appid
var timestamp=Math.round(new Date().getTime()/1000).toString();
var nonceStr=getMachine();
var package="prepay_id="+prepayId;
var signType="MD5";
var stringSignTemp="appId={0}&nonceStr={1}&package={2}&signType={3}&timeStamp={4}&key=qwertyuiopasdfghjklzxcvbqwertyui";
stringSignTemp=String.format(stringSignTemp,appId,nonceStr,package,signType,timestamp);
var paySign=$.md5(stringSignTemp).toUpperCase();
onBridgeReady(appId,timestamp,nonceStr,package,signType,paySign);
}
/**
*支付参数校验
*/
function onBridgeReady(appId,timestamp,nonceStr,package,signType,paySign){
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" ){
alert("支付成功");
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
} else{
alert("支付失败");
}
});
}
/**
*获得随机数
*/
function getMachine(){
var chars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
var machine="";
for(var i=0; i<16;i++){
var t=parseInt(61*Math.random())
machine=machine+chars[t];
}
return machine;
}
后台调用
//支付调用
String payMethod = object.optString("payMethod"); //支付方式
// String orderNo = "xxx";
if (payMethod.trim().equals("0")){
String code = object.optString("code");
String wx_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + SysConfig.getWx_appid() + "&secret=" + SysConfig.getWx_secret() + "&code=" + code + "&grant_type=authorization_code";
String sb2 = HttpUtil.httpsGet(wx_url);
if(sb2 == null || "".equals(sb2)){
map.put("code",30001);
map.put("msg","网络繁忙,请稍后重试");
return map;
}
JSONObject object2 = JSONObject.fromObject(sb2);
System.out.println("object2==="+object2);
openid = object2.optString("openid");
if (openid == ""){
map.put("code", 31002);
map.put("msg", "授权失败,请稍后重试");
return map;
}
Map<String, String> data = new HashMap<String, String>();
data.put("appid", SysConfig.getWx_appid());//商户appid
data.put("body", "xxx支付:");
data.put("detail", "xxx描述");
data.put("mch_id", SysConfig.getWx_mch_id());
data.put("nonce_str",WXPayUtil.generateNonceStr());//随机串
data.put("notify_url", SysConfig.getWx_notify_verify());//回调地址
data.put("openid",openid);
data.put("out_trade_no", orderNo);//商户订单
data.put("sign_type", "MD5");
data.put("spbill_create_ip", GetIpUtil.getIp(request));
data.put("total_fee", String.valueOf((int)(amount*100)));//金额:分
data.put("trade_type", "JSAPI");
String xml = WXPayUtil.generateSignedXml(data,SysConfig.getWx_key());//这里是微信商户的支付key,也就是api密钥
System.out.println("xml==="+xml);
String respn = HttpUtil.sendJsonPost(SysConfig.getWx_payMent(),xml).toString();
if (respn == null){
map.put("code", 31001);
map.put("msg", "系统繁忙,请稍后重试");
return map;
}
Map resp = JSONObject.fromObject(WXPayUtil.parseXml(respn).get("xml"));
if("SUCCESS".equals(resp.get("return_code"))){
prepayId = resp.get("prepay_id").toString();
}else{
map.put("code", 31003);
map.put("msg", "系统繁忙,请稍后重试");
return map;
}
}else{
map.put("code", 10004);
map.put("msg", "支付方式异常!");
}
下面是支付所需的工具类:
发起请求的POST和GET
public static String httpsGet(String urlStr) {
StringBuilder result = new StringBuilder();
BufferedReader reader = null;
try {
// 创建连接
URL url = new URL(urlStr);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.connect();
// 读取响应
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
System.out.println("Https返回:");
while ((line = reader.readLine()) != null) {
result.append(line.trim());
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException ex) {
LogUtil.error("io流关闭错误!" + ex);
ex.printStackTrace();
}
}
return result.toString();
}
//发送json请求
public static StringBuilder sendJsonPost(String url, String param) {
if (url == null) {
return new StringBuilder("NETWORKURLERROR");
}
PrintWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder("");
try {