Home  >  Article  >  Java  >  Java test case calls WeChat third-party payment (complete code)

Java test case calls WeChat third-party payment (complete code)

php是最好的语言
php是最好的语言Original
2018-08-08 09:59:144571browse

1. Write the configuration items

#微信支付接口
ias.pay.wxpay.payUrl=https://api.mch.weixin.qq.com/pay/unifiedorder
#回调地址
ias.pay.wxpay.notifyUrl=
#终端IP
ias.pay.wxpay.spbillCreateIp=
ias.pay.wxpay.appId=
ias.pay.wxpay.mchId=
ias.pay.wxpay.tradeType=APP
ias.pay.wxpay.packages=Sign=WXPay
ias.pay.wxpay.key=

2. The java test case calls WeChat third-party payment, where payProp is the configuration item,

	@Autowired
	private PayProp payProp;
	
	@Test
	public void createPay() {
		WxPay wxPay = new WxPay();
		wxPay.setPayUrl(payProp.getWxpay().getPayUrl());
		wxPay.setAppId(payProp.getWxpay().getAppId());
		wxPay.setMchId(payProp.getWxpay().getMchId());
		wxPay.setSpbillCreateIp(payProp.getWxpay().getSpbillCreateIp());
		wxPay.setNotifyUrl(payProp.getWxpay().getNotifyUrl());
		wxPay.setTradeType(payProp.getWxpay().getTradeType());
		wxPay.setKey(payProp.getWxpay().getKey());
		wxPay.setBody("腾讯充值中心-QQ会员充值");
		wxPay.setNonceStr(随机字符串,长度要求在32位以内。);
		wxPay.setOutTradeNo(订单号);
		wxPay.setTotalFee(支付金额);
		wxPay.setSign(WeiXinUtil.sign(wxPay, wxPay.getKey()));
		String xml = XmlUtil.toXml(wxPay);
		log.debug("微信支付xml为:\n{}", xml);
		
		String results = RestClient.getClient().postForObject(wxPay.getPayUrl(), xml, String.class);
		log.debug("返回的xml:\n{}", results.toString());
		WXResults wxResults = XmlUtil.toBean(results, WXResults.class);
		if(StringUtil.equals(wxResults.getReturnCode(), "SUCCESS")) {
			log.debug("返回信息", wxResults.toString());
		} else {
			throw new BusinessException(30010, wxResults.getReturnMsg());
		}
	}

3. The payment is successful, the callback interface

	@RequestMapping(value="wxpay/notify", produces={"application/xml"})
    public String notify(@RequestBody String callback) throws DocumentException {
		log.debug("微信支付回调xml为:{}", callback);
		WxNotify notify = XmlUtil.toBean(callback, WxNotify.class);
		if(notify.getReturnCode().equals("SUCCESS") || notify.getResultCode().equals("SUCCESS")) {
			Map<String, Object> map =  XmlUtil.xml2map(callback, false);
				boolean signVerified = WeiXinUtil.isWechatSign(map, payProp.getWxpay().getKey());
				if(signVerified) {
					log.info("微信支付验签成功!!!");
					log.info("微信支付完成!!!!!");
				}
		}
		return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    }

4. The XmlUtil help class used is attached with the code

    /** 
     * xml转map 不带属性 
     * @param xmlStr 
     * @param needRootKey 是否需要在返回的map里加根节点键 
     * @return 
     * @throws DocumentException 
     */  
    public static Map<String,Object> xml2map(String xmlStr, boolean needRootKey) throws DocumentException {  
        Document doc = DocumentHelper.parseText(xmlStr);  
        Element root = doc.getRootElement();  
        Map<String, Object> map = xml2map(root);  
        if(root.elements().size()==0 && root.attributes().size()==0){  
            return map;  
        }  
        if(needRootKey){  
            //在返回的map里加根节点键(如果需要)  
            Map<String, Object> rootMap = new HashMap<String, Object>();  
            rootMap.put(root.getName(), map);  
            return rootMap;  
        }  
        return map;  
    } 
    /**
     *  将传入xml文本转换成Java对象
     * @Title: toBean 
     * @param xmlStr
     * @param cls  xml对应的class类
     * @return T   xml对应的class类的实例对象
     * 
     * 调用的方法实例:PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);
     */
	public static <T> T  toBean(String xmlStr,Class<T> cls){
        //注意:不是new Xstream(); 否则报错:java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory
        XStream xstream=new XStream(new DomDriver());
        xstream.processAnnotations(cls);
        T obj=(T)xstream.fromXML(xmlStr);
        return obj;            
    }

5. The code involved in the signature generation and verification tool class

package com.ias.server.pay.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ias.common.utils.bean.ClassUtil;
import com.ias.common.utils.collection.ArrayUtils;
import com.ias.common.utils.date.TimeUtil;
import com.ias.common.utils.encrypt.MD5Util;
import com.ias.common.utils.string.StringUtil;
import com.ias.server.pay.annotations.Sign;

public class WeiXinUtil {
	
	private static final Logger log = LoggerFactory.getLogger(WeiXinUtil.class);
	
	/** 
	 * 微信支付签名
	 * @author: jiuzhou.hu
	 * @date:2017年3月15日下午12:54:52 
	 * @param obj
	 * @param keyStr
	 * @return
	 */
	public static String sign(Object obj, String keyStr) {
		Map<String, String> fields = new HashMap<>();
		for(Field field : obj.getClass().getDeclaredFields()) {
			Sign sign = field.getAnnotation(Sign.class);
			if(field.getAnnotation(Sign.class) != null) {
				fields.put(field.getName(), sign.value());
			}
		}
		
		List<String> signs = new ArrayList<>();
		for(String key:fields.keySet()) {
			Object ov = ClassUtil.getFieldValue(obj, key);
			if(ov != null) {
				signs.add(fields.get(key) + "=" + ov);
			}
		}
		signs.sort((String s1, String s2) -> s1.compareTo(s2));
		signs.add("key=" + keyStr);
		String _signs = ArrayUtils.toString(signs,&#39;&&#39;);
		log.debug("未加密的sign串为:{}", _signs);
		String md5Sign = MD5Util.encode(_signs).toUpperCase();
		log.debug("md5加密过的sign串为:{}", md5Sign);
		return md5Sign;
	}
	
	/**
	 * 微信验签
	 * @author feng.ye
	 * @date 2018年7月19日 下午1:27:27
	 * @param map 
	 * @param apiKey
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isWechatSign(Map<String, Object> map,String apiKey) {
	     StringBuffer sb = new StringBuffer();
	     Set es = map.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) && !"key".equals(k)) {
	             sb.append(k + "=" + v + "&");
	         }
	     }
	     sb.append("key=" + apiKey);
	     String sign = MD5Util.encode(sb.toString()).toUpperCase();
	     log.debug("新生成签名为:{}", sign);
	     String validSign = ((String) map.get("sign")).toUpperCase();
	     log.debug("微信端返回签名为:{}", validSign);
	     if(StringUtil.isNotBlank(validSign) && StringUtil.equals(sign, validSign)) {
	    	 return true;
	     }else {
	    	 return false;
	     }
	 }
	
	/** 
	 * 获取10位时间戳
	 * @author: jiuzhou.hu
	 * @date:2017年3月15日下午1:17:49 
	 * @return
	 */
	public static long timestamp() {
		return Long.parseLong(String.valueOf(TimeUtil.getSysTimestamp().getTime()).toString().substring(0,10));
	}
}

Related recommendations:

Can’t the test directory of WeChat payment be used to test scan code payment?

Instance analysis of calling WeChat payment function in Java

The above is the detailed content of Java test case calls WeChat third-party payment (complete code). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn