zoukankan      html  css  js  c++  java
  • mui 微信支付 与springMVC服务器交互

    昨天搞定了微信支付,没有想象中的难,主要是官方的demo不全好多东西要自己琢磨,mui端的就不写了支付宝的有了一模一样.上java端的首先是jar包

    一个是用来解析xml文件

    一个是用来解析json

    当然可以替代

    然后是工具类当然并不是全都用的到.

    ===============================================================================================================

    public class ConfigUtil {

    /**
    * 服务号相关信息
    */
    public final static String APPID = "****";// 服务号的应用号
    public final static String MCH_ID = "*****";// 商户号
    public final static String API_KEY = "******";// API密钥
    public final static String SIGN_TYPE = "MD5";// 签名加密方式

    public final static String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    }

    ===============================================================================================================

    /**
    * md5加密
    *
    * @author Administrator
    *
    */
    public class MD5Util {

    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 hexDigits[d1] + hexDigits[d2];
    }

    public static String MD5Encode(String origin, String charsetname) {
    String resultString = null;
    try {
    resultString = new String(origin);
    MessageDigest md = MessageDigest.getInstance("MD5");
    if (charsetname == null || "".equals(charsetname))
    resultString = byteArrayToHexString(md.digest(resultString
    .getBytes()));
    else
    resultString = byteArrayToHexString(md.digest(resultString
    .getBytes(charsetname)));
    } catch (Exception exception) {
    }
    return resultString;
    }

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

    }

    ===============================================================================================================


    /**
    * 信任管理器
    */
    public class MyX509TrustManager implements X509TrustManager {

    // 检查客户端证书
    public void checkClientTrusted(X509Certificate[] chain, String authType)
    throws CertificateException {
    }

    // 检查服务器端证书
    public void checkServerTrusted(X509Certificate[] chain, String authType)
    throws CertificateException {
    }

    // 返回受信任的X509证书数组
    public X509Certificate[] getAcceptedIssuers() {
    return null;
    }

    ===============================================================================================================

    /**
    * 解析mxl
    *
    * @author Administrator
    *
    */
    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();
    }

    }

    ===============================================================================================================

    /**
    * 支付公共工具
    *
    * @author Administrator
    *
    */
    public class PayCommonUtil {

    /**
    * 创建临时字符串
    *
    * @param length
    * 创建长度
    * @return 该长度的随机字符串
    */
    public static String CreateNoncestr(int length) {
    String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    String res = "";
    for (int i = 0; i < length; i++) {
    Random rd = new Random();
    res += chars.indexOf(rd.nextInt(chars.length() - 1));
    }
    return res;
    }

    /**
    * 创建随机字符串16位
    *
    * @return
    */
    public static String CreateNoncestr() {
    String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    String res = "";
    for (int i = 0; i < 16; i++) {
    Random rd = new Random();
    res += chars.charAt(rd.nextInt(chars.length() - 1));
    }
    return res;
    }

    /**
    * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
    *
    * @return boolean
    */
    public static boolean isTenpaySign(String characterEncoding,
    SortedMap<Object, Object> packageParams) {
    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=" + ConfigUtil.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);
    }

    /**
    * @Description:sign签名
    * @param characterEncoding
    * 编码格式
    * @param parameters
    * 请求参数
    * @return
    */
    public static String createSign(String characterEncoding,
    SortedMap<Object, Object> parameters) {
    // 签名字符串
    StringBuffer sb = new StringBuffer();
    // 遍历map集合
    Set es = parameters.entrySet();
    Iterator it = es.iterator();
    while (it.hasNext()) {
    Map.Entry entry = (Map.Entry) it.next();
    String k = (String) entry.getKey();
    Object v = entry.getValue();
    if (null != v && !"".equals(v) && !"sign".equals(k)
    && !"key".equals(k)) {
    sb.append(k + "=" + v + "&");
    }
    }
    sb.append("key=" + ConfigUtil.API_KEY);
    System.out.println(sb + "=================sign签名字符串");
    String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding)
    .toUpperCase();
    return sign;
    }

    /**
    * @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)) {
    sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
    } else {
    sb.append("<" + k + ">" + v + "</" + k + ">");
    }
    }
    sb.append("</xml>");
    return sb.toString();
    }

    /**
    * @Description:返回给微信的参数
    * @param return_code
    * 返回编码
    * @param return_msg
    * 返回信息
    * @return
    */
    public static String setXML(String return_code, String return_msg) {
    return "<xml><return_code><![CDATA[" + return_code
    + "]]></return_code><return_msg><![CDATA[" + return_msg
    + "]]></return_msg></xml>";
    }

    /**
    * 发送https请求
    *
    * @param requestUrl
    * 请求地址
    * @param requestMethod
    * 请求方式(GET、POST)
    * @param outputStr
    * 提交的数据
    * @return 返回微信服务器响应的信息
    */
    public static String httpsRequest(String requestUrl, String requestMethod,
    String outputStr) {
    try {
    // 创建SSLContext对象,并使用我们指定的信任管理器初始化
    TrustManager[] tm = { new MyX509TrustManager() };
    SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
    sslContext.init(null, tm, new java.security.SecureRandom());
    // 从上述SSLContext对象中得到SSLSocketFactory对象
    SSLSocketFactory ssf = sslContext.getSocketFactory();
    URL url = new URL(requestUrl);
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    // conn.setSSLSocketFactory(ssf);
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setUseCaches(false);
    // 设置请求方式(GET/POST)
    conn.setRequestMethod(requestMethod);
    conn.setRequestProperty("content-type",
    "application/x-www-form-urlencoded");
    // 当outputStr不为null时向输出流写数据
    if (null != outputStr) {
    OutputStream outputStream = conn.getOutputStream();
    // 注意编码格式
    outputStream.write(outputStr.getBytes("UTF-8"));
    outputStream.close();
    }
    // 从输入流读取返回内容
    InputStream inputStream = conn.getInputStream();
    InputStreamReader inputStreamReader = new InputStreamReader(
    inputStream, "UTF-8");
    BufferedReader bufferedReader = new BufferedReader(
    inputStreamReader);
    String str = null;
    StringBuffer buffer = new StringBuffer();
    while ((str = bufferedReader.readLine()) != null) {
    buffer.append(str);
    }
    // 释放资源
    bufferedReader.close();
    inputStreamReader.close();
    inputStream.close();
    inputStream = null;
    conn.disconnect();
    return buffer.toString();
    } catch (ConnectException ce) {
    // log.error("连接超时:{}", ce);
    } catch (Exception e) {
    // log.error("https请求异常:{}", e);
    }
    return null;
    }

    /**
    * 发送https请求
    *
    * @param requestUrl
    * 请求地址
    * @param requestMethod
    * 请求方式(GET、POST)
    * @param outputStr
    * 提交的数据
    * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
    */
    public static JSONObject httpsRequest(String requestUrl,
    String requestMethod) {
    JSONObject jsonObject = null;
    try {
    // 创建SSLContext对象,并使用我们指定的信任管理器初始化
    TrustManager[] tm = { new MyX509TrustManager() };
    SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
    sslContext.init(null, tm, new java.security.SecureRandom());
    // 从上述SSLContext对象中得到SSLSocketFactory对象
    SSLSocketFactory ssf = sslContext.getSocketFactory();
    URL url = new URL(requestUrl);
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    // conn.setSSLSocketFactory(ssf);
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setUseCaches(false);
    conn.setConnectTimeout(3000);
    // 设置请求方式(GET/POST)
    conn.setRequestMethod(requestMethod);
    // conn.setRequestProperty("content-type",
    // "application/x-www-form-urlencoded");
    // 当outputStr不为null时向输出流写数据
    // 从输入流读取返回内容
    InputStream inputStream = conn.getInputStream();
    InputStreamReader inputStreamReader = new InputStreamReader(
    inputStream, "UTF-8");
    BufferedReader bufferedReader = new BufferedReader(
    inputStreamReader);
    String str = null;
    StringBuffer buffer = new StringBuffer();
    while ((str = bufferedReader.readLine()) != null) {
    buffer.append(str);
    }
    // 释放资源
    bufferedReader.close();
    inputStreamReader.close();
    inputStream.close();
    inputStream = null;
    conn.disconnect();

    jsonObject = JSONObject.parseObject(buffer.toString());
    } catch (ConnectException ce) {
    // log.error("连接超时:{}", ce);
    } catch (Exception e) {
    System.out.println(e);
    // log.error("https请求异常:{}", e);
    }
    return jsonObject;
    }

    public static String urlEncodeUTF8(String source) {
    String result = source;
    try {
    result = java.net.URLEncoder.encode(source, "utf-8");
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    return result;
    }

    /**
    * 获取ip地址
    *
    * @param request
    * @return
    */
    public static String getIpAddr(HttpServletRequest request) {
    InetAddress addr = null;
    try {
    addr = InetAddress.getLocalHost();
    } catch (UnknownHostException e) {
    return request.getRemoteAddr();
    }
    byte[] ipAddr = addr.getAddress();
    String ipAddrStr = "";
    for (int i = 0; i < ipAddr.length; i++) {
    if (i > 0) {
    ipAddrStr += ".";
    }
    ipAddrStr += ipAddr[i] & 0xFF;
    }
    return ipAddrStr;
    }
    }

    ===============================================================================================================

     最后是java请求接口

    /**
    * 微信支付接口
    *
    * @param req
    * @param resp
    * @return 返回字符串给app由app调用微信支付功能
    */
    @ResponseBody
    @RequestMapping(value = "/wxPrePay", produces = "text/html;charset=UTF-8", method = { RequestMethod.GET })
    public String wxPrePay(HttpServletRequest request,
    HttpServletResponse response) {
    String str = null;

    // 金额单位转换成元
    int price100 = new BigDecimal(0.01).multiply(new BigDecimal(100))
    .intValue();
    if (price100 <= 0) {

    return "付款金额错误";
    }
    // 设置回调地址-获取当前的地址拼接回调地址
    String url = request.getRequestURL().toString();
    String domain = url.substring(0, url.length() - 13);
    // 生产环境
    String notify_url = domain + "wxNotify.html";
    // 测试环境
    // String notify_url =
    // "http://1f504p5895.51mypc.cn/cia/app/wxNotify.html";

    SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
    parameters.put("appid", ConfigUtil.APPID);// appid
    parameters.put("mch_id", ConfigUtil.MCH_ID);// 商户id
    parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());// 随机字符串
    parameters.put("body", "购买测试");// 商品描述
    parameters.put("out_trade_no", PayCommonUtil.CreateNoncestr(6)); // 订单唯一id
    parameters.put("fee_type", "CNY");// 支付方式
    parameters.put("total_fee", String.valueOf(price100));// 总金额
    parameters.put("spbill_create_ip", PayCommonUtil.getIpAddr(request));// 获取ip地址
    parameters.put("notify_url", notify_url);// 回调地址
    parameters.put("trade_type", "APP");// 交易类型
    // 设置签名
    String sign = PayCommonUtil.createSign("UTF-8", parameters);
    parameters.put("sign", sign);
    // 封装请求参数成xml字符串
    String requestXML = PayCommonUtil.getRequestXml(parameters);
    // 调用统一下单接口返回prepay_id
    String result = PayCommonUtil.httpsRequest(
    ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXML);
    System.out.println(" " + result);
    try {
    /**
    * 统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,
    * partnerId
    * ,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
    **/
    Map<String, String> map = XMLUtil.doXMLParse(result);

    SortedMap<Object, Object> parameterMap2 = new TreeMap<Object, Object>();
    parameterMap2.put("appid", ConfigUtil.APPID);
    parameterMap2.put("partnerid", ConfigUtil.MCH_ID);
    parameterMap2.put("prepayid", map.get("prepay_id"));
    parameterMap2.put("package", "Sign=WXPay");
    parameterMap2.put("noncestr", PayCommonUtil.CreateNoncestr());
    // 本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下
    parameterMap2.put(
    "timestamp",
    Long.parseLong(String.valueOf(System.currentTimeMillis())
    .toString().substring(0, 10)));
    String sign2 = PayCommonUtil.createSign("UTF-8", parameterMap2);
    parameterMap2.put("sign", sign2);

    str = JSON.toJSONString(parameterMap2);

    } catch (JDOMException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    return str;
    }

  • 相关阅读:
    spring-102-spring全注解快速实现事务
    spring-101-springAOP
    spring-201-springmvc基于MappingJacksonValue 实现JSONP
    啥是JSONP---转
    request.getSession(boolean create)的正确使用姿势
    spring-003-Resource资源
    spring-002-Ioc bean配置
    spring-001-Ioc 顶层容器
    为企业提供免费代码安全扫描服务(每月限一次)
    圆满完成平安科技Web安全与App应用安全测试培训!
  • 原文地址:https://www.cnblogs.com/tjwrth-juglans/p/7644198.html
Copyright © 2011-2022 走看看