关闭

java 微信公众号支付接口开发总结

标签: JAVA微信支付
426人阅读 评论(0) 收藏 举报

1、在做微信支付的时候,需要注意验证签名是否正确,一般很多时候错误都是签名引起的;

2、获取openid 需要通过授权获取

public class WePay {

//统一下单中参数参照微信公众号支付接口文档;

    @Autowired
    private IWeChatService weChatService;
     /**获取同一下单prepay_id
      * @param orderId 订单号,不能重复
      * @param order_price 商品价格,单位分
      * @param id 用户ID
      * @param callback 回调地址
      * @param convert 是否生成二维码
      * @return
      * @throws Exception
      */
    public static String weixin_pay(String openId,String body,String orderId,String order_price,String callback) throws Exception {
        // 账号信息
        String appid = Constant.WE_CHANT_CONST.APP_ID; // appid
        String mch_id = Constant.WE_CHANT_CONST.MERCHANT_ID; // 商业号
        String key = Constant.WE_CHANT_CONST.KEY; // key
        String nonce_str=getNonceStr();
        //获取openId
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("openid", openId);
        //商品价格   注意,单位是分!
        packageParams.put("total_fee", order_price);
        //发起请求的电脑IP
        packageParams.put("spbill_create_ip", Constant.WE_CHANT_CONST.SPBILL_CREATE_IP);
        //回调接口地址
        packageParams.put("notify_url",callback);
        packageParams.put("trade_type", Constant.WE_CHANT_CONST.TRADE_TYPE);
        //packageParams.put("attach", attach);
        packageParams.put("body",body);
        packageParams.put("out_trade_no", orderId);
        packageParams.put("device_info", Constant.WE_CHANT_CONST.DEVICE_INFO);

        String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
        packageParams.put("sign", sign);

        String requestXML = PayCommonUtil.getRequestXml(packageParams);

        String resXml = HttpUtil.postData(Constant.WE_CHANT_CONST.UFDODER_URL, requestXML);

        Map map = XMLUtil.doXMLParse(resXml);
         String prepay_id = (String) map.get("prepay_id");
        return prepay_id;

    }

// 将js支付需要的参数封装(用于在controller推送到jsp页面)

   
    /**
     * 获取支付配置
     * @param @param preayId 统一下单prepay_id
     * @param @return
     * @param @throws Exception    
     * @return JsAPIConfig    
     * @throws
     */
    public static JsAPIConfig createPayConfig(String prepayId) throws Exception {
        JsAPIConfig config = new JsAPIConfig();
        String appId = Constant.WE_CHANT_CONST.APP_ID; // appid
        String nonce_str=getNonceStr();
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String packageName = "prepay_id="+prepayId;
        String key = Constant.WE_CHANT_CONST.KEY; // key
        
        StringBuffer sign = new StringBuffer();
        sign.append("appId=").append(appId);
        sign.append("&nonceStr=").append(nonce_str);
        sign.append("&package=").append(packageName);
        sign.append("&signType=").append("MD5");
        sign.append("&timeStamp=").append(timestamp);
        sign.append("&key=").append(key);
        String signature = DigestUtils.md5Hex(sign.toString()).toUpperCase();
        config.setAppId(appId);
        config.setNonce(nonce_str);
        config.setTimestamp(timestamp);
        config.setPackageName(packageName);
        config.setSignature(signature);
        config.setSignType("MD5");

        return config;

    }

//微信支付订单查询

    public static Map orderquery(String order) throws Exception {
        String url = "https://api.mch.weixin.qq.com/pay/orderquery";
        // 账号信息
        String appid = Constant.WE_CHANT_CONST.APP_ID; // appid
        String mch_id = Constant.WE_CHANT_CONST.MERCHANT_ID; // 商业号
        String key = Constant.WE_CHANT_CONST.KEY; // key
        String nonce_str=getNonceStr();
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("out_trade_no", order);
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
        packageParams.put("sign", sign);

        String requestXML = PayCommonUtil.getRequestXml(packageParams);

        String resXml = HttpUtil.postData(url, requestXML);

        Map map = XMLUtil.doXMLParse(resXml);
        
        
        return map;
    }
    
    public static String getNonceStr() {
        Random random = new Random();
        return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "UTF-8");
      }

}



------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

工具类



public class PayCommonUtil {  
          
        /**
         * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
         * @return boolean
         */  
        public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {  
            StringBuffer sb = new StringBuffer();  
            Set es = packageParams.entrySet();  
            Iterator it = es.iterator();  
            while(it.hasNext()) {  
                Map.Entry entry = (Map.Entry)it.next();  
                String k = (String)entry.getKey();  
                String v = (String)entry.getValue();  
                if(!"sign".equals(k) && null != v && !"".equals(v)) {  
                    sb.append(k + "=" + v + "&");  
                }  
            }  
              
            sb.append("key=" + API_KEY);  
              
            //算出摘要  
            String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();  
            String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();  
              
            //System.out.println(tenpaySign + "    " + mysign);  
            return tenpaySign.equals(mysign);  
        }  
      
        /**
         * @author
         * @date 2016-4-22
         * @Description:sign签名
         * @param characterEncoding
         *            编码格式
         * @param parameters
         *            请求参数
         * @return
         */  
        public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {  
            StringBuffer sb = new StringBuffer();  
            Set es = packageParams.entrySet();  
            Iterator it = es.iterator();  
            while (it.hasNext()) {  
                Map.Entry entry = (Map.Entry) it.next();  
                String k = (String) entry.getKey();  
                String v = (String) entry.getValue();  
                if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {  
                    sb.append(k + "=" + v + "&");  
                }  
            }  
            sb.append("key=" + API_KEY);  
            System.out.println("签名所用到的字符串!》》》》" +sb.toString());
            String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  
            return sign;  
        }  
      
        /**
         * @author
         * @date 2016-4-22
         * @Description:将请求参数转换为xml格式的string
         * @param parameters
         *            请求参数
         * @return
         */  
        public static String getRequestXml(SortedMap<Object, Object> parameters) {  
            StringBuffer sb = new StringBuffer();  
            sb.append("<xml>");  
            Set es = parameters.entrySet();  
            Iterator it = es.iterator();  
            while (it.hasNext()) {  
                Map.Entry entry = (Map.Entry) it.next();  
                String k = (String) entry.getKey();  
                String v = (String) entry.getValue();  
                if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {  
                    sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");  
                } else {  
                    sb.append("<" + k + ">" + v + "</" + k + ">");  
                }  
            }  
            sb.append("</xml>");  
            return sb.toString();  
        }  
      
        /**
         * 取出一个指定长度大小的随机正整数.
         *  
         * @param length
         *            int 设定所取出随机数的长度。length小于11
         * @return int 返回生成的随机数。
         */  
        public static int buildRandom(int length) {  
            int num = 1;  
            double random = Math.random();  
            if (random < 0.1) {  
                random = random + 0.1;  
            }  
            for (int i = 0; i < length; i++) {  
                num = num * 10;  
            }  
            return (int) ((random * num));  
        }  
      
        /**
         * 获取当前时间 yyyyMMddHHmmss
         *  
         * @return String
         */  
        public static String getCurrTime() {  
            Date now = new Date();  
            SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");  
            String s = outFormat.format(now);  
            return s;  
        }  
      
    }  





public class HttpUtil {

          
        //private static Logger log = Logger.getLogger(AccountController.class);
        private final static int CONNECT_TIMEOUT = 5000; // in milliseconds  
        private final static String DEFAULT_ENCODING = "UTF-8";  
          
        public static String postData(String urlStr, String data){  
            return postData(urlStr, data, null);  
        }  
          
        public static String postData(String urlStr, String data, String contentType){  
            BufferedReader reader = null;  
            try {  
                URL url = new URL(urlStr);  
                URLConnection conn = url.openConnection();  
                conn.setDoOutput(true);  
                conn.setConnectTimeout(CONNECT_TIMEOUT);  
                conn.setReadTimeout(CONNECT_TIMEOUT);  
                if(contentType != null)  
                    conn.setRequestProperty("content-type", contentType);  
                OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);  
                if(data == null)  
                    data = "";  
                writer.write(data);   
                writer.flush();  
                writer.close();    
      
                reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));  
                StringBuilder sb = new StringBuilder();  
                String line = null;  
                while ((line = reader.readLine()) != null) {  
                    sb.append(line);  
                    sb.append("\r\n");  
                }  
                return sb.toString();  
            } catch (IOException e) {  
              //  log.error("Error connecting to " + urlStr + ": " + e.getMessage());  
            } finally {  
                try {  
                    if (reader != null)  
                        reader.close();  
                } catch (IOException e) {  
                }  
            }  
            return null;  
        }  
}






public class XMLUtil {

        /**
         * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
         * @param strxml
         * @return
         * @throws JDOMException
         * @throws IOException
         */  
        public static Map doXMLParse(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 = XMLUtil.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(XMLUtil.getChildrenText(list));  
                    }  
                    sb.append(value);  
                    sb.append("</" + name + ">");  
                }  
            }  
              
            return sb.toString();  
        }  
          
    }  




0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6743次
    • 积分:131
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:8篇
    • 译文:0篇
    • 评论:0条
    文章分类