微信支付(APP)

微信支付

工具类(用于在微信支付服务后台生成预支付交易单)

package com.fengdi.lianmeng.zhifu.weixin;

import com.fengdi.lianmeng.util.MD5;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * 类说明:除被扫支付场景以外,店铺系统先调用该接口在微信支付服务后台生成预支付交易单,
 * 返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。
 */
public class UnifiedorderReq{

	/**
	 * 公众账号ID
	 */
	private String appid;
	/**
	 * 店铺号
	 */
	private String mch_id;
	/**
	 * 设备号
	 */
	private String device_info;
	/**
	 * 随机字符串
	 */
	private String nonce_str;
	/**
	 * 签名
	 */
	private String sign;
	/**
	 * 商品描述
	 */
	private String body;
	/**
	 * 商品详情
	 */
	private String detail;
	/**
	 * 附加数据
	 */
	private String attach;
	/**
	 * 店铺订单号
	 */
	private String out_trade_no;
	/**
	 * 货币类型
	 */
	private String fee_type;
	/**
	 * 总金额
	 */
	private Integer total_fee;
	/**
	 * 终端IP
	 */
	private String spbill_create_ip;
	/**
	 * 交易起始时间
	 */
	private String time_start;
	/**
	 * 交易结束时间
	 */
	private String time_expire;
	/**
	 * 商品标记
	 */
	private String goods_tag;
	/**
	 * 通知地址
	 */
	private String notify_url;
	/**
	 * 交易类型
	 */
	private String trade_type;
	/**
	 * 商品ID
	 */
	private String product_id;
	/**
	 * 指定支付方式
	 */
	private String limit_pay;
	/**
	 * 用户标识
	 */
	private String openid;
	public String getAppid() {
		return appid;
	}
	public void setAppid(String appid) {
		this.appid = appid;
	}
	public String getMch_id() {
		return mch_id;
	}
	public void setMch_id(String mch_id) {
		this.mch_id = mch_id;
	}
	public String getDevice_info() {
		return device_info;
	}
	public void setDevice_info(String device_info) {
		this.device_info = device_info;
	}
	public String getNonce_str() {
		return nonce_str;
	}
	public void setNonce_str(String nonce_str) {
		this.nonce_str = nonce_str;
	}
	public String getSign() {
		return sign;
	}
	public void setSign(String sign) {
		this.sign = sign;
	}
	public String getBody() {
		return body;
	}
	public void setBody(String body) {
		this.body = body.length()>40?body.substring(0, 40):body;
	}
	public String getDetail() {
		return detail;
	}
	public void setDetail(String detail) {
		this.detail = detail;
	}
	public String getAttach() {
		return attach;
	}
	public void setAttach(String attach) {
		this.attach = attach;
	}
	public String getOut_trade_no() {
		return out_trade_no;
	}
	public void setOut_trade_no(String out_trade_no) {
		this.out_trade_no = out_trade_no;
	}
	public String getFee_type() {
		return fee_type;
	}
	public void setFee_type(String fee_type) {
		this.fee_type = fee_type;
	}
	public Integer getTotal_fee() {
		return total_fee;
	}
	public void setTotal_fee(Integer total_fee) {
		this.total_fee = total_fee;
	}
	public String getSpbill_create_ip() {
		return spbill_create_ip;
	}
	public void setSpbill_create_ip(String spbill_create_ip) {
		this.spbill_create_ip = spbill_create_ip;
	}
	public String getTime_start() {
		return time_start;
	}
	public void setTime_start(String time_start) {
		this.time_start = time_start;
	}
	public String getTime_expire() {
		return time_expire;
	}
	public void setTime_expire(String time_expire) {
		this.time_expire = time_expire;
	}
	public String getGoods_tag() {
		return goods_tag;
	}
	public void setGoods_tag(String goods_tag) {
		this.goods_tag = goods_tag;
	}
	public String getNotify_url() {
		return notify_url;
	}
	public void setNotify_url(String notify_url) {
		this.notify_url = notify_url;
	}
	public String getTrade_type() {
		return trade_type;
	}
	public void setTrade_type(String trade_type) {
		this.trade_type = trade_type;
	}
	public String getProduct_id() {
		return product_id;
	}
	public void setProduct_id(String product_id) {
		this.product_id = product_id;
	}
	public String getLimit_pay() {
		return limit_pay;
	}
	public void setLimit_pay(String limit_pay) {
		this.limit_pay = limit_pay;
	}
	public String getOpenid() {
		return openid;
	}
	public void setOpenid(String openid) {
		this.openid = openid;
	}
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("UnifiedorderReq [appid=");
		builder.append(appid);
		builder.append(", mch_id=");
		builder.append(mch_id);
		builder.append(", device_info=");
		builder.append(device_info);
		builder.append(", nonce_str=");
		builder.append(nonce_str);
		builder.append(", sign=");
		builder.append(sign);
		builder.append(", body=");
		builder.append(body);
		builder.append(", detail=");
		builder.append(detail);
		builder.append(", attach=");
		builder.append(attach);
		builder.append(", out_trade_no=");
		builder.append(out_trade_no);
		builder.append(", fee_type=");
		builder.append(fee_type);
		builder.append(", total_fee=");
		builder.append(total_fee);
		builder.append(", spbill_create_ip=");
		builder.append(spbill_create_ip);
		builder.append(", time_start=");
		builder.append(time_start);
		builder.append(", time_expire=");
		builder.append(time_expire);
		builder.append(", goods_tag=");
		builder.append(goods_tag);
		builder.append(", notify_url=");
		builder.append(notify_url);
		builder.append(", trade_type=");
		builder.append(trade_type);
		builder.append(", product_id=");
		builder.append(product_id);
		builder.append(", limit_pay=");
		builder.append(limit_pay);
		builder.append(", openid=");
		builder.append(openid);
		builder.append("]");
		return builder.toString();
	}
	
	public String toSignString(){
		Class<?> clz = this.getClass();
		Field[] fields = clz.getDeclaredFields();
		StringBuilder builder = new StringBuilder();
		for (Field field : fields) {
			builder.append(field.getName());
		}
		return builder.toString();
	}
	
	public String signString(){
		StringBuilder builder = new StringBuilder();
		builder.append("appid="+appid);
		if(attach!=null){
			builder.append("&attach="+attach);
		}
		builder.append("&body="+body);
		builder.append("&mch_id="+mch_id);
		builder.append("&nonce_str="+nonce_str);
		builder.append("&notify_url="+notify_url);
		if(!trade_type.equals("APP")) {
			builder.append("&openid="+openid);
		}
		builder.append("&out_trade_no="+out_trade_no);
		builder.append("&spbill_create_ip="+spbill_create_ip);
		builder.append("&total_fee="+total_fee);
		builder.append("&trade_type="+trade_type);
		builder.append("&key="+FgWxConfig.mobilekey);
		return builder.toString();
	}
	
	public String wapSignString(){
		StringBuilder builder = new StringBuilder();
		builder.append("appid="+appid);
		if(attach!=null){
			builder.append("&attach="+attach);
		}
		builder.append("&body="+body);
		builder.append("&mch_id="+mch_id);
		builder.append("&nonce_str="+nonce_str);
		builder.append("&notify_url="+notify_url);
		if(!trade_type.equals("APP")) {
			builder.append("&openid="+openid);
		}
		builder.append("&out_trade_no="+out_trade_no);
		builder.append("&spbill_create_ip="+spbill_create_ip);
		builder.append("&total_fee="+total_fee);
		builder.append("&trade_type="+trade_type);
		builder.append("&key="+FgWxConfig.key);
		return builder.toString();
	}
	
	public String toXml(){
		return "<xml>" +
		          "<appid>"+appid+"</appid>"+
		          (attach != null? "<attach>"+attach+"</attach>" : "")+
                 "<body>"+body+"</body>"+
                 "<mch_id>"+mch_id+"</mch_id>"+
                 "<nonce_str>"+nonce_str+"</nonce_str>"+
                 "<notify_url>"+notify_url+"</notify_url>"+
                 (trade_type.equals("APP") == true?"":"<openid>"+openid+"</openid>")+
                 "<out_trade_no>"+out_trade_no+"</out_trade_no>"+
                 "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
                 "<total_fee>"+total_fee+"</total_fee>"+
                 "<trade_type>"+trade_type+"</trade_type>"+
                 "<sign>"+MD5.encryptByMD5(signString()).toUpperCase()+"</sign>"+
                 "</xml>";
	}
	
	public String toWapXml(){
		return "<xml>" +
		          "<appid>"+appid+"</appid>"+
		          (attach != null? "<attach>"+attach+"</attach>" : "")+
                 "<body>"+body+"</body>"+
                 "<mch_id>"+mch_id+"</mch_id>"+
                 "<nonce_str>"+nonce_str+"</nonce_str>"+
                 "<notify_url>"+notify_url+"</notify_url>"+
                 (trade_type.equals("APP") == true?"":"<openid>"+openid+"</openid>")+
                 "<out_trade_no>"+out_trade_no+"</out_trade_no>"+
                 "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
                 "<total_fee>"+total_fee+"</total_fee>"+
                 "<trade_type>"+trade_type+"</trade_type>"+
                 "<sign>"+MD5.encryptByMD5(wapSignString()).toUpperCase()+"</sign>"+
                 "</xml>";
	}
	
	/*支付查询签名字符串*/
	public String signQueryString(String transaction_id){
		StringBuilder builder = new StringBuilder();
		builder.append("appid="+appid);
		builder.append("&body="+body);
		builder.append("&mch_id="+mch_id);
		builder.append("&nonce_str="+nonce_str);
		builder.append("&transaction_id="+transaction_id);
		builder.append("&key="+FgWxConfig.mobilekey);
		return builder.toString();
	}
	
	/*支付查询*/
	public String toQueryXml(String transaction_id){
		StringBuilder sBuilder=new StringBuilder();
		sBuilder.append("<xml>");
		sBuilder.append("<appid>"+appid+"</appid>");
		sBuilder.append("<body>"+body+"</body>");
		sBuilder.append("<mch_id>"+mch_id+"</mch_id>");
		sBuilder.append("<nonce_str>"+nonce_str+"</nonce_str>");
		sBuilder.append("<transaction_id>"+transaction_id+"</transaction_id>");
		sBuilder.append("<sign>"+MD5.encryptByMD5(signQueryString(transaction_id)).toUpperCase()+"</sign>");
		sBuilder.append("</xml>");
		return sBuilder.toString();
	}
	
	public Map<String,Object> toMap(){
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("appid", appid);
		if(attach!=null){
			params.put("attach", attach);
		}
		params.put("body", body);
		params.put("mch_id", mch_id);
		params.put("nonce_str", nonce_str);
		params.put("notify_url", notify_url);
		if(!trade_type.equals("APP")) {
			params.put("openid", openid);
		}
		params.put("out_trade_no", out_trade_no);
		params.put("spbill_create_ip", spbill_create_ip);
		params.put("total_fee", total_fee);
		params.put("trade_type", trade_type);
		params.put("sign", MD5.encryptByMD5(signString()).toUpperCase());
		return params;
	}

工具类(微信统一下单)

/**
	 * 微信支付应用下单接口(APP)
	 * @param unifiedorderReq
	 * @param payCategory
	 * @return
	 * @throws FdServiceException
	 */
	@Override
	public AppWeixinPayResponse appUnifiedorderReq(UnifiedorderReq unifiedorderReq, String payCategory) throws FdServiceException {
		AppWeixinPayResponse appWeixinPayResponse = new AppWeixinPayResponse();
		SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
		parameterMap.put("appid", FgWxConfig.appid_app);  //应用appid
		parameterMap.put("mch_id", FgWxConfig.mchId);  //商户号
		parameterMap.put("nonce_str", Random2Utils.generateString(20));//随机字符串
		parameterMap.put("body", "商品描述");
		parameterMap.put("out_trade_no", unifiedorderReq.getAttach());//订单号,自己后台生成
		parameterMap.put("fee_type", "CNY");//币种
		parameterMap.put("total_fee", unifiedorderReq.getTotal_fee());//支付金额
		parameterMap.put("spbill_create_ip", unifiedorderReq.getSpbill_create_ip());//id地址
		parameterMap.put("notify_url", fgProperties.getDomainUrl() + FgWxConfig.weixinOrderNotifyCallBack);//回调地址
		parameterMap.put("trade_type", "APP");//类型

		String sign = WxPayUtils.createSign("UTF-8", parameterMap);

		parameterMap.put("sign", sign);//签名
		String requestXML = WxPayUtils.getRequestXml(parameterMap);
		String result = FgHttp.sendPost(FgWxConfig.unifiedorderUrl, requestXML);
		Map<String, String> map = new HashMap<>();
		try {
			map = WxPayUtils.doXMLParse(result);
			if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
				logger.info("微信统一下单返回成功:" + map);
				appWeixinPayResponse.setAppid(FgWxConfig.appid_app);
				appWeixinPayResponse.setNoncestr(parameterMap.get("nonce_str").toString());
				appWeixinPayResponse.setPartnerid(FgWxConfig.mchId);
				appWeixinPayResponse.setPrepayid(map.get("prepay_id"));
				appWeixinPayResponse.setTimestamp((System.currentTimeMillis() + "").substring(0, 10));

				//以下为重新生成签名返回客户端,以便直接吊起支付
				SortedMap<String, Object> signParam = new TreeMap<>();
				signParam.put("appid", FgWxConfig.appid_app);
				signParam.put("noncestr", parameterMap.get("nonce_str").toString());
				signParam.put("package", "Sign=WXPay");
				signParam.put("partnerid", FgWxConfig.mchId);
				signParam.put("prepayid", map.get("prepay_id"));
				signParam.put("timestamp", appWeixinPayResponse.getTimestamp());
				appWeixinPayResponse.setSign(WxPayUtils.createSign("UTF-8", signParam));
			} else {
				logger.info("微信统一下单返回失败:" + map);
				throw new FdServiceException(ErrorCode.ILLEGAL_ARGUMENT, "微信统一下单返回失败:" + map.get("return_msg"));
			}
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return appWeixinPayResponse;
	}

工具类

package com.fengdi.lianmeng.util.tencent;

import com.fengdi.lianmeng.zhifu.weixin.FgWxConfig;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.*;

public class WxPayUtils {

    //生成签名
    public static String createSign(String characterEncoding, SortedMap<String,Object> parameters){
        StringBuffer sb = new StringBuffer();
        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=" + FgWxConfig.key);
        String sign = MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }

    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 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];
    }

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

    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 = getChildrenText(children);
            }

            m.put(k, v);
        }

        //关闭流
        in.close();

        return m;
    }

    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(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }
        return sb.toString();
    }

    //请求xml组装
    public static String getRequestXml(SortedMap<String,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 key = (String)entry.getKey();
            String value = entry.getValue().toString();
            if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {
                sb.append("<"+key+">"+"<![CDATA["+value+"]]></"+key+">");
            }else {
                sb.append("<"+key+">"+value+"</"+key+">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值