微信公众号支付

1.配置测试支付目录域名,添加测试公众号。

2.因为公众号支付需要openid,所以配置网页授权域名。

3.pay页面调用H5微信授权,回调returnWxPay。

function wxpay(params){
    var json = "{";
    for(var item in params){  
          var value=params[item];//key所对应的value  
          json = json+"%22"+item+"%22:"+value+",";
   }
   json = json+"}";
    var url = "http://xm.ysyisu.cn/server/returnWxPay";
    var str = "https://open.weixin.qq.com/connect/oauth2/authorize?"+
    "appid=wx87019669d6f33b43&"+
    "redirect_uri="+encodeURI(url)+"&"+
    "response_type=code&"+
    "scope=snsapi_base&"+
    "state="+json+
    "#wechat_redirect";
    window.location.href=str;
    }

4、到回调方法执行业务,返回weixinPay页面

@RequestMapping("/returnWxPay")
public String returnWxPay(Model m,HttpServletRequest request,String code){
Map<String, Object> map = service.returnWxPay(request,code);
String state = request.getParameter("state");
int jsontype = service.getJSONType(state);
JSONObject json = new JSONObject();
JSONArray arr = new JSONArray();
if(jsontype==0){
json = new JSONObject(state);
Integer type = (Integer) json.get("type");
Integer mid = (Integer) json.get("mid");
       Double price = (Double) json.get("price");
       map.put("type", type);
       map.put("mid", mid);
       map.put("price", price);
       if(type==1){ //广告

}else if(type==2){  //单品
Integer goodnum = (Integer) json.get("goodnum");
map.put("goodnum", goodnum);
}else if(type==3){ //购物车

}else if(type==4){ //头条

}

}else if(jsontype==1){ //购物车  购物车的类别为jsonarray
map.put("type", 3);
}

m.addAttribute("map", map);

return "client/weixinPay";
}

5.取到openid

public Map<String, Object> returnWxPay(HttpServletRequest request,String code) {

Map<String, String> result = UserServiceImpl.getUserInfoAccessToken(code);//通过这个code获取access_token
        String openId = result.get("openid");
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("openid", openId);
        Map<String, Object> map = new HashMap<String, Object>();
try {
map = WeixinReturn(request,param);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;

}

6.调用统一下单接口 并封装公众号H5调用支付的参数

// 请求微信服务器返回xml
public Map<String, Object> WeixinReturn(HttpServletRequest request,Map<String, Object> map)throws UnsupportedEncodingException {
String ip = getIpAddr(request);  //获取真实IP
map = return_yw(request, map);  //返回业务map  1.订单 2.金额 3.各类参数

Map<String, Object> result = new HashMap<String, Object>();
long a = Long.parseLong(String.valueOf(System.currentTimeMillis()).toString().substring(0,10));
String url = WeixinPayUtil.order_url;
Document doc = DocumentHelper.createDocument();
doc.setXMLEncoding("utf-8");
Element xml = doc.addElement("xml");
//公众账号ID
Element appid = xml.addElement("appid");
appid.addCDATA(WeixinPayUtil.appid);
//商户号
Element mch_id = xml.addElement("mch_id");
mch_id.addCDATA(WeixinPayUtil.mch_id);
//随机字符串
Element nonce_str = xml.addElement("nonce_str");
String suiji = WeixinPayUtil.MD5Encode("" + Math.random(),"utf-8");
nonce_str.addCDATA(suiji);
//商品描述
Element body = xml.addElement("body");
String str = "xm-sp";
body.addCDATA(str);
//商户订单号
Element out_trade_no = xml.addElement("out_trade_no");
out_trade_no.addCDATA(map.get("out_trade_no").toString());
//标价金额
Element total_fee = xml.addElement("total_fee");
total_fee.addCDATA(String.valueOf((int) Math.floor(Double.parseDouble(map.get("total_fee").toString()) * 100)));
//终端IP
Element spbill_create_ip = xml.addElement("spbill_create_ip");
spbill_create_ip.addCDATA(ip);
//通知地址
Element notify_url = xml.addElement("notify_url");
notify_url.addCDATA(WeixinPayUtil.notify_url);
//交易类型
Element trade_type = xml.addElement("trade_type");
trade_type.addCDATA(WeixinPayUtil.trade_type);
//openid
Element openid = xml.addElement("openid");
openid.addCDATA((String) map.get("openid"));
//参数attach
Element attach = xml.addElement("attach");
attach.addCDATA((String) map.get("attach"));

SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
parameters.put("appid", WeixinPayUtil.appid);
parameters.put("body", str);
parameters.put("mch_id", WeixinPayUtil.mch_id);
parameters.put("nonce_str", suiji);
parameters.put("notify_url", WeixinPayUtil.notify_url);
parameters.put("out_trade_no", map.get("out_trade_no").toString());
parameters.put("spbill_create_ip", ip);
parameters.put("total_fee", String.valueOf((int) Math.floor(Double.parseDouble(map.get("total_fee").toString()) * 100)));
parameters.put("trade_type", WeixinPayUtil.trade_type);
parameters.put("openid", (String) map.get("openid"));
parameters.put("attach", (String) map.get("attach"));


//签名
String stringSign = WeixinPayUtil.createSign("UTF-8", parameters);
Element sign = xml.addElement("sign");
sign.addCDATA(stringSign);


String xmlString = doc.asXML();
String xx = sendPost(url, xmlString);  //调用统一下单
//String xx = doPost(url, xmlString, "utf-8");
Map<String, Object> res = new HashMap<String, Object>();

try {
Document reDocument = DocumentHelper.parseText(xx);
Element root = reDocument.getRootElement();
for (Iterator it = root.elementIterator(); it.hasNext();) {
Element element = (Element) it.next();
String name = element.getName();
String text = element.getTextTrim();
if("mch_id".equals(name)){
res.put("partnerId", text);
result.put("partnerId", text);
}else{
res.put(name, text);
result.put(name,text);
}
}
res.put("timestamp", Long.toString(a));
String return_code = res.get("return_code").toString();
String return_msg = res.get("return_msg").toString();
result.put("return_code", return_code);
result.put("return_msg", return_msg);
if (!return_code.equals("SUCCESS")){
return result;
}

String packageValue = "prepay_id="+res.get("prepay_id");
SortedMap<Object, Object> parm = new TreeMap<Object, Object>();
parm.put("appId", WeixinPayUtil.appid);
parm.put("timeStamp", Long.toString(a));
parm.put("nonceStr", res.get("nonce_str"));
parm.put("package", packageValue);
parm.put("signType", "MD5");
String returnSign = WeixinPayUtil.createSign("UTF-8", parm);

result.put("appid", WeixinPayUtil.appid);
result.put("timestamp", Long.toString(a));
result.put("noncestr", res.get("nonce_str"));
result.put("package", packageValue);
result.put("signType", "MD5");
result.put("mch_id", WeixinPayUtil.mch_id);
result.put("paySign", returnSign);
result.put("prepay_id", res.get("prepay_id"));
result.put("paySign", returnSign);

//业务
result.put("out_trade_no", map.get("out_trade_no")); //订单号
result.put("total_fee", map.get("total_fee"));  //总金额
} catch (DocumentException e) {
e.printStackTrace();
return result;
}
return result;
}


/**
     * 向指定 URL 发送POST方法的请求
     * 
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(),"utf-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!"+e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }   


public String getIpAddr(HttpServletRequest request) {  
         String ip = 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();  
         } 
        return ip;  
    }  

7.返回weixinPay页面,支付成功回调通知地址notify_url,该地址不能带其他参数,参数通过attach来传递

<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
  <script type="text/javascript"> 
  var appId = "${map.appid}"; 
  var timeStamp = "${map.timestamp}"; 
  var nonceStr = "${map.noncestr}"; 
  var prepay_id = "${map.prepay_id}"; 
  var signType ="${map.signType}"; 
  var paySign = "${map.paySign}"; 
  
  var type = "${map.type}";
  /* var mid = "${map.mid}";
  var price = "${map.price}";
  var goodnum = "${map.goodnum}"; */
/*   wx.config({
   debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
   appId: appId, // 必填,公众号的唯一标识
   timestamp: timeStamp, // 必填,生成签名的时间戳
   nonceStr: nonceStr, // 必填,生成签名的随机串
   signature: paySign,// 必填,签名,见附录1
   jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
}); */

   function onBridgeReady(){ 
      WeixinJSBridge.invoke( 
        'getBrandWCPayRequest', { 
          "appId" : appId,   //公众号名称,由商户传入    
          "timeStamp": timeStamp,     //时间戳,自1970年以来的秒数    
          "nonceStr" : nonceStr, //随机串    
          "package" : "prepay_id=" + prepay_id,    
          "signType" : signType,     //微信签名方式:    
          "paySign" : paySign  //微信签名  
        }, 
        function(res){   
          WeixinJSBridge.log(res.err_msg);
          if(res.err_msg == "get_brand_wcpay_request:ok"){
           if(type==1){
            window.location.href="${basePath}advert/manager";
           }else if(type==2){
            window.location.href="${basePath}order/manager";
           }else if(type==3){
          window.location.href="${basePath}order/manager";
           }else if(type==4){
            window.location.href="${basePath}main/details";
           }
           
          }else{
              //返回跳转到订单详情页面
              alert("支付失败!请重新下单再试!");
          }
        } 
      ); 
      
      /* wx.chooseWXPay({
   timestamp: timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
   nonceStr: nonceStr, // 支付签名随机串,不长于 32 位
   package: "prepay_id="+prepay_id, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
   signType: signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
   paySign: paySign, // 支付签名
   success: function (res) {
       // 支付成功后的回调函数
   }
});  */
    } 
     
     
    function pay(){ 
      if (typeof WeixinJSBridge == "undefined"){
        if( documentaddEventListener ){ 
          documentaddEventListener('WeixinJSBridgeReady', onBridgeReady, false); 
        }else if (documentattachEvent){ 
          documentattachEvent('WeixinJSBridgeReady', onBridgeReady);  
          documentattachEvent('onWeixinJSBridgeReady', onBridgeReady); 
        } 
      }else{ 
        onBridgeReady(); 
      }  
        
    } 
  </script> 

8.通知回调

//微信通知  支付回调
public void weixinNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{  
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();  
        inputStream = request.getInputStream();  
        String s ;  
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
     while ((s = in.readLine()) != null){  
     sb.append(s);  
     }  
     in.close();  
     inputStream.close();  


     //解析xml成map  
     Map<String, Object> m = new HashMap<String, Object>();  
     //m = XmlConverUtil.xmltoMap(sb.toString());  
     //m = XmlConverUtil.parseXmlStr(sb.toString());
     Document document = DocumentHelper.parseText(sb.toString());    
     m = XmlConverUtil.Dom2Map(document);
        
     //过滤空 设置 TreeMap  
     SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
     Iterator it = m.keySet().iterator();  
     while (it.hasNext()) {  
     String parameter = (String) it.next();  
     String parameterValue = m.get(parameter).toString();  
            
     String v = "";  
     if(null != parameterValue) {  
     v = parameterValue.trim();  
     }  
     packageParams.put(parameter, v);  
     }  
        
     // 账号信息  
     String key = WeixinPayUtil.key; // key  
     //判断签名是否正确  
     if(WeixinPayUtil.isTenpaySign("UTF-8", packageParams)) {  
       //------------------------------  
       //处理业务开始  
       //------------------------------  
       String resXml = "";  
       if("SUCCESS".equals((String)packageParams.get("result_code"))){  
       Map<String, Object> newMap = new HashMap<String, Object>();
       // 这里是支付成功  
       //执行自己的业务逻辑  
       String out_trade_no = packageParams.get("out_trade_no").toString();     //系统订单
       String total_fee = packageParams.get("total_fee").toString();  //金额
       String transaction_id = packageParams.get("transaction_id").toString(); //微信订单
       Double price = Double.valueOf(total_fee)/100;
       
       String attach = packageParams.get("attach").toString();
       
       int jsontype = getJSONType(attach);
       JSONObject json = new JSONObject();
       JSONArray arr = new JSONArray();
       if(jsontype==0){
        json = new JSONObject(attach);
Integer type = (Integer) json.get("type");
Integer uid = (Integer) json.get("uid");
Integer mid = (Integer) json.get("mid");
User user = dao.getUniqueResult(User.class, "id", uid); // 查询到人员信息


newMap.put("out_trade_no", out_trade_no);
newMap.put("total_fee", price);
newMap.put("transaction_id", transaction_id);
newMap.put("uid", uid);
newMap.put("type", type);
newMap.put("mid", mid);

if(type==1){ //广告
   
    dao.updateEntity(Advert.class, new String[]{"price","paytime","status","transaction_id"},
    new Object[]{price,TimeUtil.getUnixTimestamp(),1,transaction_id},
    new String[]{"id"}, new Object[]{mid});
    this.createOrder(newMap);
     
       }else if(type==2){  //单品
Integer goodnum = (Integer) json.get("goodnum");

//Double price = Double.valueOf(total_fee)/100;

//订单表支付状态变更
dao.updateEntity(Order.class, new String[]{"status","paytype","paytime","transaction_id","total_fee","paykind"}, 
new Object[]{1,1,TimeUtil.getUnixTimestamp(),transaction_id,price,"2"},
new String[]{"id","uid"}, new Object[]{mid,uid});
//商品表 销量、总量变更
Order order = (Order) dao.getEntity(Order.class,mid);;
Good good = (Good) dao.getEntity(Good.class,order.getGid());
//取到商品销售 总量
int sales = good.getSales();
int total = good.getTotal();
//取到商品数量
dao.updateEntity(Good.class, new String[]{"sales","total"}, new Object[]{sales+goodnum,total-goodnum},
new String[]{"id"}, new Object[]{good.getId()});

       }else if(type==3){ //购物车
   
       }else if(type==4){ //头条
    //保存头条信息
    TopAdvert top = new TopAdvert();
    top.setAid(mid);
    top.setPaymoney(price);
    top.setPaytime(TimeUtil.getUnixTimestamp());
    top.setTransaction_id(transaction_id);
    Integer tid = dao.saveEntityRetrunId(top);
    newMap.put("tid", tid);
    this.createOrder(newMap);
       }
//防止seesion中user失效 重新塞入
      HttpSession session = request.getSession(); 
      session.setAttribute("Uid", uid); 
      session.setAttribute("User",user);
       }else if(jsontype==1){ //购物车  购物车的类别为jsonarray
        int uid_ = 0;
        attach = attach.replaceAll("'", "\"");
      arr = new JSONArray(attach);
    for(int i=0;i<arr.length();i++){
    JSONObject obj = arr.getJSONObject(i);
    int mid = obj.getInt("mid");
    int uid = obj.getInt("uid");
    uid_ = uid;
    //订单表支付状态变更
dao.updateEntity(Order.class, new String[]{"status","paytype","paytime","transaction_id","total_fee","paykind"}, 
new Object[]{1,1,TimeUtil.getUnixTimestamp(),transaction_id,price,"3"},
new String[]{"id","uid"}, new Object[]{mid,uid});
//商品表 销量、总量变更
Order order = (Order) dao.getEntity(Order.class,mid);;
Good good = (Good) dao.getEntity(Good.class,order.getGid());
//取到商品销售 总量
int sales = good.getSales();
int total = good.getTotal();
int goodnum = order.getGoodnum();
//取到商品数量
dao.updateEntity(Good.class, new String[]{"sales","total"}, new Object[]{sales+goodnum,total-goodnum},
new String[]{"id"}, new Object[]{good.getId()});
    }
        //防止seesion中user失效 重新塞入
      HttpSession session = request.getSession(); 
      session.setAttribute("Uid", uid_); 
      User user = dao.getUniqueResult(User.class, "id", uid_); // 查询到人员信息
      session.setAttribute("User",user);
       }
       
       
       
       
       
   //执行自己的业务逻辑  
   //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.  
   resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"  
                 + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";                   
       } else {   
       resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"  
                      + "<return_msg><![CDATA[付款失败]]></return_msg>" + "</xml> ";  
       }  
       //------------------------------  
       //处理业务完毕  
       //------------------------------  
       BufferedOutputStream out = new BufferedOutputStream(  
                  response.getOutputStream());  
       out.write(resXml.getBytes());  
       out.flush();  
       out.close();  
        } else{  
       
        }       
  }  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值