JAVA微信APP支付接口整合

    上次咱們看到了支付寶的APP支付工具,那麼此次就來封裝封裝微信的APP支付;若是已經清楚了支付寶的支付流程,那麼微信支付也和它大同小異了,固然這其中確定是有各類變化的:php

    首先讓我把微信支付文檔的官網貼出來,下面代碼中有不懂得能夠查看文檔:html

    1:    各類支付: https://pay.weixin.qq.com/wiki/doc/api/sl.htmljava

    2:    APP支付: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=8_1web

    3:    業務流程: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=8_3spring

    4:    統一下單: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_1api

    5:   支付結果通知: https://pay.weixin.qq.com/wiki/doc/api/app/app_sl.php?chapter=9_7&index=3服務器

    好了,關鍵的文檔就這麼多;微信的官方支付SDK我沒有找到,就只有本身開寫啦,固然,也藉助了網上很多大牛的技術支持,在這裏表示很是很是感謝;微信

    話很少說,咱們直接來上代碼:網絡

1: 微信APP支付配置文件(數據爲測試數據):微信開發

package com.xt.shop.web.wxpay;

/**
 *<p>類  說  明: TODO 微信APP支付配置文件
 *<p>建立時間: 2017年11月2日 上午9:02:51
 *<p>創  建  人: geYang
 **/
public class WxpayConfig {
    /**
     * 微信開發平臺應用ID
     */
    public static final String APPID = "wx5cb4da2827891470";
    /**
     * 微信支付商戶號
     */
    public static final String MCH_ID = "1458672702";
    /**
     * 應用對應的憑證
     */
    public static final String APP_SECRET = "68c39252926ac35b091b9f824c1e065e";
    /**
     * 應用對應的密鑰
     */
    public static final String APP_KEY = "7PEsu5akPFRDfORYWNWj6QanQhzuXTJ0";
    /**
     * 商戶號對應的密鑰
     */
    public static final String PARTNER_KEY = "123466";
    /**
     * 商戶id
     */
    public static final String PARTNER_ID = "14698sdfs402dsfdew402";
    /**
     * 常量固定值
     */
    public static final String GRANT_TYPE = "client_credential";
    /**
     * 微信服務器回調通知URL
     */
    public static final String NOTIFY_URL = "/wxPayNotify";
    /**
     * 獲取預支付ID的接口URL 統一下單接口地址
     */
    public static final String REQUEST_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    /**
     * 關閉訂單接口,避免出現(訂單重複提交出錯)
     */
    public static final String CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder";
    /**
     * 查看訂單接口
     */
    public static final String ORDER_QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
    
    
    
    
}

2: MD5加密工具

package com.xt.shop.web.wxpay;

import java.security.MessageDigest;

/**
 *<p>類  說  明: TODO MD5加密工具類
 *<p>建立時間: 2017年11月7日 上午10:34:26
 *<p>創  建  人: geYang
 **/
public class MD5Util {

    /**
     *<p>方法說明: TODO MD5加密  編碼:UTF-8
     *<p>建立時間: 2017年11月2日 下午4:00:17
     *<p>創  建  人: geYang
     **/
    public static String md5Encode(String paramStr) {
        String encodeStr = null;
        try {
            encodeStr = new String(paramStr);
            MessageDigest md = MessageDigest.getInstance("MD5");
            encodeStr = byteArrayToHexString(md.digest(encodeStr.getBytes("UTF-8")));
        } catch (Exception exception) {
        }
        return encodeStr;
    }


    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++){
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0){
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return HEX_DIGITS[d1] + HEX_DIGITS[d2];
    }

    private static final String[] HEX_DIGITS = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

}

3: XML解析工具

package com.xt.shop.web.wxpay;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import com.xt.shop.until.IsNull;

/**
 *<p>類  說  明: TODO XML解析工具
 *<p>建立時間: 2017年11月7日 上午10:36:15
 *<p>創  建  人: geYang
 **/
public class XMLUtil {
    /**
     * <p>方法說明: TODO 解析XML,返回第一級元素鍵值對;若是第一級元素有子節點,則此節點的值是子節點的XML數據;
     * <p>參數說明: String xmlStr XML格式字符串
     * <p>參數說明: @throws JDOMException
     * <p>參數說明: @throws IOException
     * <p>返回說明: Map<String,String> xmlMap 解析後的數據
     * <p>建立時間: 2017年11月2日 上午10:04:39
     * <p>創  建  人: geYang
     **/
    public static Map<String, String> doXMLParse(String xmlStr) throws JDOMException, IOException {
        xmlStr = xmlStr.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
        if (IsNull.isNull(xmlStr)) {
            return null;
        }
        Map<String, String> xmlMap = new HashMap<>();
        InputStream in = new ByteArrayInputStream(xmlStr.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List<Element> list = root.getChildren();
        Iterator<Element> it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List<Element> children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = XMLUtil.getXMLStr(children);
            }
            xmlMap.put(k, v);
        }
        in.close(); // 關閉流
        return xmlMap;
    }

    /**
     * <p>方法說明: TODO 獲取子結點的XML,生成XML格式字符串
     * <p>參數說明: List<Element> listElement
     * <p>返回說明: XML格式字符串
     * <p>建立時間: 2017年11月2日 上午9:58:59
     * <p>創  建  人: geYang
     **/
    private static String getXMLStr(List<Element> listElement) {
        StringBuffer xmlStr = new StringBuffer();
        if (!listElement.isEmpty()) {
            Iterator<Element> it = listElement.iterator();
            while (it.hasNext()) {
                Element e = it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List<Element> listChildren = e.getChildren();
                xmlStr.append("<" + name + ">");
                if (!listChildren.isEmpty()) {
                    xmlStr.append(XMLUtil.getXMLStr(listChildren)); // 遞歸
                }
                xmlStr.append(value);
                xmlStr.append("</" + name + ">");
            }
        }
        return xmlStr.toString();
    }

    /**
     *<p>方法說明: TODO 獲取XML編碼字符集
     *<p>參數說明: String xmlStr
     *<p>參數說明: @return
     *<p>參數說明: @throws JDOMException
     *<p>參數說明: @throws IOException
     *<p>返回說明: 
     *<p>建立時間: 2017年11月2日 上午10:31:16
     *<p>創  建  人: geYang
     **/
    public static String getXMLEncoding(String xmlStr) throws JDOMException, IOException {
        InputStream in = new ByteArrayInputStream(xmlStr.getBytes());
        SAXBuilder builder = new SAXBuilder();
        Document document = builder.build(in);
        in.close();
        return (String)document.getProperty("encoding");
    }
    
    
    /**
     *<p>方法說明: TODO 支付成功(失敗)後返回給微信的參數
     *<p>參數說明: String return_code
     *<p>參數說明: String return_msg
     *<p>返回說明: 
     *<p>建立時間: 2017年11月2日 上午10:42:10
     *<p>創  建  人: geYang
     **/
    public static String setXML(String returnCode, String returnMsg) {
        return "<xml><return_code><![CDATA[" + returnCode
                + "]]></return_code><return_msg><![CDATA[" + returnMsg
                + "]]></return_msg></xml>";
    }
    
    
    
    
    
    
    public static void main(String[] args) {
        StringBuffer xmlStr = new StringBuffer();
        xmlStr.append("<xml>");
        xmlStr.append("<appid>wx2421b1c4370ec43b</appid>");
        xmlStr.append("<attach>支付測試</attach>");
        xmlStr.append("<body>APP支付測試</body>");
        xmlStr.append("<mch_id>10000100</mch_id>");
        xmlStr.append("<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>");
        xmlStr.append("<notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>");
        xmlStr.append("<out_trade_no>1415659990</out_trade_no>");
        xmlStr.append("<spbill_create_ip>14.23.150.211</spbill_create_ip>");
        xmlStr.append("<total_fee>1</total_fee>");
        xmlStr.append("<trade_type>APP</trade_type>");
        xmlStr.append("<sign>0CB01533B8C1EF103065174F50BCA001</sign>");
        xmlStr.append("</xml>");
        System.out.println("解析前=="+xmlStr);
        Map<String, String> doXMLParse = new HashMap<>();
        try {
             doXMLParse = XMLUtil.doXMLParse(xmlStr.toString());
        } catch (JDOMException | IOException e) {
            e.printStackTrace();
            System.out.println("解析Map失敗");
        }
        System.out.println("解析後=="+doXMLParse);
        
    }
    
    
}

4: 微信支付工具

package com.xt.shop.web.wxpay;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.DecimalFormat;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import com.xt.shop.until.IsNull;
import com.xt.shop.until.http.HttpUtil;

/**
 *<p>類  說  明: TODO 微信支付工具
 *<p>建立時間: 2017年11月7日 上午10:37:46
 *<p>創  建  人: geYang
 **/
public class WxpayUtil {
    private static final String STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    /**
     *<p>方法說明: TODO 獲取微信回調地址
     *<p>建立時間: 2017年11月2日 下午1:21:05
     *<p>創  建  人: geYang
     **/
    public static String getNotifyUrl(HttpServletRequest request){
        StringBuffer requestURL = request.getRequestURL();
        return requestURL.substring(0,requestURL.indexOf("/front/"))+WxpayConfig.NOTIFY_URL;
    }
    /**
     *<p>方法說明: TODO 統一下單 參數處理
     *<p>參數說明: String orderNo       訂單號
     *<p>參數說明: String totalAmount   訂單總金額
     *<p>參數說明: String notifyUrl     回調通知地址
     *<p>參數說明: String body          訂單描述
     *<p>返回說明: 
     *<p>建立時間: 2017年11月3日 上午9:56:23
     *<p>創  建  人: geYang
     **/
    public static String getUnifiedOrder(String orderNo,String totalAmount,String notifyUrl,String body){
        SortedMap<String,String> paramMap = new TreeMap<String,String>();
        paramMap.put("appid", WxpayConfig.APPID);     //應用ID
        paramMap.put("mch_id", WxpayConfig.MCH_ID);   //商戶號
        paramMap.put("nonce_str", getNonceStr(null)); //隨機字符串
        paramMap.put("body", body);                   //商品描述
        paramMap.put("out_trade_no", orderNo);        //商戶訂單號
        paramMap.put("total_fee", getTotalFee(totalAmount));//支付總金額
        paramMap.put("spbill_create_ip",getLocalhostIP());  //當前本機IP: 192.168.102.10
        paramMap.put("notify_url", notifyUrl);              //回調通知地址
        paramMap.put("trade_type", "APP");                  //支付類型
        paramMap.put("sign", rsaSign(paramMap));            //數據簽名
        return getRequestXML(paramMap);     //請求參數
    }
    /**
     *<p>方法說明: TODO 返回APP 參數處理
     *<p>參數說明: String prepayId   預支付交易會話ID
     *<p>返回說明: 
     *<p>建立時間: 2017年11月3日 上午10:00:30
     *<p>創  建  人: geYang
     **/
    public static String getReturnParam(String prepayId){
        String timestamp = (System.currentTimeMillis()+"").substring(0, 10);
        SortedMap<String,String> returnMap = new TreeMap<String,String>();
        returnMap.put("appid", WxpayConfig.APPID);      //應用ID
        returnMap.put("partnerid", WxpayConfig.MCH_ID); //商戶號
        returnMap.put("prepayid", prepayId);            //預支付交易會話ID
        returnMap.put("package", "Sign=WXPay");         //擴展字段 固定值 Sign=WXPay
        returnMap.put("noncestr", getNonceStr(null));   //隨機字符串
        returnMap.put("timestamp", timestamp);          //時間戳
        returnMap.put("sign", rsaSign(returnMap));      //簽名
        return getRequestXML(returnMap);     //請求參數
    }
    /**
     *<p>方法說明: TODO 關閉/查看 訂單 參數處理
     *<p>參數說明: String orderNo 商戶訂單號
     *<p>建立時間: 2017年11月3日 下午2:55:53
     *<p>創  建  人: geYang
     **/
    public static String closeORqueryOrderParam(String orderNo) {
        SortedMap<String,String> returnMap = new TreeMap<String,String>();
        returnMap.put("appid", WxpayConfig.APPID);      //應用ID
        returnMap.put("mch_id", WxpayConfig.MCH_ID);    //商戶號
        returnMap.put("out_trade_no", orderNo);         //商戶訂單號
        returnMap.put("nonce_str", getNonceStr(null));  //隨機字符串
        returnMap.put("sign", rsaSign(returnMap));      //簽名
        return getRequestXML(returnMap);     //請求參數
    }
    /**
     *<p>方法說明: TODO 驗證簽名
     *<p>參數說明: Map<String,String> paramMap
     *<p>返回說明: boolean
     *<p>建立時間: 2017年11月3日 上午11:18:47
     *<p>創  建  人: geYang
     **/
    public static boolean rsaCheck(Map<String,String> paramMap){
        System.out.println("↓↓↓↓↓↓↓↓↓↓微信支付簽名驗證處理↓↓↓↓↓↓↓↓↓↓");
        SortedMap<String,String> paramSorMap = new TreeMap<String,String>();
        paramSorMap.putAll(paramMap);
        boolean rsaCheck = paramMap.get("sign").equals(rsaSign(paramSorMap));
        System.out.println("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
        return rsaCheck;
    }
    /**
     *<p>方法說明: TODO sign簽名
     *<p>參數說明: SortedMap<String,String> paramMap
     *<p>返回說明: String
     *<p>建立時間: 2017年11月2日 下午3:45:02
     *<p>創  建  人: geYang
     **/
    private static String rsaSign(SortedMap<String,String> paramMap){
        StringBuffer paramStr = new StringBuffer();
        Set<Entry<String, String>> paramSet = paramMap.entrySet();
        Iterator<Entry<String, String>> it = paramSet.iterator();
        while(it.hasNext()) {
            Entry<String, String> entry = it.next();
            String k = entry.getKey();
            String v = entry.getValue();
            if(!IsNull.isNull(v) && !"sign".equals(k) && !"key".equals(k)) {
                paramStr.append(k + "=" + v + "&");
            }
        }
        paramStr.append("key="+ WxpayConfig.APP_KEY);     //注:key爲商戶平臺設置的密鑰key
        String sign = MD5Util.md5Encode(paramStr.toString()).toUpperCase();//注:MD5簽名方式
        System.out.println("微信簽名參數=="+paramStr.toString());
        System.out.println("微信籤  名  值=="+sign);
        return sign;
    }
    /**
     *<p>方法說明: TODO 生成隨機字符串
     *<p>參數說明: Integer length 默認16
     *<p>返回說明: 長度爲 length 的字符串
     *<p>建立時間: 2017年11月2日 下午2:57:57
     *<p>創  建  人: geYang
     **/
    private static String getNonceStr(Integer length) {
        length = IsNull.isNull(length) ? 16 : length;
        StringBuffer nonceStr = new StringBuffer();
        for (int i = 0; i < length; i++) {
            Random rd = new Random();
            nonceStr.append(STR.charAt(rd.nextInt(STR.length() - 1)));
        }
        return nonceStr.toString();
    }
    /**
     *<p>方法說明: TODO 獲取本機IP
     *<p>返回說明: 經過 獲取系統全部的networkInterface網絡接口 而後遍歷 每一個網絡下的InterfaceAddress組,
     *          得到符合  "InetAddress instanceof Inet4Address" 條件的一個IpV4地址
     *<p>建立時間: 2017年11月2日 下午2:02:20
     *<p>創  建  人: geYang
     **/
    private static String getLocalhostIP(){
        String ip = null;
        Enumeration<?> allNetInterfaces;
        try {
            allNetInterfaces = NetworkInterface.getNetworkInterfaces();            
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                List<InterfaceAddress> interfaceAddress = netInterface.getInterfaceAddresses();
                for (InterfaceAddress add : interfaceAddress) {
                    InetAddress inetAddress = add.getAddress();
                    if (inetAddress != null && inetAddress instanceof Inet4Address) {
                        ip = inetAddress.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
            System.out.println("獲取IP異常");
        }
        return ip;
    }
    /**
     *<p>方法說明: TODO 將請求參數轉換爲XML格式的String
     *<p>參數說明: SortedMap<String,String> paramMap 
     *<p>返回說明: String
     *<p>建立時間: 2017年11月2日 下午4:16:21
     *<p>創  建  人: geYang
     **/
    private static String getRequestXML(SortedMap<String,String> paramMap){
        StringBuffer requestXML = new StringBuffer();
        requestXML.append("<xml>");
        Set<Entry<String, String>> paramSet = paramMap.entrySet();
        Iterator<Entry<String, String>> it = paramSet.iterator();
        while(it.hasNext()) {
            Entry<String, String> entry = it.next();
            String k = entry.getKey();
            String v = entry.getValue();
            requestXML.append("<"+k+">"+v+"</"+k+">");
        }
        requestXML.append("</xml>");
        System.out.println("微信請求參數=="+requestXML);
        return requestXML.toString();
    }
    /**
     *<p>方法說明: TODO 獲取整數格式支付總金額
     *<p>參數說明: String totalAmount  保留兩位小數的金額
     *<p>返回說明: String getTotalFee  整數的金額
     *<p>建立時間: 2017年11月2日 下午5:39:03
     *<p>創  建  人: geYang
     **/
    private static String getTotalFee(String totalAmount){
        DecimalFormat decimalFormat = new DecimalFormat("###################.###########"); 
        return decimalFormat.format(Double.valueOf(totalAmount)*100);
    }
    
    
    /**
     *<p>方法說明: TODO 訂單查看處理
     *<p>建立時間: 2017年11月3日 下午3:34:16
     *<p>創  建  人: geYang
     **/
    public static Map<String,String> orderQuery(String orderNo) throws Exception{
        System.out.println("↓↓↓↓↓↓↓↓↓↓微信支付訂單查看處理↓↓↓↓↓↓↓↓↓↓");
        String receiveParam = HttpUtil.doPostToStrUTF8(WxpayConfig.ORDER_QUERY_URL, closeORqueryOrderParam(orderNo));
        return XMLUtil.doXMLParse(receiveParam);
    }
    /**
     *<p>方法說明: TODO 訂單關閉處理
     *<p>建立時間: 2017年11月3日 下午3:34:16
     *<p>創  建  人: geYang
     **/
    public static Map<String,String> colseOrder(String orderNo) throws Exception{
        System.out.println("↓↓↓↓↓↓↓↓↓↓微信支付訂單關閉處理↓↓↓↓↓↓↓↓↓↓");
        String receiveParam = HttpUtil.doPostToStrUTF8(WxpayConfig.CLOSE_ORDER_URL, closeORqueryOrderParam(orderNo));
        return XMLUtil.doXMLParse(receiveParam);
    }
    
    
    public static void main(String[] args) throws Exception {
        String orderNo = "R20171027114996454";
        System.out.println(orderQuery(orderNo));
//        System.out.println(colseOrder(orderNo));
    }
    
    
    
    
    
    
    
    
    
    
}

5: 微信支付請求:

package com.xt.shop.web.wxpay;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.xt.shop.base.exception.MyException;
import com.xt.shop.base.service.inter.ProductOrderInter;
import com.xt.shop.base.service.inter.RepairOrderInter;
import com.xt.shop.until.IsNull;
import com.xt.shop.until.http.HttpUtil;
import com.xt.shop.until.often.MyResult;

/**
 *<p>類  說  明: TODO 微信支付處理
 *<p>建立時間: 2017年11月2日 下午1:26:08
 *<p>創  建  人: geYang
 **/
@RestController
public class WxpayController {
    /**
     * 商品訂單
     */
    @Resource
    private ProductOrderInter productOrderInter;
    /**
     * 維修訂單
     */
    @Resource
    private RepairOrderInter repairOrderInter;
    /**
     *<p>方法說明: TODO 支付回調處理
     *<p>建立時間: 2017年11月3日 上午10:58:46
     *<p>創  建  人: geYang
     **/
    @RequestMapping(value="/wxPayNotify")
    String getPayNotify(HttpServletRequest request){
        System.out.println("↓↓↓↓↓↓↓↓↓↓微信支付回調業務處理↓↓↓↓↓↓↓↓↓↓");
        Map<String,String> receiveMap = new HashMap<>();
        try {   //讀取參數  
            receiveMap = XMLUtil.doXMLParse(receiveParam(request));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("微信支付回調數據流錯誤");
        }
        System.out.println("微信支付回調參數=="+receiveMap);
        if(!WxpayUtil.rsaCheck(receiveMap)){   //簽名驗證
            System.out.println("微信支付回調簽名驗證失敗");
            return XMLUtil.setXML("FAIL", "簽名驗證失敗");
        }
       if(receiveMap.get("return_code").equals("SUCCESS")){   //返回成功
           if(receiveMap.get("result_code").equals("SUCCESS")){   //業務返回成功
              String orderNo = receiveMap.get("out_trade_no");
              System.out.println("微信支付回調商戶訂單號=="+orderNo);
              //訂單業務操做
              if(orderNo.startsWith("G")){   //商品訂單
                  try {
                      return productOrderInter.paymentProductOrder(orderNo, 1);
                  } catch (MyException e) {
                      e.printStackTrace();
                      System.out.println(e.getMessage());
                      return "failure";
                  }
              } else if(orderNo.startsWith("R")){ //維修訂單
                  try {
                      return repairOrderInter.paymentRepairOrder(orderNo, 1);
                  } catch (MyException e) {
                      e.printStackTrace();
                      System.out.println(e.getMessage());
                      return "failure";
                  }
              }
                return XMLUtil.setXML("SUCCESS", "OK");
            }
            System.out.println("微信支付回調業務錯誤:"+receiveMap.get("err_code_des"));
            return XMLUtil.setXML("FAIL", receiveMap.get("err_code_des"));
        }
        System.out.println("微信支付回調返回錯誤:"+receiveMap.get("return_msg"));
        return XMLUtil.setXML("FAIL", receiveMap.get("return_msg"));
    }
    /**
     *<p>方法說明: TODO 獲取數據流數據
     *<p>建立時間: 2017年11月3日 下午1:57:15
     *<p>創  建  人: geYang
     **/
    private static String receiveParam (HttpServletRequest request) throws IOException{
        StringBuffer receiveParam = new StringBuffer(); 
        InputStream inputStream = request.getInputStream();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
        BufferedReader in = new BufferedReader(inputStreamReader);
        while ( in.readLine() != null){
            receiveParam.append(in.readLine());
        }
        in.close();
        inputStream.close();
        System.out.println("微信支付回調參數=="+receiveParam);
        return receiveParam.toString();
    }
    
    /**
     *<p>方法說明: TODO 微信支付統一下單接口
     *<p>參數說明: String orderNo 訂單號
     *<p>返回說明: 
     *<p>建立時間: 2017年11月2日 下午1:29:00
     *<p>創  建  人: geYang
     **/
    @RequestMapping(value="/front/wxPay",method=RequestMethod.POST)
    Object wxPay(String orderNo,HttpServletRequest request) {
        if(IsNull.isNull(orderNo)){
            return MyResult.errMap("請指定訂單號");
        }
        StringBuffer totalAmount = new StringBuffer(); //訂單總價值
        StringBuffer body = new StringBuffer();        //對一筆交易的具體描述信息
        //訂單業務操做
        if(orderNo.startsWith("G")){        //商品訂單
            Map<String, String> order;
            try {
                order = productOrderInter.isPayment(orderNo);
                totalAmount.append(order.get("totalAmount"));
                body.append(order.get("productName"));  
            } catch (MyException e) {
                e.printStackTrace();
                return MyResult.errMap(e.getMessage());
            }
        } else if(orderNo.startsWith("R")){ //維修訂單
            Map<String, String> order;
            try {
                order = repairOrderInter.isPayment(orderNo);
                totalAmount.append(order.get("totalAmount"));
                body.append(order.get("repairItem"));  
            } catch (MyException e) {
                e.printStackTrace();
                return MyResult.errMap(e.getMessage());
            }
        } else {
            return MyResult.errMap("訂單號錯誤");
        }
        String notifyUrl = WxpayUtil.getNotifyUrl(request);     //回調地址
        return payment(notifyUrl,orderNo,totalAmount.toString(),body.toString());
    }
    
    /**
     *<p>方法說明: TODO 統一下單支付處理
     *<p>參數說明: String notifyUrl 回調地址
     *<p>參數說明: String orderNo   訂單號
     *<p>參數說明: String totalAmount 訂單總金額
     *<p>參數說明: String body  商品描述
     *<p>返回說明: Map<String,Object>
     *<p>建立時間: 2017年11月3日 上午10:47:09
     *<p>創  建  人: geYang
     **/
    private static Map<String,Object> payment(String notifyUrl,String orderNo,String totalAmount,String body){
        System.out.println("↓↓↓↓↓↓↓↓↓↓微信支付統一下單參數處理↓↓↓↓↓↓↓↓↓↓");
        String unifiedOrderParam = WxpayUtil.getUnifiedOrder(orderNo,totalAmount,notifyUrl, body);
        Map<String, String> receiveMap = new HashMap<>();  //回調參數
        try {
            String xmlStr = HttpUtil.doPostToStrUTF8(WxpayConfig.REQUEST_URL, unifiedOrderParam);
            receiveMap = XMLUtil.doXMLParse(xmlStr);
            System.out.println("微信返回值=="+receiveMap);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("微信支付HTTP請求錯誤");
            return MyResult.errMap("微信支付HTTP請求錯誤");
        }
        if(receiveMap.get("return_code").equals("SUCCESS")){        //請求返回正常:
            if(receiveMap.get("result_code").equals("SUCCESS")){    //業務正常:
                System.out.println("↓↓↓↓↓↓↓↓↓↓微信支付返回APP參數處理↓↓↓↓↓↓↓↓↓↓");
                Map<String,Object> data = new HashMap<>();
                data.put("data", WxpayUtil.getReturnParam(receiveMap.get("prepay_id")));
                return MyResult.succMap(data);
            }
            System.out.println("微信支付請求業務錯誤:"+receiveMap.get("err_code_des"));
            return MyResult.errMap("微信支付請求業務錯誤:"+receiveMap.get("err_code_des"));
        }
        System.out.println("微信支付請求返回錯誤:"+receiveMap.get("return_msg"));
        return MyResult.errMap("微信支付請求返回錯誤:"+receiveMap.get("return_msg"));
    }
}

        微信APP支付就是這樣;其中 WxpayController 類中 payment 方法 使用的 HTTP請求工具在個人第一個博客中:    http://www.javashuo.com/article/p-gtkxjvlf-ms.html

好了,微信的APP支付就這樣結束了,各位朋友能夠直接進行使用(只須要修改本身的配置文件就行了);有不懂的朋友能夠留言討論,也能夠和支付文檔對照查看;

其中若是有錯誤,BUG還請各位大牛指正;真誠感謝......

相關文章
相關標籤/搜索