zoukankan      html  css  js  c++  java
  • JAVA微信支付——微信公众号内支付 代码

    官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

    引入jdom-1.1.3.jar包

    HttpClientUtil.java

    package weixinpay;
    
    import org.apache.commons.lang.StringUtils;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.StatusLine;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.HttpResponseException;
    import org.apache.http.client.ResponseHandler;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.MalformedURLException;
    import java.net.URI;
    import java.net.URL;
    import java.net.URLConnection;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    
    public class HttpClientUtil {
        
        private static class SingletonHolder{
            private final static  HttpClientUtil INSTANCE=new HttpClientUtil();
        }   
        
        private HttpClientUtil(){}
        
        public static HttpClientUtil getInstance(){
            return SingletonHolder.INSTANCE;
        }
        
        public  String get(String url){
            CharsetHandler handler = new CharsetHandler("UTF-8");
             CloseableHttpClient client = null;
            try {
                HttpGet httpget = new HttpGet(new URI(url));
                HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
                client= httpClientBuilder.build();  
                client = (CloseableHttpClient) wrapClient(client);
                return client.execute(httpget, handler);
            } catch (Exception e) {
                //e.printStackTrace();
                return "";
            }finally {
                try {
                    if(client!=null){
                        client.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
           }
        }
        
        public static String post(String url, String params,String contentType)
           {
            
              //创建HttpClientBuilder  
              HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
              //HttpClient  
              CloseableHttpClient client = httpClientBuilder.build();
              client = (CloseableHttpClient) wrapClient(client);
              
              
               HttpPost post = new HttpPost(url);
               CloseableHttpResponse res = null;
               try
               {
                   StringEntity s = new StringEntity(params,"UTF-8");
                   if(StringUtils.isBlank(contentType)){
                       s.setContentType("application/json");
                   }
                   s.setContentType(contentType);
                   s.setContentEncoding("utf-8");
                   post.setEntity(s);
                   res = client.execute(post);
                   HttpEntity entity = res.getEntity();
                   return EntityUtils.toString(entity, "utf-8");
               }
               catch (Exception e)
               {
                   e.printStackTrace();
               } finally {
                    try {
                        res.close();
                        client.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
               }
            return "";
         }
        
        public static String post(String urlStr,String xmlInfo) {
            String line1 = "";  
            try {  
                URL url = new URL(urlStr);  
                URLConnection con = url.openConnection();  
                con.setDoOutput(true);  
                //con.setRequestProperty("Pragma:", "no-cache");  
                con.setRequestProperty("Cache-Control", "no-cache");  
                con.setRequestProperty("Content-Type", "text/xml"); 
            
                OutputStreamWriter out = new OutputStreamWriter(con  
                .getOutputStream());           
                out.write(new String(xmlInfo.getBytes("utf-8")));  
                out.flush();  
                out.close();  
                BufferedReader br = new BufferedReader(new InputStreamReader(con  
                .getInputStream()));  
                String line = "";  
                for (line = br.readLine(); line != null; line = br.readLine()) {  
                    line1+=line;  
                } 
                return new String(line1.getBytes(),"utf-8");
                } catch (MalformedURLException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }
                return null;  
            }
        
        private class CharsetHandler implements ResponseHandler<String> {
            private String charset;
    
            public CharsetHandler(String charset) {
                this.charset = charset;
            }
    
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() >= 300) {
                    throw new HttpResponseException(statusLine.getStatusCode(),
                            statusLine.getReasonPhrase());
                }
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    if (!StringUtils.isBlank(charset)) {
                        return EntityUtils.toString(entity, charset);
                    } else {
                        return EntityUtils.toString(entity);
                    }
                } else {
                    return null;
                }
            }
        }
    
        private static HttpClient wrapClient(HttpClient base) {
            try {
                SSLContext ctx = SSLContext.getInstance("TLSv1");
                X509TrustManager tm = new X509TrustManager() {
                    public void checkClientTrusted(X509Certificate[] xcs,
                            String string) throws CertificateException {
                    }
        
                    public void checkServerTrusted(X509Certificate[] xcs,
                            String string) throws CertificateException {
                    }
        
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                };
                ctx.init(null, new TrustManager[] { tm }, null);
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
                CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
                return httpclient;
               
            } catch (Exception ex) {
                return null;
            }
        }
    
    }

    Num62.java

    package weixinpay;
    
    /**
     * 62进制数字
     */
    public class Num62 {
        /**
         * 62个字母和数字,含大小写
         */
        public static final char[] N62_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' };
        /**
         * 36个小写字母和数字
         */
        public static final char[] N36_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' };
        
        /**
         * 10 个数字
         */
        public static final char[] N10_CHARS = { '0', '1', '2', '3', '4', '5', '6',
                '7', '8', '9' };
        /**
         * 长整型用N36表示的最大长度
         */
        public static final int LONG_N36_LEN = 13;
        /**
         * 长整型用N62表示的最大长度
         */
        public static final int LONG_N62_LEN = 11;
    
        /**
         * 长整型转换成字符串
         * 
         * @param l
         * @param chars
         * @return
         */
        private static StringBuilder longToNBuf(long l, char[] chars) {
            int upgrade = chars.length;
            StringBuilder result = new StringBuilder();
            int last;
            while (l > 0) {
                last = (int) (l % upgrade);
                result.append(chars[last]);
                l /= upgrade;
            }
            return result;
        }
    
        /**
         * 长整数转换成N62
         * 
         * @param l
         * @return
         */
        public static String longToN62(long l) {
            return longToNBuf(l, N62_CHARS).reverse().toString();
        }
    
        /**
         * 长整型转换成N36
         * 
         * @param l
         * @return
         */
        public static String longToN36(long l) {
            return longToNBuf(l, N36_CHARS).reverse().toString();
        }
    
        /**
         * 长整数转换成N62
         * 
         * @param l
         * @param length
         *            如不足length长度,则补足0。
         * @return
         */
        public static String longToN62(long l, int length) {
            StringBuilder sb = longToNBuf(l, N62_CHARS);
            for (int i = sb.length(); i < length; i++) {
                sb.append('0');
            }
            return sb.reverse().toString();
        }
    
        /**
         * 长整型转换成N36
         * 
         * @param l
         * @param length
         *            如不足length长度,则补足0。
         * @return
         */
        public static String longToN36(long l, int length) {
            StringBuilder sb = longToNBuf(l, N36_CHARS);
            for (int i = sb.length(); i < length; i++) {
                sb.append('0');
            }
            return sb.reverse().toString();
        }
    
        /**
         * N62转换成整数
         * 
         * @param n62
         * @return
         */
        public static long n62ToLong(String n62) {
            return nToLong(n62, N62_CHARS);
        }
    
        /**
         * N36转换成整数
         * 
         * @param n36
         * @return
         */
        public static long n36ToLong(String n36) {
            return nToLong(n36, N36_CHARS);
        }
    
        private static long nToLong(String s, char[] chars) {
            char[] nc = s.toCharArray();
            long result = 0;
            long pow = 1;
            for (int i = nc.length - 1; i >= 0; i--, pow *= chars.length) {
                int n = findNIndex(nc[i], chars);
                result += n * pow;
            }
            return result;
        }
    
        private static int findNIndex(char c, char[] chars) {
            for (int i = 0; i < chars.length; i++) {
                if (c == chars[i]) {
                    return i;
                }
            }
            throw new RuntimeException("N62(N36)非法字符:" + c);
        }
    
        public static void main(String[] args) {
            System.out.println(longToN62(Long.MAX_VALUE));
        }
    }

    微信支付支付参数配置类

    PaymentConfig.java

    package weixinpay;
    
    public class PaymentConfig {
        /*******微信支付参数*********/
        //公众账号ID
        public static final String appid="wxd";
        //密钥
        public static final String appKey="h";
        //商户号
        public static final String mch_id="1584";
        //接口地址
        public static final String pay_url="https://api2.mch.weixin.qq.com/pay/unifiedorder";
    
    //交易场景信息
        public static final String scene_info = "{"store_info" : {"id": "zxbm","name": "支付","area_code": "430000","address": "中国" }}";
    
        
    }

    PayUtil.java

    package weixinpay;
    
    import org.apache.commons.lang.StringUtils;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.JDOMException;
    import org.jdom.input.SAXBuilder;
    
    import java.io.*;
    import java.security.MessageDigest;
    import java.util.*;
    
    
    public class PayUtil {
    
    
    
    
        /**
        * 将需要传递给微信的参数转成xml格式
        * @param parameters
        * @return
        */
        public static String assembParamToXml(Map<String,String> parameters){
            StringBuffer sb = new StringBuffer();
            sb.append("<xml>");
            Set<String> es = parameters.keySet();
            List<Object> list=new ArrayList<Object>(es);
            Object[] ary =list.toArray();
            Arrays.sort(ary);
            list=Arrays.asList(ary);
            Iterator<Object> it = list.iterator();
            while(it.hasNext()) {
                String key =  (String) it.next();
                String val=(String) parameters.get(key);
                if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {
                    sb.append("<"+key+">"+"<![CDATA["+val+"]]></"+key+">");
                }else {
                    sb.append("<"+key+">"+val+"</"+key+">");
                }
            }
            sb.append("</xml>");
            return sb.toString();
        }
        
    
        /**
        * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
        * @param strxml
        * @return
        * @throws JDOMException
        * @throws IOException
        */
        public static Map parseXMLToMap(String strxml) throws JDOMException, IOException {
            strxml = strxml.replaceFirst("encoding=".*"", "encoding="UTF-8"");
            if(null == strxml || "".equals(strxml)) {
                return null;
            }
            Map m = new HashMap();
            InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(in);
            Element root = doc.getRootElement();
            List list = root.getChildren();
            Iterator it = list.iterator();
            while(it.hasNext()) {
                Element e = (Element) it.next();
                String k = e.getName();
                String v = "";
                List children = e.getChildren();
                if(children.isEmpty()) {
                    v = e.getTextNormalize();
                } else {
                    v =PayUtil.getChildrenText(children);
                }
                m.put(k, v);
            }
            //关闭流
            in.close();
            return m;
        }
    
        /**
        * 获取子结点的xml
        * @param children
        * @return String
        */
        public static String getChildrenText(List children) {
            StringBuffer sb = new StringBuffer();
            if(!children.isEmpty()) {
                Iterator it = children.iterator();
                while(it.hasNext()) {
                    Element e = (Element) it.next();
                    String name = e.getName();
                    String value = e.getTextNormalize();
                    List list = e.getChildren();
                    sb.append("<" + name + ">");
                    if(!list.isEmpty()) {
                        sb.append(getChildrenText(list));
                    }
                    sb.append(value);
                    sb.append("</" + name + ">");
                }
            }
            return sb.toString();
        }
    
        /**
        * 微信支付签名sign
        * @param param
        * @param key
        * @return
        */
        @SuppressWarnings("unchecked")
        public static String createSign(Map<String, String> param,String key){
            //签名步骤一:按字典排序参数
            List list=new ArrayList(param.keySet());
            Object[] ary =list.toArray();
            Arrays.sort(ary);
            list=Arrays.asList(ary);
            String str="";
            for(int i=0;i<list.size();i++){
                str+=list.get(i)+"="+param.get(list.get(i)+"")+"&";
            }
            //签名步骤二:加上key
            str+="key="+key;
            //步骤三:加密并大写
            str=PayUtil.MD5Encode(str,"utf-8").toUpperCase();
            return str;
        }
    
        public static String MD5Encode(String origin,String charsetName){
            String resultString=null;
            try{
                resultString=new String(origin);
                MessageDigest md=MessageDigest.getInstance("MD5");
                if(StringUtils.isBlank(charsetName)){
                    resultString=byteArrayToHexString(md.digest(resultString.getBytes()));
                }else{
                    resultString=byteArrayToHexString(md.digest(resultString.getBytes(charsetName)));
                }
            }catch(Exception e){
            
            }
            return resultString;
        }
    
        public static String byteArrayToHexString(byte b[]){
            StringBuffer resultSb=new StringBuffer();
            for(int i=0;i<b.length;i++){
                resultSb.append(PayUtil.byteToHexString(b[i]));
            }
            return resultSb.toString();
        }
    
        public static String byteToHexString(byte b){
            int n=b;
            if(n<0){
                n+=256;
            }
            int d1=n/16;
            int d2=n%16;
            return PayUtil.hexDigits[d1]+PayUtil.hexDigits[d2];
        }
    
        public static final String hexDigits[]={ "0", "1", "2", "3", "4", "5",  
        "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    
    
        /**
         * 元转换为分
         * @param amount
         */
        public static String changeY2F(Double amount){    
                String currency =  amount.toString();  
                int index = currency.indexOf(".");    
                int length = currency.length();    
                Long amLong = 0l;    
                if(index == -1){    
                    amLong = Long.valueOf(currency+"00");    
                }else if(length - index >= 3){    
                    amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));    
                }else if(length - index == 2){    
                    amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);    
                }else{    
                    amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");    
                }    
                return amLong.toString();    
        }
    
    }

    WeixinPay.java

    package weixinpay;
    
    import org.apache.commons.lang.RandomStringUtils;
    import org.apache.commons.lang.StringUtils;
    import org.springframework.ui.ModelMap;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class WeixinPay {
    
    
        /**
         * 微信统一下单
         *
         * @param trade_type 交易类型
         * @param openId     用户的openId
         * @param request
         * @param wxReturn   微信支付异步回调地址
         * @param orderNo    订单号
         * @param price      订单金额
         * @return
         */
        public static Map<String, String> weixinUniformOrder(String openId,
                                                             HttpServletRequest request, String wxReturn, String orderNo, Double price) {
            Map<String, String> paramMap = new HashMap<String, String>();
            // 微信分配的公众账号ID(企业号corpid即为此appId)[必填]
            paramMap.put("appid", PaymentConfig.appid);
            // 微信支付分配的商户号 [必填]
            paramMap.put("mch_id", PaymentConfig.mch_id);
            // 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB" [非必填]
            paramMap.put("device_info", "WEB");
            // 随机字符串,不长于32位。 [必填]
            paramMap.put("nonce_str", RandomStringUtils.random(10, Num62.N62_CHARS));
            // 商品或支付单简要描述 [必填]
            paramMap.put("body", PaymentConfig.mch_id);
            // 商户系统内部的订单号,32个字符内、可包含字母, [必填]
            paramMap.put("out_trade_no", orderNo);
            // 符合ISO 4217标准的三位字母代码,默认人民币:CNY. [非必填]
            paramMap.put("fee_type", "CNY");
    
            // 金额必须为整数 单位为分 [必填]
            paramMap.put("total_fee", PayUtil.changeY2F(price));
            // APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP [必填]
            paramMap.put("spbill_create_ip", request.getRemoteAddr());
            // 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。 [必填]
            paramMap.put("notify_url", wxReturn);
            // 交易类型{取值如下:JSAPI,NATIVE,APP,(JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付)}
            // [必填]
            paramMap.put("trade_type", "JSAPI");
            //openid trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
            paramMap.put("openid", openId);
            // 商品ID{trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。}
            paramMap.put("product_id", "商品ID");
            // 根据微信签名规则,生成签名
            paramMap.put("sign", PayUtil.createSign(paramMap, PaymentConfig.appKey));
            // 把参数转换成XML数据格式
            String xmlWeChat = PayUtil.assembParamToXml(paramMap);
            String resXml = HttpClientUtil.post(PaymentConfig.pay_url, xmlWeChat);
            Map<String, String> map = new HashMap<String, String>();
            try {
                if (StringUtils.isNotBlank(resXml)) {
                    map = PayUtil.parseXMLToMap(resXml);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return map;
        }
    
    
        /**
         * 微信公众号支付(手机端)
         *
         * @param wxReturn 微信支付异步回调地址
         * @param openId   用户的openid
         * @param orderNo  订单号
         * @param price    订单金额
         * @param request
         * @param response
         * @param model
         * @return
         */
        public static String weixinPayByMobile(String wxReturn, String openId, String orderNo, Double price,
                                               HttpServletRequest request, HttpServletResponse response,
                                               ModelMap model) {
            Map<String, String> map = weixinUniformOrder(openId,
                    request, wxReturn, orderNo, price);
            String returnCode = map.get("return_code");
            if (returnCode.equalsIgnoreCase("FAIL")) {
    
                //调用失败操作
                //当return_code为FAIL时返回信息为错误原因 ,例如 签名失败、参数格式校验错误
                map.get("return_msg");
    
            } else if (returnCode.equalsIgnoreCase("SUCCESS")) {
                if (map.get("err_code") != null) {
    
                    //支付失败操作
                    //错误代码描述
                    map.get("err_code_des");
    
    
                } else if (map.get("result_code").equalsIgnoreCase(
                        "SUCCESS")) {
                    String prepay_id = map.get("prepay_id");
                    Long time = System.currentTimeMillis() / 1000;
                    String nonceStr = RandomStringUtils.random(16, Num62.N10_CHARS);
                    //公众号appid
                    model.addAttribute("appId", PaymentConfig.appid);
                    //时间戳 当前的时间 需要转换成秒
                    model.addAttribute("timeStamp", time);
                    //随机字符串  不长于32位
                    model.addAttribute("nonceStr", nonceStr);
                    //订单详情扩展字符串 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
                    model.addAttribute("package", "prepay_id=" + prepay_id);
                    //签名方式 签名算法,暂支持MD5
                    model.addAttribute("signType", "MD5");
                    Map<String, String> paramMap = new HashMap<String, String>();
                    paramMap.put("appId", PaymentConfig.appid);
                    paramMap.put("timeStamp", time.toString());
                    paramMap.put("nonceStr", nonceStr);
                    paramMap.put("package", "prepay_id=" + prepay_id);
                    paramMap.put("signType", "MD5");
                    //签名
                    model.addAttribute("paySign", PayUtil.createSign(paramMap, PaymentConfig.appKey));
    
                    //跳转到 weixin_prepay.html
                    return "weixin_prepay.html";
                }
            }
            // 失败提示跳转页面,自己设计
            return "error.html";
        }
    
    
        //通知微信正确接收
        public static String getSuccessXml() {
            String xml = "<xml>" +
                    "<return_code><![CDATA[SUCCESS]]></return_code>" +
                    "<return_msg><![CDATA[OK]]></return_msg>" +
                    "</xml>";
            return xml;
        }
    
    }

    微信公众号支付跳转页面主要逻辑代码

    weixin_prepay.html

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>微信支付</title>
        <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript"></script>
        <script type="text/javascript">
            wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: '${appId!}', // 必填,公众号的唯一标识
                timestamp: "${timeStamp!}", // 必填,生成签名的时间戳
                nonceStr: '${nonceStr!}', // 必填,生成签名的随机串
                signature: "${paySign!}", // 必填,签名,见附录1
                jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
            });
            wx.ready(function () {
                wx.chooseWXPay({
                    appId: "${appId!}",
                    timestamp: "${timeStamp!}",
                    nonceStr: "${nonceStr!}",
                    package: "${package!}",
                    signType: "MD5",
                    paySign: "${paySign!}",
                    success: function (res) {
                        alert("成功");
                        window.location.href = "成功之后跳转地址";
                    },
                    cancel: function () {
                        alert("用户已取消");
                    },
                    error: function (e) {
                        alert("失败");
                    }
                });
            });
        </script>
    </head>
    <body>
    <div class="w1187b">
        <div class="w1173">
        </div>
    </div>
    </body>
    </html>

    后台控制器调用类

    WeixinPayAct.java

    package weixinpay;
    
    
    import org.apache.commons.lang.StringUtils;
    import org.jdom.JDOMException;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import weixin.XMLUtil;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.*;
    import java.util.*;
    
    
    @Controller
    public class WeixinPayAct {
    
        /**
         * 微信支付
         *
         * @param request
         * @param response
         * @param model
         * @return
         */
        @RequestMapping(value = "weixin_Pay.jspx")
        public String selectPay(HttpServletRequest request,
                                HttpServletResponse response, ModelMap model) {
    
            String wxReturn = "微信支付异步回调地址";
            String orderNo = "订单号";
            String openId = "用户的openId";
            //支付金额
            Double price = 0.01;
    
            return WeixinPay.weixinPayByMobile(wxReturn, openId, orderNo, price,
                    request, response, model);
    
        }
    
    
        /**
         * 微信支付通知
         *
         * @return
         */
        @ResponseBody
        @RequestMapping(value = "/wechart_notice.jspx")
        public String wechartNotice(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
            String result = "";
            try {
                InputStream inStream = request.getInputStream();
                ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = inStream.read(buffer)) != -1) {
                    outSteam.write(buffer, 0, len);
                }
                outSteam.close();
                inStream.close();
                result = new String(outSteam.toByteArray(), "utf-8");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //判断返回报文是否为空
            if (StringUtils.isNotBlank(result)) {
                try {
                    Map<String, String> map = XMLUtil.doXMLParse(result);
                    //获取商家订单编号 对应orderID
                    String orderNo = map.get("out_trade_no");
                    //String orderNo = RequestUtils.getQueryParam(request,"orderNo");
                    //获取微信支付订单号
                    String transaction_id = map.get("transaction_id");
    
                    Order order = orderMng.findByOrderNo(orderNo);
                    //判断支付是否成功
                    if ("SUCCESS".equals(map.get("result_code"))) {
                        //支付成功,这里之所以加了一个判断,是因为这个回调可能会有多次,所以我们只有当订单状态时未支付的情况下,才执行下面操作
                        if (!Constants.ORDER_SUCCESS.equals(order.getStatus())) {
                            //当微信支付成功后,把订单支付状态改为已支付
                            order.setStatus(Constants.ORDER_SUCCESS);
                        }
                        //处理业务逻辑
                    } else {
                        //支付失败
                        order.setStatus(Constants.ORDER_FAIL);
                    }
                    orderMng.update(order);
                } catch (JDOMException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return WeixinPay.getSuccessXml();
        }
    
    
    }

    如果浏览器请求返回:errMsg: "chooseWXPay:fail, the permission value is offline verifying"

    这个错误是由于我们用的开发工具开发,只要在手机上打开就可以了

  • 相关阅读:
    函数和函数模版在一个。cpp中的情况!(除了左移和右移,其他的不要用友元函数!!!)
    const typedef 和指针的问题(这里必须初始化的才初始化了,不必须的则没有初始化)
    const constptr 和引用的盲点(未解决)
    对于数据流建模和行为级建模的梳理(重点)
    vivado实现模16的计数器
    用vivado实现4比特加法器
    三输入或门(发现这个玩意很不好耍,编程出现错误,不知道哪里出现的,一不小心2输成3也无法查证)
    SpringMVC第一个例子
    Mybatis与Spring的mapper代理整合方法
    Mybatis与Spring的原生Dao整合
  • 原文地址:https://www.cnblogs.com/pxblog/p/12815705.html
Copyright © 2011-2022 走看看