微信公众号支付开发(java)

1.微信支付也有很多种方式,今天我们所介绍的是公众号支付这种方式。这也是本人第一次进行微信开发,可能有一些地方介绍不到位,请见谅。

2.开发前准备,我们先去https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1将一些工具下载下来,其实也可以自己写,只不过会有些麻烦,我们可以直接下载来使用。选择

Java版本【微信支付】API对应的SDK和调用示例的工具下载。

3.生成超链接跳转到我们的充值页面。

4.前台调用js进行异步发起下单请求。

5.后台接收到前台发起的请求,获取前台发过来的信息,将信息进行封装进行统一下单,需要加入到Map的信息有:appid(公众账号ID)、mch_id(商户号)、body(商品描述)、device_info(设备号)、out_trade_no(商户订单号)、fee_type(标价币种)、total_fee(标价金额)、spbill_create_ip(终端IP)、notify_url(通知地址)、trade_type(交易类型)、openid(用户标识)、nonce_str(随机字符串);也可以加入其它的,可以参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1,其中的请求参数,其中必填是的属于必须的,其它的可以视情况而定。调用wxpay.unifiedOrder(map)生成订单。

6.获取订单中的appId、timeStamp、nonceStr、package(值为prepay_id:prepay_id就是指下单时生成的订单id)、signType的值调用generateSignature(Map)生成签名,将生成的签名存放到五生成的订单中使用json的格式返回到前台中,此时前台可以获取后台传过来的值,接着前台调用callpay();在onBridgeReady()中,需要获取的值有:appId、timeStamp、nonceStr、package、signType、paySign(可能少一个都有可能回调不到微信输入密码页面),当出现微信密码输入页面的时候,我们就成功了一大半了。

7.支付成功后,接着开始处理后台回调,也就是notify_url里面的地址。注意:接收微信支付异步通知回调地址也是有要求:通知url必须为直接可访问的url,不能携带参数。同时,我们可以获取支付结果,我们们使用里面的参数生成一个本地签名,同时和结果集里面的签名比较,一样我们就可以进行我们的业务处理。处理完成后我们还要给通知一个回应,不然它会每隔一段时间它会再请求。

8.开发结束。

代码如下:

(1)、充值页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
    <meta name="format-detection" content="telephone=no">
    <title>微信充值</title>

</head>
<body>
<div class="vbox">
    <div class="content">
        <ul class="rechange-choose clearfix" id="rechange-choose">
            <li class="active"><button class="btn btn-hollow-primary btn-w-per-100" data-value="30"><span class="money">30</span>元</button></li>
            <li><button class="btn btn-hollow-primary btn-w-per-100" data-value="50"><span class="money">50</span>元</button></li>
            <li><button class="btn btn-hollow-primary btn-w-per-100" data-value="100"><span class="money">100</span>元</button></li>
            <li><button class="btn btn-hollow-primary btn-w-per-100" data-value="200"><span class="money">200</span>元</button></li>
           
        </ul>
        <div class="rechange-btn">
            <button id="rechangeBtn" class="btn btn-primary btn-w-per-100">立即充值</button>
        </div>
    </div>
</div>
</body>

<script>
(function () {
    var prepay_id,
        paySign,
        appId,
        timeStamp,
        nonceStr,
        packageStr,
        signType,
        orderNo;

    function onBridgeReady(){
        WeixinJSBridge.invoke(
            'getBrandWCPayRequest', {
                "appId"     : appId,     //公众号名称,由商户传入
                "timeStamp" : timeStamp, //时间戳数
                "nonceStr"  : nonceStr , //随机串
                "package":"prepay_id="+prepay_id,
                "signType"  : 'MD5',  //微信签名方式:
                "paySign"   : paySign    //微信签名
            },
            function(res){
                var last = JSON.stringify(res); //将JSON对象转化为JSON字符
                if(res.err_msg === "get_brand_wcpay_request:ok" ) {
                   
                }
                if (res.err_msg ===     "get_brand_wcpay_request:cancel") {
                    alert("交易取消");
                }
                if (res.err_msg === "get_brand_wcpay_request:fail") {
                    alert("支付失败");
                }
            }
        );
    }
    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();
        }
    }
    /*点击支付*/
    $('#rechangeBtn').on('click', function () {
        payPublic();
    });
    function payPublic() {
        var url = "支付处理地址";
      
        Http.post(url, {
            type : "add",
            oppendId : '${oppendId!}',
            total_fee:currentMoney
        }, function (data) {
            
                prepay_id = data.prepay_id;
                paySign = data.sign;
                appId = data.appid;
                timeStamp = data.timeStamp;
                nonceStr = data.nonce_str;
              
              
                callpay();
            
           
        }, function (err) {

        });
    }
}());

</script>
</html>

(2)、充值处理

protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        String type = request.getParameter("type");
        String oppendId = request.getParameter("oppendId");

        if (type != null) {
            if (type.equals("toadd")) {
   
                return new ModelAndView("weixin/pay/add").addObject("oppendId",oppendId);
            } else if (type.equals("add")) {
                 /**
                 *  公众号支付  下单
                 */
                 WXPayConfigImpl config =WXPayConfigImpl.getInstance();
                 WXPay  wxpay = new WXPay(config);
                    String totalFree=request.getParameter("total_fee");  
                    String out_trade_no = UtilPramKey.getPriamKey("P");//订单号
                    
                    double free =Double.valueOf(totalFree);
                    
                    free=free*100;
                    totalFree=(int)free+"";
                    HashMap<String, String> data = new HashMap<String, String>();
                    data.put("appid",config.getAppID());
                    data.put("mch_id",config.getMchID());
                    
                    data.put("body", "产品描述");
                    data.put("device_info", "WEB");
                    data.put("out_trade_no", out_trade_no);
                    data.put("fee_type", "CNY");
                    data.put("total_fee", totalFree);
                    data.put("spbill_create_ip", "123.12.12.123");
                    data.put("notify_url", "异步通知地址");
                    data.put("trade_type", "JSAPI");
                    data.put("openid", oppendId);
                    data.put("nonce_str", "随机数");//随机数
                    try {
                        Map<String, String> r = wxpay.unifiedOrder(data);
                        JSONObject js222 =new JSONObject(r);
                                            
                        Date d =new Date();
           if(r.get("return_code").equals("SUCCESS") && r.get("result_code").equals("SUCCESS")){
    
                  //业务处理模块点                    
                        
           }else{
                  //下单失败
                        
              }
                           
                        String timestr=  d.getTime()/1000+"";
                        r.put("timeStamp", timestr);
                        
                        String prepay_id=r.get("prepay_id");
                        Map<String, String> payMap = new HashMap<String, String>(); 
                        payMap.put("appId", config.getAppID()); 
                        payMap.put("timeStamp", timestr); 
                        payMap.put("nonceStr", r.get("nonce_str")); 
                        payMap.put("package", "prepay_id="+prepay_id); 
                        payMap.put("signType", "MD5"); 

                        String paySign = WXPayUtil.generateSignature(payMap, config.getKey()); 
                        r.put("sign", paySign);
                        
                        JSONObject js =new JSONObject(r);              
                        writeStringToResponse(js.toString(),response);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
          }

            return null; 
    }
    

 (3)、异步回调处理

protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        String re = getNotify(request);
        writeStringToResponse(re, response);
        return null;
    }

    public String getNotify(HttpServletRequest request) {
        String result = null;
        String inlength;
        String notifyXml = "";
        try {
            while ((inlength = request.getReader().readLine()) != null) {
                notifyXml += inlength;
            }
        } catch (IOException e) {
        //获取XML错误
}if (StringUtils.isEmpty(notifyXml)) {
       //xml为空 }
try { Map<String, String> map = WXPayUtil.xmlToMap(notifyXml); String appid=map.get("appid"); String bank_type=map.get("bank_type"); String cash_fee=map.get("cash_fee"); String device_info=map.get("device_info"); String fee_type=map.get("fee_type"); String is_subscribe=map.get("is_subscribe"); String mch_id=map.get("mch_id"); String nonce_str=map.get("nonce_str"); String openid=map.get("openid"); String out_trade_no=map.get("out_trade_no"); String result_code = map.get("result_code"); String return_code = map.get("return_code"); String sign=map.get("sign"); String time_end=map.get("time_end"); String total_fee=map.get("total_fee"); String trade_type=map.get("trade_type"); String transaction_id=map.get("transaction_id"); Map<String, String> date=new HashMap<>(); date.put("appid", appid); date.put("bank_type", bank_type); date.put("cash_fee", cash_fee); date.put("device_info", device_info); date.put("fee_type", fee_type); date.put("is_subscribe", is_subscribe); date.put("mch_id", mch_id); date.put("nonce_str", nonce_str); date.put("openid", openid); date.put("out_trade_no", out_trade_no); date.put("result_code", result_code); date.put("return_code", return_code); date.put("time_end", time_end); date.put("total_fee", total_fee); date.put("trade_type", trade_type); date.put("transaction_id", transaction_id); WXPayConfigImpl config = WXPayConfigImpl.getInstance(); String localSign=WXPayUtil.generateSignature(date, config.getKey()); if(localSign.equals(sign)){if (result_code.equals("SUCCESS") && return_code.equals("SUCCESS")) { //业务模块处理点 }else {           //签名失败 } } catch (Exception e) { //转化XML错误 e.printStackTrace(); } //正确的结果要分上面几个不一样返回,不能这样只返回一个 result = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "; return result;
}

 (如若哪里存在漏洞请多多提出来,非常感谢)

 



posted @ 2017-10-23 15:49  静喧  阅读(5052)  评论(0编辑  收藏  举报