微信小程序服务商支付 java版

WeixinUtil.java

package com.belzee.zxw.utils;


import com.alibaba.fastjson.JSONObject;
import com.belzee.zxw.model.WeixinTemplate;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.*;


/** 微信工具类*/
public class WeiXinUtils {
	protected static  Logger logger = LoggerFactory.getLogger(WeiXinUtils.class);

	/** appId*/
	public static final String APPID = "";

	/*** 服务商统一下单 url*/
	private static final String mchPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	/*** 服务商id*/
	private static final String serverMchId="";

	/*** 服务号Appid*/
	private static final String serverAppId="";

	/*** 服务商ApiKey*/
	public static final String serverPayKey="";

	/** 交易类型*/
	private static final String tradeType="JSAPI";

	

	public static Map<String,String> toMchPay(String subMchId,String body,String detail,
											  String outTradeNo,Integer totalFee,String timeStart,
											  String subOpenid,String spbillCreateIp) {
		SortedMap<String,Object> map = new TreeMap<>();
		map.put("appid",serverAppId);
		map.put("mch_id",serverMchId);
		map.put("sub_appid",APPID);
		map.put("sub_mch_id",subMchId);
		map.put("nonce_str",PayUtil.create_nonce_str());
		map.put("body",body);
		//map.put("detail",detail);
		map.put("out_trade_no",outTradeNo);
		map.put("total_fee",totalFee+"");
		map.put("trade_type",tradeType);
		map.put("sub_openid",subOpenid);
		map.put("spbill_create_ip",spbillCreateIp);
		map.put("notify_url","https://www.xlcnp.cn/zzwweixinorder/notify");
		map.put("sign",PayUtil.createSign(map));
		Map<String, String> headers = new HashMap<>();
		headers.put("content-type", "application/json;charset=utf-8");
		String s = HttpClientUtils.sendPost(mchPayUrl, headers, PayUtil.getRequestXml(map), "utf-8");
		Map<String,String> returnMap = new HashMap<>();

		try {
			returnMap = PayUtil.doXMLParse(s);
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		logger.error("request:"+PayUtil.getRequestXml(map));

		logger.error("return:"+JSONObject.toJSONString(returnMap));
		return returnMap;
	}


}

Pay.Util

package com.belzee.zxw.utils;


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

/**
 * 支付工具类
 * @author Charlie
 * 2016年8月4日 上午9:18:09
 */
public class PayUtil {
    private static final String serverPayKey=WeiXinUtils.serverPayKey;

    /**
     * 获取随机字符串
     *
     * @return 2016年8月4日 上午9:26:07
     * @author Xuehao
     */
    public static String create_nonce_str() {
        String s = UUID.randomUUID().toString();
        // 去掉“-”符号
        return s.replaceAll("\\-", "").toUpperCase();
    }

    /**
     * 获取时间戳
     *
     * @return 2016年8月4日 上午9:26:20
     * @author Xuehao
     */
    public static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }


    /**
     * 构造签名
     *
     * @param params
     * @param encode
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String createSign(Map<String, String> params, boolean encode) throws UnsupportedEncodingException {
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuffer temp = new StringBuffer();
        boolean first = true;
        for (Object key : keys) {
            if (first) {
                first = false;
            } else {
                temp.append("&");
            }
            temp.append(key).append("=");
            Object value = params.get(key);
            String valueString = "";
            if (null != value) {
                valueString = value.toString();
            }
            if (encode) {
                temp.append(URLEncoder.encode(valueString, "UTF-8"));
            } else {
                temp.append(valueString);
            }
        }
        return temp.toString();
    }

    //生成签名
    public static String createSign(SortedMap<String, Object> parameters){
        StringBuilder sb = new StringBuilder();
        Set es = parameters.entrySet();
        for (Object e : es) {
            Map.Entry entry = (Map.Entry) e;
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k).append("=").append(v).append("&");
            }
        }
        sb.append("key=").append(serverPayKey);
        System.out.println(sb.toString());
        return MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
    }

    //请求xml组装
    public static String getRequestXml(SortedMap<String, Object> parameters){
        StringBuilder sb = new StringBuilder();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        for (Object e : es) {
            Map.Entry entry = (Map.Entry) e;
            String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            if ("attach".equalsIgnoreCase(key) || "body".equalsIgnoreCase(key) || "sign".equalsIgnoreCase(key)) {
                sb.append("<").append(key).append(">").append("<![CDATA[").append(value).append("]]></").append(key).append(">");
            } else {
                sb.append("<").append(key).append(">").append(value).append("</").append(key).append(">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }
    //xml解析
    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();
        for (Object aList : list) {
            Element e = (Element) aList;
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }
            m.put(k, v);
        }
        //关闭流
        in.close();
        return m;
    }
    private static String getChildrenText(List children) {
        StringBuilder sb = new StringBuilder();
        if(!children.isEmpty()) {
            for (Object aChildren : children) {
                Element e = (Element) aChildren;
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<").append(name).append(">");
                if (!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</").append(name).append(">");
            }
        }

        return sb.toString();
    }

    /**
     * 验证回调签名
     * @param map
     * @return
     */
    public static boolean isTenpaySign(Map<String, String> map) {
        String charset = "utf-8";
        String signFromAPIResponse = map.get("sign");
        if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {
            System.out.println("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
            return false;
        }
        System.out.println("服务器回包里面的签名是:" + signFromAPIResponse);
        //过滤空 设置 TreeMap
        SortedMap<String,String> packageParams = new TreeMap<>();
        for (String parameter : map.keySet()) {
            String parameterValue = map.get(parameter);
            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }
        StringBuilder sb = new StringBuilder();
        Set es = packageParams.entrySet();
        for (Object e : es) {
            Map.Entry entry = (Map.Entry) e;
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k).append("=").append(v).append("&");
            }
        }
        sb.append("key=").append(serverPayKey);
        //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
        //算出签名
        String tobesign = sb.toString();
        String resultSign = MD5Util.MD5Encode(tobesign, "utf-8").toUpperCase();
        String tenpaySign = packageParams.get("sign").toUpperCase();
        return tenpaySign.equals(resultSign);
    }


}

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值