JAVA微信支付——微信公眾號內支付 代碼


 

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

 

微信PC二維碼支付方式參考:https://www.cnblogs.com/pxblog/p/10542917.html 

 

沙箱環境調試:https://www.cnblogs.com/pxblog/p/13844925.html

 

本地開發環境支付回調調試方法可以參考:https://www.cnblogs.com/pxblog/p/11623053.html

 

引入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")
    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")
    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"

這個錯誤是由於我們用的開發工具開發,只要在手機上打開就可以了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM