Java

微信公众号支付

2019-11-22  本文已影响0人  Liuluckyzz

最近在做一个项目中的一个小功能是关于微信支付的,在这里总结一下代码

微信支付:

//C端微信支付
    public String CDWeiXinPay(HttpServletRequest request,
                              HttpServletResponse response) {
        Map<String, String> map = getRequestParams(request);
        CallResult result = new CallResult();
        try {
            String paramContent = "";
            String sign = "";
            String nonceStr = CheckUtil.generateNonceStr();
            Map<String, String> param = new HashMap<>();
            param.put("appid", WeiXinConst.APPID); //公众号id
            param.put("mch_id", WeiXinConst.MCHID);//商户平台id
            param.put("device_info", "WEB");
            param.put("nonce_str", nonceStr);
            param.put("body", "蚁传播公众号支付");//订单标题
            param.put("out_trade_no", map.get("orderId"));//订单ID
            param.put("total_fee",  map.get("payAmount")); //订单需要支付的金额
            param.put("trade_type", "JSAPI");//交易类型 JSAPI 公众号支付 NATIVE 扫码支付 APP APP支付
            param.put("notify_url",WeiXinConst.cd_notify_url);//notify_url 支付成功之后 微信会进行异步回调的地址
            param.put("openid", map.get("openId"));//微信授权获取openId
            param.put("sign_type", "MD5");
            sign = WXPayUtil.generateSignature(param,WeiXinConst.KEY);
            param.put("sign", sign);
            paramContent = WXPayUtil.mapToXml(param);
            String s = OkHttpUtil.getInstance().doPost(WeiXinConst.sm_weiXinPay_url, paramContent);//微信支付路径
            Map<String, String> returnResult = WXPayUtil.xmlToMap(s);
            String prepay_id;
            HashMap<String, String> pageParam = new HashMap<>();
            if (returnResult.get("return_code").equals("SUCCESS") && returnResult.get("result_code").equals("SUCCESS")) {
                prepay_id = returnResult.get("prepay_id");
                String timestamp = CheckUtil.create_timestamp();
                pageParam.put("appId", WeiXinConst.APPID);
                pageParam.put("nonceStr", nonceStr);
                pageParam.put("package", "prepay_id=" + prepay_id);
                pageParam.put("timeStamp", timestamp);
                pageParam.put("signType", "MD5");
                String pageSign =WXPayUtil.generateSignature(pageParam,WeiXinConst.KEY);
                pageParam.put("paySign", pageSign);
                pageParam.put("prepay_id", prepay_id);
                result.addSuccess("请求成功");
            } else {
                result.addError("请求失败");
            }
            result.setData(pageParam);
            System.out.println("--------------------"+JsonUtil.transformObject(result)+"--------------------------------------");
            logger.info(result);
        } catch (Exception e) {
            logger.error(e.toString(), e);
            result.addError("服务器异常:" + e.getMessage());
        }
        return JsonUtil.transformObject(result);
    }
public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }
public class OkHttpUtil {
    private static OkHttpUtil okHttpUtil;
    private static OkHttpClient okHttpClient;
    private OkHttpUtil() {
        /**
         * OkHttp是一个第三方类库,
         * 用于android中请求网络
         * 创建OkHttpClient对象
         */
        okHttpClient = new OkHttpClient();
    }
    public static OkHttpUtil getInstance() {
        if (okHttpUtil == null) {
            okHttpUtil = new OkHttpUtil();
        }
        return okHttpUtil;
    }

    public String doGet(String url) {
        /**
         * 请求接口
         * 创建Request对象
         */
        Request request = new Request.Builder()
                .url(url)
                .build();
        //得到request对象
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String doPost(String url, Map<String, String> param) {
        FormBody.Builder builder = new FormBody.Builder();
        for (Map.Entry<String, String> entry : param.entrySet()) {
            builder.add(entry.getKey(), entry.getValue());
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String doPostParam(String url, Map<String, Object> param) {
        FormBody.Builder builder = new FormBody.Builder();
        for (Map.Entry<String, Object> entry : param.entrySet()) {
            builder.add(entry.getKey(), (String) entry.getValue());
        }
        RequestBody body = builder.build();
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String doPost(String url, String param) {
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSON, param);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Call call = okHttpClient.newCall(request);
        try {
            Response response = call.execute();
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
public class CheckUtil {
    /**
     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
     * @param data 待签名数据
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
        if (WXPayConstants.SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        }
        else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        }
        else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }
    /**
     * 通过HttpServletRequest返回IP地址
     * @param request HttpServletRequest
     * @return ip String
     * @throws Exception
     */
    public static String getIpAddr(HttpServletRequest request) throws Exception {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }
    public static String getXMLFromMap(Map<String, String> map) throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set<String> set = map.keySet();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String key = it.next();
            sb.append("<" + key + ">").append(map.get(key)).append("</" + key + ">");
        }
        sb.append("</xml>");
        return sb.toString();
    }
    /**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            throw ex;
        }
    }
    public static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
上面代码里WeiXinConst实体类中主要是配置了微信支付的一系列的参数。微信支付中所需要的参数都可以写到这个实体类中,在支付成功之后微信会自动回调我们在上面配置的微信回调地址,进行支付成功之后的操作。
上一篇下一篇

猜你喜欢

热点阅读