實(shí)戰(zhàn):第八章:支付寶Native,JSAPI支付與微信Native,JSAPI,MWEB支付實(shí)現(xiàn)

首先是H5的支付,先看控制層的代碼

        @Autowired
        AliPayH5Bean aliPayH5Bean;
     
        @Autowired
        WxPayH5MWEB wxPayH5MWEB;
     
        @Autowired
        WxPayH5JSAPI wxPayH5JSAPI;
     
        @LoginRequired(isNeedLogin = true)
        @ApiOperation("H5去支付,支付主接口,用于控制支付流程")
        @GetMapping(value = "/h5/pay" ,produces = { "application/json;charset=UTF-8" })
        @ResponseBody
        public Object wxPrepay(String orderSn,BigDecimal totalAmount,String code,String channelId){
            //正常開(kāi)發(fā)情況下是根據(jù)用戶(hù)登錄的id和訂單編號(hào)查詢(xún)?cè)撚唵问欠駷榈卿浻脩?hù)的訂單并獲取訂單信息,訂單價(jià)格是不會(huì)作為參數(shù)傳入的,這里只是演示支付不做那么麻煩
            String result = "";
            if(PayConstant.CHANNELALIH5.equals(channelId)){
                Map<String, Object> wxMap = aliPayH5Bean.getPayMap();
                wxMap.put("out_trade_no", orderSn);
                wxMap.put("total_fee", "1".equals(aliPayH5Bean.getPayMap().get("is_real_pay")) ? totalAmount : 0.01);
                //手機(jī)網(wǎng)站支付,調(diào)用支付寶(網(wǎng)頁(yè)類(lèi)支付接口),這里沒(méi)有寫(xiě)(系統(tǒng)調(diào)用類(lèi)支付接口)
                result = PayUtils.alipayh5(wxMap);
                if (StringUtils.isEmpty(result)) {
                    throw new AppException("憑證生成失敗!");
                }
                return result;
            }else if(PayConstant.CHANNELWXMWEB.equals(channelId)){
                Map<String, Object> wxMap = wxPayH5MWEB.getPayMap();
                wxMap.put("out_trade_no", orderSn);
                wxMap.put("total_fee", "1".equals(wxPayH5MWEB.getPayMap().get("is_real_pay")) ? MoneyUtil.convertYuanToFen(String.valueOf(totalAmount)): 1);
                //MWEB支付是微信之外的瀏覽器,訪問(wèn)手機(jī)網(wǎng)站時(shí)使用的支付手段
                Map<String, String> map = PayUtils.wxh5MWEBPay(wxMap);
                if (map == null) {
                    throw new AppException("支付憑證生成失敗!");
                }
                return map;
            }else if(PayConstant.CHANNELWXJSAPI.equals(channelId)){
                Map<String, Object> wxMap = wxPayH5JSAPI.getPayMap();
                wxMap.put("out_trade_no", orderSn);
                wxMap.put("total_fee", "1".equals(wxPayH5MWEB.getPayMap().get("is_real_pay")) ? MoneyUtil.convertYuanToFen(String.valueOf(totalAmount)): 1);
                //JSAPI支付需要微信授權(quán),前端引導(dǎo)用戶(hù)到指定頁(yè)面獲取到微信給code,code五分鐘內(nèi)只能用一次,
                // 后端根據(jù)code獲取openid,微信公眾平臺(tái)配置時(shí)需要配置支付目錄與授權(quán)目錄要注意域名是否與后臺(tái)配置一致
                String openId = PayUtils.getOpenId(code, wxMap);
                wxMap.put("openId",openId);
                Map<String, String> map = PayUtils.wxJSAPIPay(wxMap);
                if (map == null) {
                    throw new AppException("支付憑證生成失敗!");
                }
                return map;
            }
            return null;
        }

以上三種支付方式都是需要和前端交互的網(wǎng)頁(yè)類(lèi)支付接口

然后看看H5的配置類(lèi):
 

        @Configuration
        @PropertySource("classpath:H5Pay.properties")
        public class H5PayConfig {
            //是否真實(shí)支付
            @Value("${is_real_pay}")
            private String is_real_pay;
            //支付寶H5
            @Value("${alipay_h5_app_id}")
            private String alipay_h5_app_id;
            @Value("${alipay_h5_private_key}")
            private String alipay_h5_private_key;
            @Value("${alipay_h5_public_key}")
            private String alipay_h5_public_key;
            @Value("${alipay_h5_notify_url}")
            private String alipay_h5_notify_url;
            @Value("${aplipay_h5_return_url}")
            private String aplipay_h5_return_url;
            //微信H5
            @Value("${wx_h5_appid}")
            private String wx_h5_appid;
            @Value("${wx_h5_appsecret}")
            private String wx_h5_appsecret;
            @Value("${wx_h5_partnerkey}")
            private String wx_h5_partnerkey;
            @Value("${wx_h5_mch_id}")
            private String wx_h5_mch_id;
            //微信H5交易類(lèi)型是trade_type=MWEB
            @Value("${wx_mweb_notify_url}")
            private String wx_mweb_notify_url;
            @Value("${wx_mweb_return_url_h5}")
            private String wx_mweb_return_url_h5;
            //微信H5交易類(lèi)型是trade_type=JSAPI
            @Value("${wx_jsapi_notify_url}")
            private String wx_jsapi_notify_url;
            @Value("${wx_jsapi_return_url_h5}")
            private String wx_jsapi_return_url_h5;
            /**
             * 微信H5支付,微信瀏覽器
             * @return
             */
            @Bean
            public WxPayH5JSAPI getWxPayH5JSAPI(){
                WxPayH5JSAPI wxPayH5JSAPI = new WxPayH5JSAPI();
                Map<String, String>  map = new HashMap<>();
                map.put("wx_h5_appid", wx_h5_appid);
                map.put("wx_h5_appsecret", wx_h5_appsecret);
                map.put("wx_h5_partnerkey", wx_h5_partnerkey);
                map.put("wx_h5_mch_id", wx_h5_mch_id);
                map.put("wx_jsapi_notify_url", wx_jsapi_notify_url);
                map.put("wx_jsapi_return_url_h5",wx_jsapi_return_url_h5);
                wxPayH5JSAPI.setPayMap(map);
                return wxPayH5JSAPI;
            }
        
            /**
             * 微信H5支付,非微信瀏覽器
             * @return
             */
            @Bean
            public WxPayH5MWEB getWxPayH5MWEB(){
                WxPayH5MWEB wxPayH5Bean = new WxPayH5MWEB();
                Map<String, String>  map = new HashMap<>();
                map.put("wx_h5_appid", wx_h5_appid);
                map.put("wx_h5_appsecret", wx_h5_appsecret);
                map.put("wx_h5_partnerkey", wx_h5_partnerkey);
                map.put("wx_h5_mch_id", wx_h5_mch_id);
                map.put("wx_mweb_notify_url", wx_mweb_notify_url);
                map.put("wx_mweb_return_url_h5",wx_mweb_return_url_h5);
                wxPayH5Bean.setPayMap(map);
                return wxPayH5Bean;
            }
        
            /**
             * 支付寶H5支付,非微信瀏覽器,微信不允許調(diào)用支付寶的支付接口
             * @return
             */
            @Bean
            public AliPayH5Bean getAlipayH5Info(){
                AliPayH5Bean payBean = new AliPayH5Bean();
                Map<String, String>  map = new HashMap<>();
                map.put("alipay_app_id", alipay_h5_app_id);
                map.put("alipay_private_key", alipay_h5_private_key);
                map.put("alipay_public_key", alipay_h5_public_key);
                map.put("notify_url", alipay_h5_notify_url);
                map.put("return_url", aplipay_h5_return_url);
                map.put("is_real_pay", is_real_pay);
                payBean.setPayMap(map);
                return payBean;
            }
        }

然后看看自定義實(shí)體類(lèi):

        public class AliPayH5Bean {
     
            private Map payMap;
        
            public Map getPayMap() {
                return payMap;
            }
        
            public void setPayMap(Map payMap) {
                this.payMap = payMap;
            }
        }
     
        public class WxPayH5MWEB {
        
            private Map payMap;
        
            public Map getPayMap() {
                return payMap;
            }
        
            public void setPayMap(Map payMap) {
                this.payMap = payMap;
            }
        }
     
        public class WxPayH5JSAPI {
        
            private Map payMap;
        
            public Map getPayMap() {
                return payMap;
            }
        
            public void setPayMap(Map payMap) {
                this.payMap = payMap;
            }
        }

然后是pc掃碼的支付:

        @Autowired
        WxClient wxClient;
     
        @LoginRequired(isNeedLogin = true)
        @ApiOperation("pc端去支付,支付主接口,用于控制整體支付流程")
        @RequestMapping(value = "/alipay/submit", method = RequestMethod.GET)
        @ResponseBody
        public String goToPay(String orderSn, BigDecimal totalAmount, Integer channelId) {
            //根據(jù)訂單創(chuàng)建支付信息并保存,這里真實(shí)開(kāi)發(fā)不會(huì)使用金額傳參,容易被篡改價(jià)格,但是為了方便暫時(shí)先這樣寫(xiě)
            Map<String, String> requestMap = savePayInfo(orderSn, totalAmount);
            String form="";
            if(PayConstant.CHANNELALINATIVE.equals(channelId)){
                //阿里支付
                form = generateForm(requestMap, form);
            }else if (PayConstant.CHANNELWXNATIVE.equals(channelId)){
                //微信支付
                Map map = wxClient.getMap();
                map.put("out_trade_no",orderSn);
                map.put("total_fee",totalAmount);
                String code_url = PayUtils.wxPcPay(map);
                String fileName = TimeUtils.getCurrentTime("yyyyMMddHHmmss") + ".png";
                String img_path = String.valueOf(map.get("img_path"));
                //說(shuō)明:商戶(hù)后臺(tái)系統(tǒng)先調(diào)用微信支付的統(tǒng)一下單接口,微信后臺(tái)系統(tǒng)返回鏈接參數(shù)code_url,
                // 商戶(hù)后臺(tái)系統(tǒng)將code_url值生成二維碼圖片,用戶(hù)使用微信客戶(hù)端掃碼后發(fā)起支付。
                // 注意:code_url有效期為2小時(shí),過(guò)期后掃碼不能再發(fā)起支付。
                //將code_url的值生成二維碼圖片上傳到七牛云,這里就不寫(xiě)上傳七牛云的代碼了,
                // img_path:保存二維碼的基礎(chǔ)全路徑+"/qrcode/"+fileName:保存二維碼的圖片名稱(chēng)+code_url:保存到二維碼里的內(nèi)容
                form = img_path + "/qrcode/" + fileName;
            }else{
                //其他第三方支付(未接入)
     
            }
            //發(fā)送檢查支付結(jié)果的消息隊(duì)列(這里只檢查了阿里的支付)
            payService.sendingPayMQ(orderSn,6,channelId);
            return form;
        }
     
        
        /**
         * 支付寶pc端掃碼支付沒(méi)有寫(xiě)到工具類(lèi)里面了,支付寶生成表單
         * @param requestMap
         * @param form
         * @return
         */
        private String generateForm(Map<String, String> requestMap, String form) {
            //創(chuàng)建PC場(chǎng)景下單并支付請(qǐng)求對(duì)象
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//創(chuàng)建API對(duì)應(yīng)的request
            //設(shè)置同步返回地址,HTTP/HTTPS開(kāi)頭字符串
            alipayRequest.setReturnUrl(PCPayConfig.alipay_pc_return_url);
            //支付寶服務(wù)器主動(dòng)通知商戶(hù)服務(wù)器里指定的頁(yè)面http/https路徑。
            alipayRequest.setNotifyUrl(PCPayConfig.alipay_pc_notify_url);//在公共參數(shù)中設(shè)置回跳和通知地址
            //填充業(yè)務(wù)參數(shù)
            alipayRequest.setBizContent(JSON.toJSONString(requestMap));
            try {
                //調(diào)用SDK生成表單
                form = alipayClient.pageExecute(alipayRequest).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            return form;
        }

看看自定義的實(shí)體類(lèi):

    public class WxClient {
     
        private Map map;
     
        public Map getMap() {
            return map;
        }
     
        public void setMap(Map map) {
            this.map = map;
        }
    }

然后看看pc的配置類(lèi):

    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.javaliao.portal.bean.WxClient;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import java.util.HashMap;
    import java.util.Map;
     
    @Configuration
    @PropertySource("classpath:PCPay.properties")
    public class PCPayConfig {
     
        //阿里pc端
        @Value("${alipay_pc_url}")
        private String alipay_pc_url;
        @Value("${alipay_pc_public_key}")
        public static  String alipay_pc_public_key;
        @Value("${alipay_pc_private_key}")
        private String alipay_pc_private_key;
        @Value("${alipay_pc_app_id}")
        private String alipay_pc_app_id;
        @Value("${alipay_pc_notify_url}")
        public static String alipay_pc_notify_url;
        @Value("${alipay_pc_return_url}")
        public static  String alipay_pc_return_url;
        //微信pc端
        @Value("${wx_pc_appid}")
        public static String wx_pc_appid;
        @Value("${wx_pc_url}")
        public static String wx_pc_url;
        @Value("${wx_pc_appsecret}")
        public static String wx_pc_appsecret;
        @Value("${wx_pc_partnerkey}")
        public static String wx_pc_partnerkey;
        @Value("${wx_pc_mch_id}")
        public static String wx_pc_mch_id;
        @Value("${wx_pc_notify_url}")
        public static String wx_pc_notify_url;
        @Value("${img_path}")
        public static String img_path;
        public final static String format="json";
        public final static String charset="utf-8";
        public final static String sign_type="RSA2";
     
        @Bean
        public WxClient wxClient(){
            WxClient wxClient = new WxClient();
            Map<String , Object> map = new HashMap<>();
            map.put("wx_pc_appid",wx_pc_appid);
            map.put("wx_pc_appsecret",wx_pc_appsecret);
            map.put("wx_pc_partnerkey",wx_pc_partnerkey);
            map.put("wx_pc_mch_id",wx_pc_mch_id);
            map.put("wx_pc_notify_url",wx_pc_notify_url);
            map.put("wx_pc_url",wx_pc_url);
            map.put("img_path",img_path);
            wxClient.setMap(map);
            return wxClient;
        }
     
        /**
         * pc端支付寶支付Native
         * @return
         */
        @Bean
        public AlipayClient alipayClient(){
            return new DefaultAlipayClient(alipay_pc_url,alipay_pc_app_id,alipay_pc_private_key,format,charset,alipay_pc_public_key,sign_type);
        }
     
     
    }

支付的工具類(lèi):

        package com.javaliao.portal.util;
        import com.alibaba.fastjson.JSON;
        import com.alipay.api.AlipayApiException;
        import com.alipay.api.AlipayClient;
        import com.alipay.api.DefaultAlipayClient;
        import com.alipay.api.domain.AlipayTradeAppPayModel;
        import com.alipay.api.domain.AlipayTradeWapPayModel;
        import com.alipay.api.internal.util.AlipaySignature;
        import com.alipay.api.request.*;
        import com.alipay.api.response.AlipayTradeAppPayResponse;
        import com.alipay.api.response.AlipayTradeRefundResponse;
        import com.javaliao.portal.bean.WXPubBean;
        import com.javaliao.portal.log4j.BaseLogger;
        import org.apache.http.HttpResponse;
        import org.apache.http.client.methods.HttpPost;
        import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
        import org.apache.http.conn.ssl.SSLContexts;
        import org.apache.http.entity.StringEntity;
        import org.apache.http.impl.client.CloseableHttpClient;
        import org.apache.http.impl.client.HttpClients;
        import org.apache.http.util.EntityUtils;
        import org.w3c.dom.Document;
        import org.w3c.dom.Node;
        import org.w3c.dom.NodeList;
        import javax.net.ssl.SSLContext;
        import javax.xml.parsers.DocumentBuilder;
        import java.io.ByteArrayInputStream;
        import java.io.File;
        import java.io.FileInputStream;
        import java.io.InputStream;
        import java.net.URLEncoder;
        import java.security.KeyStore;
        import java.util.HashMap;
        import java.util.Map;
        import java.util.SortedMap;
        import java.util.TreeMap;
        
        public class PayUtils {
     
            /**
             * 支付寶H5支付
             * @param map
             * @return
             */
            public static String alipayh5(Map<String, Object> map) {
                AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",map.get("alipay_app_id").toString(), map.get("alipay_private_key").toString(), "json", "utf-8", map.get("alipay_public_key").toString(),"RSA2");
                AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
                model.setOutTradeNo(map.get("out_trade_no").toString());
                model.setSubject("委托檢測(cè)服務(wù)");
                model.setTotalAmount(map.get("total_fee").toString());
                model.setBody("委托檢測(cè)服務(wù)");
                model.setTimeoutExpress("2m");
                model.setProductCode("FAST_INSTANT_TRADE_PAY");
                // 創(chuàng)建手機(jī)網(wǎng)站API對(duì)應(yīng)的request:AlipayTradeWapPayRequest;pc端的是AlipayTradePagePayRequest
                AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
                alipayRequest.setReturnUrl(map.get("return_url").toString());
                alipayRequest.setNotifyUrl(map.get("notify_url").toString());
                alipayRequest.setBizModel(model);
                // 調(diào)用SDK生成表單
                String form = null;
                try {
                    form = alipayClient.pageExecute(alipayRequest).getBody();
                    BaseLogger.info("支付寶支付生成同步響應(yīng)報(bào)文: " + form);
                    /*直接將完整的表單html輸出到頁(yè)面。說(shuō)明:手機(jī)網(wǎng)站支付alipay.trade.wap.pay:
                    對(duì)于頁(yè)面跳轉(zhuǎn)類(lèi)API,SDK不會(huì)也無(wú)法像系統(tǒng)調(diào)用類(lèi)API一樣自動(dòng)請(qǐng)求支付寶并獲得結(jié)果,
                     而是在接受request請(qǐng)求對(duì)象后,為開(kāi)發(fā)者生成前臺(tái)頁(yè)面請(qǐng)求需要的完整form表單的html(包含自動(dòng)提交腳本),
                     商戶(hù)直接將這個(gè)表單的String輸出到http response中即可。*/
                    return form;
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                }
                return null;
            }
        
            /**
             * 微信JSAPI支付
             * @param map
             * @return
             */
            public static Map<String, String> wxJSAPIPay(Map<String, Object> map) {
                SortedMap<String, String> paraMap = new TreeMap<String, String>();
                String random = NumberUtils.createRandom(false, 32);
                paraMap.put("appid", String.valueOf(map.get("wx_h5_appid")));// "wxe5703c4e06a09cc8";
                paraMap.put("attach", StringUtils.isNull(String.valueOf(map.get("attach"))) ? "商品購(gòu)買(mǎi)" : map.get("attach") + "");
                paraMap.put("body", StringUtils.isNull(String.valueOf(map.get("body"))) ? "商品購(gòu)買(mǎi)" : map.get("body") + "");
                paraMap.put("mch_id", String.valueOf(map.get("wx_h5_mch_id")));
                paraMap.put("nonce_str", random);
                paraMap.put("openid", String.valueOf(map.get("openId")));
                paraMap.put("out_trade_no", String.valueOf(map.get("out_trade_no")));
                paraMap.put("spbill_create_ip", "172.168.0.1");//終端ip,在APP和網(wǎng)頁(yè)支付提交用戶(hù)端ip,Native支付填調(diào)用微信支付API的機(jī)器IP。
                paraMap.put("total_fee", String.valueOf(map.get("total_fee")));
                paraMap.put("trade_type", "JSAPI");
                paraMap.put("notify_url", map.get("wx_jsapi_notify_url") + "");
                paraMap.put("sign_type", "MD5");
                // 簽名
                RequestHandler reqHandler = new RequestHandler(null, null);
                reqHandler.init(String.valueOf(map.get("wx_h5_appid")), String.valueOf(map.get("wx_h5_appsecret")),
                        String.valueOf(map.get("wx_h5_partnerkey")));
                paraMap.put("sign", reqHandler.createSign(paraMap));
                // 統(tǒng)一下單
                String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
                String xml = WXUtils.ArrayToXml(paraMap);
                String prepay_id = "";
                try {
                    // 提交
                    prepay_id = getPayPubNo(url, xml);
                    if (prepay_id.equals("")) {
                        return null;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println(e.getMessage());
                    return null;
                }
                SortedMap<String, String> packageParams = new TreeMap<String, String>();
                // 需要再次簽名,這里要加上時(shí)間戳
                String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
                String prepay_id2 = "prepay_id=" + prepay_id;
                String packages = prepay_id2;
                packageParams.put("appId", String.valueOf(map.get("wx_h5_appid")));
                packageParams.put("timeStamp", timestamp);
                packageParams.put("nonceStr", random);
                packageParams.put("package", packages);
                packageParams.put("signType", "MD5");
                String finalsign = reqHandler.createSign(packageParams);
                packageParams.put("paySign", finalsign);
                return packageParams;
            }
        
            /**
             * 根據(jù)code獲取微信openid
             * @param code
             * @param map
             * @return
             */
            public static String getOpenId(String code,Map<String, Object> map)  {
                WXPubBean wxUserInfo = WXUtils.getWXUserInfo((String) map.get("wx_pub_appid"), (String) map.get("wx_pub_appsecret"), code);
                BaseLogger.info("獲取微信用戶(hù)授權(quán)信息:"+wxUserInfo.toString());
                if(wxUserInfo != null){
                    return wxUserInfo.getOpenid();
                }
                return null;
            }
        
            /**
             * 提交url給微信獲取響應(yīng)信息
             * @param url
             * @param xml
             * @return
             */
            private static String getPayPubNo(String url, String xml) {
                String prepay_id = "";
                try {
                    String result = HttpUtils.getDataByJson(url, xml);
                    if (result.indexOf("FAIL") != -1) {
                        return prepay_id;
                    }
                    Document document = XmlUtils.getDocumentByXml(result);
                    prepay_id = XmlUtils.getValueByTagName(document, "prepay_id");
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("------------------------------" + e.getMessage());
                }
                return prepay_id;
            }
        
            /**
             * 微信h5mweb支付
             * @param map
             * @return
             */
            public static Map<String, String> wxh5MWEBPay(Map<String, Object> map) {
                // 設(shè)置微信原生支付所需參數(shù)
                // 封裝
                SortedMap<String, String> paraMap = new TreeMap<String, String>();
                paraMap.put("appid", String.valueOf(map.get("wx_h5_appid")));
                paraMap.put("attach", StringUtils.isNull(map.get("attach") + "") ? "商品購(gòu)買(mǎi)" : map.get("attach") + "");
                paraMap.put("body", StringUtils.isNull(map.get("body") + "") ? "商品購(gòu)買(mǎi)" : map.get("body") + "");
                paraMap.put("mch_id", String.valueOf(map.get("wx_h5_mch_id")));
                paraMap.put("nonce_str", NumberUtils.createRandom(false, 32));
                paraMap.put("out_trade_no", String.valueOf(map.get("out_trade_no")));
                paraMap.put("spbill_create_ip", "172.168.0.1");
                paraMap.put("total_fee", String.valueOf(map.get("total_fee")));
                paraMap.put("trade_type", "MWEB");
                paraMap.put("notify_url", String.valueOf(map.get("wx_mweb_notify_url")));
                paraMap.put("sign_type", "MD5");
                // 簽名
                RequestHandler reqHandler = new RequestHandler(null, null);
                reqHandler.init(String.valueOf(map.get("wx_h5_appid")), String.valueOf(map.get("wx_h5_appsecret")), String.valueOf(map.get("wx_h5_partnerkey")));
                String sign = reqHandler.createSign(paraMap);
                paraMap.put("sign", sign);
                // 統(tǒng)一下單
                String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
                String xml = WXUtils.ArrayToXml(paraMap);
                String mweb_url = "";
                try {
                    // 提交
                    mweb_url = getPayNo(url, xml,map);
                    if (mweb_url.equals("")) {
                        return null;
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                    return null;
                }
                SortedMap<String, String> packageParams = new TreeMap<String, String>();
                //直接將拼接好的url發(fā)給前端即可,后端的支付代碼就沒(méi)啥事了
                packageParams.put("mweb_url", mweb_url);
                return packageParams;
            }
        
            /**
             * XML格式字符串轉(zhuǎn)換為Map
             * @param strXML XML字符串
             * @return XML數(shù)據(jù)轉(zhuǎn)換后的Map
             * @throws Exception
             */
            public static Map<String, String> xmlToMap(String strXML) throws Exception {
                try {
                    Map<String, String> data = new HashMap<String, String>();
                    DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
                    InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
                    Document doc = documentBuilder.parse(stream);
                    doc.getDocumentElement().normalize();
                    NodeList nodeList = doc.getDocumentElement().getChildNodes();
                    for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                        Node node = nodeList.item(idx);
                        if (node.getNodeType() == Node.ELEMENT_NODE) {
                            org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                            data.put(element.getNodeName(), element.getTextContent());
                        }
                    }
                    try {
                        stream.close();
                    } catch (Exception ex) {}
                    return data;
                } catch (Exception ex) {
                    throw ex;
                }
            }
        
            /**
             * 微信Native支付
             * @param map
             * @return
             */
            public static String wxPcPay(Map<String, Object> map) {
                // 設(shè)置微信原生支付所需參數(shù)
                String nonce_str = NumberUtils.createRandom(false, 32);
                // 封裝
                SortedMap<String, String> paraMap = new TreeMap<String, String>();
                paraMap.put("appid",String.valueOf(map.get("wx_pc_appid")));
                paraMap.put("attach",StringUtils.isNull(map.get("attach") + "") ? "商品購(gòu)買(mǎi)" : map.get("attach") + "");
                paraMap.put("body",StringUtils.isNull(map.get("body") + "") ? "商品購(gòu)買(mǎi)" : map.get("body") + "");
                paraMap.put("mch_id",String.valueOf(map.get("wx_pc_mch_id")));
                paraMap.put("nonce_str",nonce_str);
                paraMap.put("out_trade_no",String.valueOf(map.get("out_trade_no")));
                paraMap.put("spbill_create_ip","172.168.0.1");//用戶(hù)點(diǎn)擊微信支付的瀏覽器的IP
                paraMap.put("total_fee",String.valueOf(map.get("total_fee")));
                paraMap.put("trade_type","NATIVE");//掃碼支付類(lèi)型
                paraMap.put("notify_url",String.valueOf(map.get("wx_pc_notify_url")));
                paraMap.put("sign_type", "MD5");
                // 簽名
                RequestHandler reqHandler = new RequestHandler(null, null);
                reqHandler.init(String.valueOf(map.get("wx_pc_appid")), String.valueOf(map.get("wx_pc_appsecret")), String.valueOf(map.get("wx_pc_partnerkey")));
                String sign = reqHandler.createSign(paraMap);
                paraMap.put("sign", sign);
                // 統(tǒng)一下單
                String xml = WXUtils.ArrayToXml(paraMap);
                System.out.println(xml);
                String code_url = "";
                try {
                    String result = HttpUtils.getDataByJson(String.valueOf(map.get("wx_pc_url")), xml);
                    BaseLogger.info("微信支付生成同步響應(yīng)報(bào)文:" + result);
                    if (result.indexOf("FAIL") != -1) {
                        return null;
                    }
                    Document document = XmlUtils.getDocumentByXml(result);
                    code_url = XmlUtils.getValueByTagName(document, "code_url");
                    return code_url;
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("------------------------------" + e.getMessage());
                }
                return null;
            }
        
            public static String getPayNo(String url, String xmlParam,Map<String, Object> maps) {
                String prepay_id = "";
                try {
                    String result = HttpUtils.getDataByJson(url, xmlParam);
                    if (result.indexOf("FAIL") != -1) {
                        return prepay_id;
                    }else if(result.indexOf("SUCCESS") != -1){
                        //以下內(nèi)容是返回前端頁(yè)面的json數(shù)據(jù)
                        String mweb_url = "";//跳轉(zhuǎn)鏈接
                        Map<String, String> map = WXPayUtil.xmlToMap(result);
                        mweb_url =  map.get("mweb_url");
                        //支付完返回瀏覽器跳轉(zhuǎn)的地址,如跳到查看訂單頁(yè)面
                        String redirect_url = maps.get("wx_mweb_return_url_h5") +
                                "?payWay=1&orderId=" + maps.get("out_trade_no") + "";
                        String redirect_urlEncode =  URLEncoder.encode(redirect_url,"utf-8");//對(duì)上面地址urlencode
                        mweb_url = mweb_url + "&redirect_url=" + redirect_urlEncode;//拼接返回地址
                        return mweb_url;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("------------------------------" + e.getMessage());
                }
                return prepay_id;
            }
     
        }