1. 写好配置项
#微信支付接口ias.pay.wxpay.payurl=https://api.mch.weixin.qq.com/pay/unifiedorder#回调地址ias.pay.wxpay.notifyurl=#终端ipias.pay.wxpay.spbillcreateip=ias.pay.wxpay.appid=ias.pay.wxpay.mchid=ias.pay.wxpay.tradetype=appias.pay.wxpay.packages=sign=wxpayias.pay.wxpay.key=
2. java测试用例调用微信第三方支付,其中的payprop为配置项,
@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。支付成功,回调接口
@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.其中用到的xmlutil帮助类附上代码
/** * 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. 涉及到的生成签名和验签工具类代码
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,'&'); 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)); }}
相关推荐:
微信支付的测试目录不能用来测试扫码支付吗?
java中调用微信支付功能的实例分析
以上就是java测试用例调用微信第三方支付(完整代码)的详细内容。