1. Écrivez les éléments de configuration
#微信支付接口 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. Le scénario de test Java appelle le paiement tiers WeChat, où payProp est l'élément de configuration,
@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. Le paiement est réussi, l'interface de rappel
@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. La classe d'aide XmlUtil utilisée est jointe avec le 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 Le code impliqué dans l'outil de génération et de vérification de signature. classe
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)); } }
Recommandations associées :
Analyse d'instance d'appel de la fonction de paiement WeChat en Java
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!