公众号微信支付java开发,微信支付签名错误,或者一直请求回调方法问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37581708/article/details/78928874

本编为原创,如需转载,请注明出处。

微信支付开发过程中,如果没有遇到签名错误这个问题或者一直请求回调方法问题,那么感觉你开发了一个假对接,网上也有许多列子,以及官网也有微信团队demo,但是还是有解决不了的各种签名问题,demo需要手动修改因为他的加密方式会不尽如人意,还有排序问题。好了,话不多说,直接进入步骤中。

注意:如果遇到签名错误,一定要查看参数顺序

          比较坑的是,

1:官网商户key填写的时候提示你8位数还是6位数以上的数字加字母组成就可以,但是你必须在设定完之后,再次修改成32位加密字符串!!!

2:回调地址,如果你是http://www.xxx.cn/txxxr/wxpay/wxpay.do的方式,你的地址需要写成http://www.xxx.cn/txxxr/wxpay/      !!!

好了,以上两个问题如果都没问题了,那么我们进入正式代码开发。(具体工具类以及全部代码,会在本文的末尾中。)

在此只介绍重点步骤,开发可以在demo中修改我的路径以及自己的逻辑就可以。


controller方法:

package cn.teacher.wxpay.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import cn.teacher.weiXin.dao.BasWxUserForStuDao;
import cn.teacher.wxpay.sdk.WXPay;
import cn.teacher.wxpay.sdk.WXPayUtil;
import cn.teacher.wxpay.util.WXPayConfigImpl;

@Controller
@RequestMapping("wxpay")
public class WXPayController {
	private WXPay wxpay;
    private WXPayConfigImpl config;
    private String out_trade_no;
    
    @Autowired
	private BasWxUserForStuDao basWxUserForStuDao;
    
    @RequestMapping(value="/wxpay_memberManagement")
    public  String memberManagement(HttpServletRequest request,Model model){
    	String openid ="ogcMwwuHoHeMG5Mp_cPkmYYdY6CU";
    	return "memberManagement";
    }
    @RequestMapping(value="/wxpay_packageInfo")
    public  String packageInfo(HttpServletRequest request){
    	return "packageInfo";
    }
    
    
    public WXPayController() throws Exception {
        config = WXPayConfigImpl.getInstance();
        wxpay = new WXPay(config);
        out_trade_no = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }
    
    
    /**
     * 扫码支付  下单
	 * @throws Exception 
     */
	@RequestMapping(value = "/wxpay_unifiedOrder", produces = "application/json;charset=UTF-8")//这一步必须有!!
	@Transactional
    public @ResponseBody String doUnifiedOrder(String bodyname,String fee) throws Exception {//bodyname例如:腾讯支付中心,fee为价格
		JSONObject result = new JSONObject();
		Map<String, String> resdata = new HashMap<String, String>();
		//获取到用户的openid
		String openid ="ogcMwwuHoHeMG5Mp_cPkmYYdY6CU";
		 Map<String, String> data = new HashMap<String, String>();
	        data.put("body", bodyname);
	        data.put("out_trade_no", out_trade_no);//生成的订单编号
	        data.put("fee_type", "CNY");
	        data.put("total_fee", fee);
	        data.put("spbill_create_ip", "58.87.76.30");//请求ip地址
	        data.put("notify_url", "http://xxx.mmath.cn/teacher/uploadwx/paytest");//请求成功返回路径
	        data.put("trade_type", "JSAPI");//公众号支付类型
	        data.put("openid", openid);
	        try {
	        	//统一下单,得到prepay_id
	            Map<String, String> r = wxpay.unifiedOrder(data);
	            //得到带预支付prepay_id
	            String prepay_id= r.get("prepay_id");
	            //拼接组成新的sign并加密
	            String timestamp = String.valueOf(new Date().getTime()/1000);
	            String stringA =""+"appId="+config.getAppID()+"&nonceStr="+r.get("nonce_str") +"&package=prepay_id="+prepay_id+"&signType=MD5"+"&timeStamp=" + timestamp + "&key="+config.getKey();
	            String sign=WXPayUtil.MD5(stringA).toUpperCase();
	            //返回页面数据供调用H5使用 
	            result.put("appId", config.getAppID());//appid
	            result.put("timeStamp", timestamp);//时间戳精确到秒
	            result.put("nonceStr", r.get("nonce_str"));//订单编号
	            result.put("paySign", sign);//sign
	            result.put("signType", "MD5");//加密方式
	            result.put("packageStr", "prepay_id=" + prepay_id);  //预支付id
	            result.put("flag", true);//支付方法状态
		//可以在此处添加一个临时的订单步骤,状态为支付中,在回调接口中修改支付状态为支付成功或者失败
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	        return JSON.toJSONString(result);
	}
}


页面jsp代码

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<% String path = request.getContextPath(); %>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>个人中心</title>
<script type="text/javascript" src="<%=path %>/js/jquery.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<body>
<div>
	<div style=" width: 100%;">
		<ul >
			<li style="width: 80%;float: left;"><p><strong id="bodyname">99元套餐</strong></p><p>六年级下学期下载</p></li>
			<li style="width: 20%;float: left;"><p><input type="button" value="结算" onclick="pay();" style="background-color: yellow;"></li>
			<li style="width: 100%;float: left;" >
			<input name="tab" type="checkbox" value="" onclick="money();"/>赵小小
			<input  name="tab" type="checkbox" value=""  onclick="money();"/>陈大
			<input  name="tab" type="checkbox" value=""  onclick="money();"/>辰辰
			   合计¥<strong id="m">0</strong> </li>
		</ul>		
	</div>
</div>
<script type="text/javascript">
var prepay_id ,paySign,appId ,timeStamp, nonceStr,packageStr ,signType ;
/**
 * 点击支付按钮进行方法调用
 */
function pay(){
var fee="20";
var bodyname="XXX支付界面";
    var url = "http://XXX.mmath.cn/teacher/wxpay/wxpay_unifiedOrder";
    $.ajax({
    type:"post",
    url:url,
    data: "bodyname="+bodyname+"&fee="+fee,
    success:function(data) {
     if(data.flag){
         appId = data.appId;
         paySign = data.paySign;
         timeStamp = data.timeStamp;
         nonceStr = data.nonceStr;
         packageStr = data.packageStr;
         signType = data.signType;
         callpay();
        }else{
         alert("统一下单失败");
        }
    }
});
}
/*
 * 调用支付h5页面
 */
function onBridgeReady(){
    WeixinJSBridge.invoke(
        'getBrandWCPayRequest', {
             "appId":appId,     //公众号名称,由商户传入
             "timeStamp":timeStamp, //时间戳,自1970年以来的秒数
             "nonceStr":nonceStr , //随机串
             "package":packageStr,  //预支付交易会话标识
             "signType":signType,     //微信签名方式
             "paySign":paySign         //微信签名
         },
         function(res){
          if(res.err_msg == "get_brand_wcpay_request:ok" ) {
         alert('支付成功');
     }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
         alert('支付取消');
     }else if(res.err_msg == "get_brand_wcpay_request:fail" ){
        alert('支付失败');
     } //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
         }
    );
}
/**
 * 判断是否进入支付步骤
 */
function callpay(){
    if (typeof WeixinJSBridge == "undefined"){
        if( document.addEventListener ){
            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        }else if (document.attachEvent){
            document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
            document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
    }else{
        onBridgeReady();
    }
}

</script>
</body>
</html>

其余的文件以及工具类

由于上次上传的文件没有声明以下内容,导致码农下载完资源后看到个官方demo基本一致,直接弃置不用,所以在此特别声明。如果介意,不要下载。

(本文项目是在微信官方demo的基础上进行修改开发的,所以类名方法名和框架结构和官方demo基本一致,但是部分内容会进行修改,请下载前仔细阅读)

http://download.csdn.net/download/qq_37581708/10198124

好吧,我不知道怎么弄成免费的,你们可以联系我,我私发给你们,或者留下你的QQ~

下面是最后一步处理:回调接口

/**
	 * 支付成功后,接收微信返回的回调方法
	 */
	@RequestMapping(value="/order", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public void order(HttpServletRequest request, HttpServletResponse response) throws Exception{
		String msg = "success";
        response.setContentType("text/xml");     
        String resXml = "";
	BufferedReader reader = null;
        reader = request.getReader();
        String line = "";
        String xmlString = null;
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();
        request.getReader().close();
        Document doc = null;
        try {
            // 下面的是通过解析xml字符串的
            doc = DocumentHelper.parseText(xmlString); // 将字符串转为XML
            Element rootElt = doc.getRootElement(); // 获取根节点
            Element recordEle = (Element)rootElt;
            String result_code = recordEle.elementTextTrim("result_code");
            String return_code = recordEle.elementTextTrim("return_code");
            String out_trade_no = recordEle.elementTextTrim("out_trade_no");
            String stuNo =out_trade_no.split("_ms_")[1];
		//在此处开始进行数据库订单记录状态插入与修改
            if(return_code.indexOf("SUCCESS")!=-1){ 
            	if(result_code.indexOf("SUCCESS")!=-1){
            		//支付成功
            		wXPayService.updateOrder(out_trade_no, "1",stuNo);
            	}else{
            		//支付失败
            		wXPayService.updateOrder(out_trade_no, "2","1");
            	}
		//这一步非常重要:返回给微信成功通知,否则会一直回调。
            	resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                BufferedOutputStream out = new BufferedOutputStream(
                        response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
                response.getWriter().println(msg);
            }
            
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


猜你喜欢

转载自blog.csdn.net/qq_37581708/article/details/78928874