精华内容
下载资源
问答
  • 1.微信支付异步回调接口@SuppressWarnings("static-access")@RequestMapping("callback")@ResponseBodypublic Object callback(HttpServletRequest request,HttpServletResponse response) throws Exception{...

    1.微信支付异步回调接口

    @SuppressWarnings("static-access")

    @RequestMapping("callback")

    @ResponseBody

    public Object callback(HttpServletRequest request,HttpServletResponse response) throws Exception{

    ResultBean result = new ResultBean();

    String inputLine="";

    String notityXml = "";

    try {

    while ((inputLine = request.getReader().readLine()) != null) {

    notityXml += inputLine;

    }

    request.getReader().close();

    } catch (Exception e) {

    e.printStackTrace();

    }

    System.out.println("异步回调XML信息:"+notityXml);

    if(!notityXml.isEmpty()){

    //解析并读取统一下单中的参数信息

    MapprepayMap = XmlUtil.getPrepayMapInfo(notityXml);

    if(!prepayMap.isEmpty()){

    String orderId = prepayMap.get("out_trade_no")+"";

    String resCode=prepayMap.get("result_code")+"";

    String returnCode=prepayMap.get("return_code")+"";

    System.out.println("解析并读取统一下单中的参数信息:"+orderId+"==="+resCode+"==="+returnCode);

    }

    //回调中业务逻辑完毕

    }else{

    result.fillCode(ResultBeanCodeEnum.OPERA_FAIL);

    }

    }else{

    result.fillCode(ResultBeanCodeEnum.OPERA_FAIL);

    }

    return result;

    }

    2.解析并读取统一下单中的参数信息工具类

    //解析xml

    public static  MapgetPrepayMapInfo(String Str)  {

    //解析并读取统一下单中的参数信息

    //1.去掉前后的xml标签

    String notityXml = Str.replaceAll("?xml>", "");

    System.out.println(notityXml);

    //2.匹配一段一段这样的数据

    Pattern pattern = Pattern.compile("");

    Matcher matcher = pattern.matcher(notityXml);

    //3.配置是否包含 CDATA 包裹的数据

    Pattern pattern2 = Pattern.compile("!.*]");

    MapmapInfo = new HashMap<>();

    while(matcher.find()) {

    //获取键

    String key = matcher.group().replaceAll(".*/", "");

    key = key.substring(0, key.length() - 1);

    Matcher matcher2 = pattern2.matcher(matcher.group());

    String value = matcher.group().replaceAll("?.*?>", "");

    //获取值

    if(matcher2.find() && !value.equals("DATA")) {

    value = matcher2.group().replaceAll("!.*\\[", "");

    value = value.substring(0, value.length() - 2);

    }

    mapInfo.put(key, value);

    }

    return mapInfo;

    }

    展开全文
  • /*** 微信支付接口实现** @create: 2019-10-10 15:40* @author: Sun*/@Service@Slf4jpublic class WxPayServiceImpl implements WxPayService {@Autowiredprivate MyWxPayConfig myWxPayConfig;@Overridepublic ...

    /**

    * 微信支付接口实现

    *

    * @create: 2019-10-10 15:40

    * @author: Sun

    */

    @Service

    @Slf4j

    public class WxPayServiceImpl implements WxPayService {

    @Autowired

    private MyWxPayConfig myWxPayConfig;

    @Override

    public String payAsyncNotifyVerificationSign(HttpServletRequest httpServletRequest) {

    WXPay wxPay = new WXPay(myWxPayConfig);

    String returnXmlMessage = null;

    String notifyXmlData = null;

    try {

    notifyXmlData = readXmlFromStream(httpServletRequest);

    Map notifyMapData = WXPayUtil.xmlToMap(notifyXmlData);

    log.info("[payAsyncNotifyVerificationSign] [xml转换为map数据成功] [notifyMapData:{}]", notifyMapData);

    // 验证签名

    boolean signatureValid = wxPay.isPayResultNotifySignatureValid(notifyMapData);

    if (signatureValid) {

    // TODO:订单支付成功之后相关业务逻辑...

    // 一切正常返回的xml数据

    returnXmlMessage = setReturnXml(WXPayConstants.SUCCESS, "OK");

    log.info("[payAsyncNotifyVerificationSign] [out_trade_no:{}] [支付成功异步消息处理成功:{}]", notifyMapData.get("out_trade_no"), returnXmlMessage);

    } else {

    returnXmlMessage = setReturnXml(WXPayConstants.FAIL, "Verification sign failed!");

    log.info("[payAsyncNotifyVerificationSign] [out_trade_no:{}] [验签失败:{}]", notifyMapData.get("out_trade_no"), returnXmlMessage);

    }

    } catch (IOException e) {

    log.error("[payAsyncNotifyVerificationSign] [读取微信服务器返回流中xml数据时发生异常:{}] ", ExceptionUtils.getStackTrace(e));

    returnXmlMessage = setReturnXml(WXPayConstants.FAIL, "An exception occurred while reading the WeChat server returning xml data in the stream.");

    } catch (Exception e) {

    log.error("[payAsyncNotifyVerificationSign] [xml数据:{}] [异常:{}] ", notifyXmlData, ExceptionUtils.getStackTrace(e));

    returnXmlMessage = setReturnXml(WXPayConstants.FAIL, "Payment successful, exception occurred during asynchronous notification processing.");

    log.warn("[payAsyncNotifyVerificationSign] [支付成功异步消息处理失败:{}]", returnXmlMessage);

    }

    return returnXmlMessage;

    }

    /**

    * 从流中读取微信返回的xml数据

    *

    * @param httpServletRequest

    * @return

    * @throws IOException

    */

    private String readXmlFromStream(HttpServletRequest httpServletRequest) throws IOException {

    InputStream inputStream = httpServletRequest.getInputStream();

    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

    final StringBuffer sb = new StringBuffer();

    String line = null;

    try {

    while ((line = bufferedReader.readLine()) != null) {

    sb.append(line);

    }

    } finally {

    bufferedReader.close();

    inputStream.close();

    }

    return sb.toString();

    }

    /**

    * 设置返回给微信服务器的xml信息

    *

    * @param returnCode

    * @param returnMsg

    * @return

    */

    private String setReturnXml(String returnCode, String returnMsg) {

    return "+ returnCode + "]]>+ returnMsg + "]]>";

    }

    }

    展开全文
  • java 微信支付异步回调接口

    千次阅读 2019-07-08 10:51:22
    1.微信支付异步回调接口 @SuppressWarnings("static-access") @RequestMapping("callback") @ResponseBody public Object callback(HttpServletRequest request,HttpServletResponse response) throws Exception...

    1.微信支付异步回调接口

    @SuppressWarnings("static-access")
        @RequestMapping("callback")
        @ResponseBody
        public Object callback(HttpServletRequest request,HttpServletResponse response) throws Exception{
            ResultBean result = new ResultBean();
            String inputLine="";
            String notityXml = "";
            try {
                while ((inputLine = request.getReader().readLine()) != null) {
                    notityXml += inputLine;
                }
                request.getReader().close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("异步回调XML信息:"+notityXml);
            if(!notityXml.isEmpty()){
                //解析并读取统一下单中的参数信息
                Map<String, Object> prepayMap = XmlUtil.getPrepayMapInfo(notityXml);
                if(!prepayMap.isEmpty()){
                    String orderId = prepayMap.get("out_trade_no")+"";
                    String resCode=prepayMap.get("result_code")+"";
                    String returnCode=prepayMap.get("return_code")+"";
                    System.out.println("解析并读取统一下单中的参数信息:"+orderId+"==="+resCode+"==="+returnCode);
                    }
                    //回调中业务逻辑完毕
                }else{
                    result.fillCode(ResultBeanCodeEnum.OPERA_FAIL);
                }
            }else{
                result.fillCode(ResultBeanCodeEnum.OPERA_FAIL);
            }
            return result;
        }

    2.解析并读取统一下单中的参数信息工具类

     //解析xml
        public static  Map<String, Object> getPrepayMapInfo(String Str)  {
            //解析并读取统一下单中的参数信息
            //1.去掉前后的xml标签
            String notityXml = Str.replaceAll("</?xml>", "");
            System.out.println(notityXml);
            //2.匹配一段一段这样的数据   <attach><![CDATA[支付测试]]></attach>
            Pattern pattern = Pattern.compile("<.*?/.*?>");
            Matcher matcher = pattern.matcher(notityXml);
            //3.配置是否包含<![CDATA[CNY]]> CDATA 包裹的数据
            Pattern pattern2 = Pattern.compile("!.*]");
            Map<String, Object> mapInfo = new HashMap<>();
            while(matcher.find()) {
                //获取键
                String key = matcher.group().replaceAll(".*/", "");
                key = key.substring(0, key.length() - 1);
                Matcher matcher2 = pattern2.matcher(matcher.group());
                String value = matcher.group().replaceAll("</?.*?>", "");
                //获取值
                if(matcher2.find() && !value.equals("DATA")) {
                    value = matcher2.group().replaceAll("!.*\\[", "");
                    value = value.substring(0, value.length() - 2);
                } 
                mapInfo.put(key, value);
            }
            return mapInfo;
        }

    展开全文
  • 前段时间做微信支付,微信浏览器填写金额商品名之后提交跳转付款页面确认然后返回界面判断,今天来详细说下   国际惯例先贴代码 mcontroller.java   public void wxpay() { if(this.getPara("openid&...

     

    前段时间做微信支付,微信浏览器填写金额商品名之后提交跳转付款页面确认然后返回界面判断,今天来详细说下

     

    国际惯例先贴代码

    mcontroller.java

     

    public void wxpay() {
            if(this.getPara("openid")==null){
            this.redirect(Conts.wxpayoauth.replace("*state*", "wxpay"));
            return;
            }
            //上面这块主要是验证下,获得openid,验证功能改天再开一篇文章,然后把openid存一下
            this.setAttr("openid", this.getPara("openid"));
            //价格和info(info0+info1拼接而成)纯粹是需求需要,这里大家灵活处理
            if(this.getPara("price")==null){
            this.setAttr("res", "");
            this.setAttr("str", "");
            this.setAttr("tag",false);
            this.render("wxpay.html");
            return;
            }
            this.setAttr("tag", true);
            String price = this.getPara("price");
            String info0 = this.getPara("info0");
            String info1 = this.getPara("info1");
            if("1".equals(info1))
            info1="综合费";
            else if("2".equals(info1))
            info1="激励基金";
            else if("3".equals(info1))
            info1="房屋押金";
            else if("4".equals(info1))
            info1="门禁卡";
            else if("5".equals(info1))
            info1="车位费";
    
            String info = info0+"("+info1+")";
    
            String jsapi_ticket =Sha1Util.getAccessToken(PropKit.get("appId"),PropKit.get("appSecret"));
    //看清楚.这是ticket..用token在https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi里换的,大家一定要注意这里,这是个坑,一定要按照微信的规则得到这串,并且一定保证微信规则能得到返回值,还有个支付授权目录,这个一定要记得修改我写的是我这个方法的访问地址就是。。。/m/wxpay/.http://jingyan.baidu.com/article/ed2a5d1f340dd409f7be177c.html 这个是获得access——token的规则,其实官方的demo中工具类获取的,还有这容易出错,记得吧ip添加到白名单,这有个我搞不懂的,有些ip就是获取不到token,但是加了白名单之后就可以了,难不成遇见一个加一个?有说只有几个特殊的家进入就行,这个是个容易出错的地方,提醒下大家
            String nonce_str = Sha1Util.getNonceStr();// 随机字符串
            String timestamp = Sha1Util.getTimeStamp();// 时间戳
            String appid = PropKit.get("appId");//APPID
            String url="http://man666666n.cn/m/pay/";//发起支付的前端页面的URL地址.而且...而且必须在微信支付里面配置才行!!!
            String sign = null;
            try {
            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("jsapi_ticket", jsapi_ticket);
            packageParams.put("noncestr", nonce_str);
            packageParams.put("timestamp", timestamp);
            packageParams.put("url", url);
            sign = Sha1Util.createSHA1Sign(packageParams);
            } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
            String res="appId : \"" + appid + "\",timestamp : \"" + timestamp //微信个傻逼..这里的timestamp是小写~~
            + "\", nonceStr : \"" + nonce_str
            + "\", signature : \"" + sign + "\"";
            System.out.println("sign签名="+res);
            this.setAttr("price", price);
            this.setAttr("info", info);
            this.setAttr("res", res);
            this.setAttr("str",  dopay(this.getPara("openid"),price,info,nonce_str,timestamp));
    
            this.render("wxpay.html");
            }
    

    工具类如果需要在官方的demo中有
    mcontroller
     

    public String dopay(String openId,String money,String info,String nonce_str,String timestamp) {
    
            // 网页授权后获取传递的参数
            String currTime = TenpayUtil.getCurrTime();
            String orderNo = currTime+Sha1Util.getNonceStr().substring(0, 18);
            float sessionmoney = Float.parseFloat(money);
            String finalmoney = String.format("%.2f", sessionmoney);
            finalmoney = finalmoney.replace(".", "");
            finalmoney = String.valueOf(Integer.parseInt(finalmoney));
    
            // 商户相关资料
            String appid = PropKit.get("appId");
            String appsecret = PropKit.get("appSecret");
            String mch_id = PropKit.get("mch_id");//邮件里的MCHID
            String partnerkey = PropKit.get("paterner_key");;//在微信商户平台pay.weixin.com里自己生成的那个key
            String body = info;
            // 商户订单号
            String out_trade_no = orderNo;
            // 订单生成的机器 IP
            String spbill_create_ip = Sha1Util.getIp2(getRequest());
            // 这里notify_url是 支付完成后微信发给该链接信息,可以判断会员是否支付成功,改变订单状态等。这个就是notify_url方法,在后面贴的,微信会返回我们一些值我们判断一下,返回success就结束了订单状态了,不然会一直访问回调
            String notify_url = "http://man666666n/m/notify_url";
            String trade_type = "JSAPI";
            String openid =openId;
    
            Wxpaydto wx = new Wxpaydto();
            wx.setBody(info);
            wx.setOpenId(this.getPara("openid"));
            wx.setOrderId(orderNo);
            wx.setSpbillCreateIp(spbill_create_ip);
            wx.setTotalFee(money);
            wx.setTime(new Date());
            wx.setNotifyUrl("http://man6666n.cn/m/notify_url");
            wx.setIstrue("0");
            wx.save();
    
            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("appid", appid);
            packageParams.put("mch_id", mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("out_trade_no", out_trade_no);
            packageParams.put("total_fee", finalmoney);
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", notify_url);
            packageParams.put("trade_type", trade_type);
            packageParams.put("openid", openid);
    
            RequestHandler reqHandler = new RequestHandler(null, null);
            reqHandler.init(appid, appsecret, partnerkey);
    
            String sign = reqHandler.createSign(packageParams);
            String xml = "<xml>" + "<appid>" + appid + "</appid>"
            + "<mch_id>"+ mch_id + "</mch_id>"
            + "<nonce_str>" + nonce_str+ "</nonce_str>"
            + "<sign><![CDATA[" + sign + "]]></sign>"
            + "<body><![CDATA[" + body + "]]></body>"
            + "<out_trade_no>"+ out_trade_no+ "</out_trade_no>"
            + "<total_fee>"+ finalmoney+ "</total_fee>"
            + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
            + "<notify_url>" + notify_url + "</notify_url>"
            + "<trade_type>" + trade_type + "</trade_type>"
            + "<openid>"+ openid + "</openid>" + "</xml>";
    
            String allParameters = "";
            try {
            allParameters = reqHandler.genPackage(packageParams);
            } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
            String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            String prepay_id = "";
            try {
            prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
            if (prepay_id.equals("")) {
            System.out.println("统一支付接口获取预支付订单出错");
            }
            } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            }
            SortedMap<String, String> finalpackage = new TreeMap<String, String>();
            String nonceStr2 = nonce_str;
            String prepay_id2 = "prepay_id=" + prepay_id;
            String packages = prepay_id2;
            finalpackage.put("appId", appid);
            finalpackage.put("timeStamp", timestamp);
            finalpackage.put("nonceStr", nonceStr2);
            finalpackage.put("package", packages);
            finalpackage.put("signType", "MD5");
            String finalsign = reqHandler.createSign(finalpackage);
            System.out.println("timestamp:\"" + timestamp
            +"\",appid:\"" + appid
            + "\",nonceStr:\"" + nonceStr2 + "\",package:\""
            + packages + "\",signType: \"MD5" + "\",paySign:\""
            + finalsign + "\"");
            return "timestamp:\"" + timestamp
            +"\",appid:\"" + appid
            + "\",nonceStr:\"" + nonceStr2 + "\",package:\""
            + packages + "\",signType: \"MD5" + "\",paySign:\""
            + finalsign + "\"";
            }
    //隐约记得好像两次的timestamp跟sign好像要求一样.这个就是js返回的一个逻辑,具体根据项目来写,微信会在两处都返回,一个是js一个是回调函数,官方的说法是js不作为标准可能会有错误
    public void paymsg(){
            String tag = this.getPara("tag");
            if(tag.equals("payok")){
            this.setAttr("msg", "支付成66666配合。");
            }
            else if(tag.equals("payfail"))
            this.setAttr("msg", "支付失66666重试。");
            else if(tag.equals("paycencel"))
            this.setAttr("msg", "支付取消。");
            else
            this.setAttr("msg", "未知错误。");
    
            this.render("msgclose.html");
            }
    public void notify_url() throws IOException{
    //这个就是回调的判断
            InputStream re = this.getRequest().getInputStream();
            System.out.println("得到的contextpath"+re);
            System.out.println(this.getRequest());
            try {
            processResponseXml(inputStream2String(re));
            } catch (Exception e) {
            e.printStackTrace();
            }
            this.renderText("SUCCESS");
            }

     

    官方工具类
    WXPayUtil 

     

     

    package com.utils;
    
    import java.io.ByteArrayInputStream;
    import java.io.InputStream;
    import java.io.StringWriter;
    import java.util.*;
    import java.security.MessageDigest;
    
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    
    public class WXPayUtil {
    	
    	public enum SignType {
            MD5, HMACSHA256
        }
        /**
         * XML格式字符串转换为Map
         *
         * @param strXML XML字符串
         * @return XML数据转换后的Map
         * @throws Exception
         */
        public static Map<String, String> xmlToMap(String strXML) throws Exception {
            try {
                Map<String, String> data = new HashMap<String, String>();
                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
                InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
                org.w3c.dom.Document doc = documentBuilder.parse(stream);
                doc.getDocumentElement().normalize();
                NodeList nodeList = doc.getDocumentElement().getChildNodes();
                for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                    Node node = nodeList.item(idx);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                        data.put(element.getNodeName(), element.getTextContent());
                    }
                }
                try {
                    stream.close();
                } catch (Exception ex) {
                    // do nothing
                }
                return data;
            } catch (Exception ex) {
                WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
                throw ex;
            }
    
        }
    
        /**
         * 将Map转换为XML格式的字符串
         *
         * @param data Map类型数据
         * @return XML格式的字符串
         * @throws Exception
         */
        public static String mapToXml(Map<String, String> data) throws Exception {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
            org.w3c.dom.Document document = documentBuilder.newDocument();
            org.w3c.dom.Element root = document.createElement("xml");
            document.appendChild(root);
            for (String key: data.keySet()) {
                String value = data.get(key);
                if (value == null) {
                    value = "";
                }
                value = value.trim();
                org.w3c.dom.Element filed = document.createElement(key);
                filed.appendChild(document.createTextNode(value));
                root.appendChild(filed);
            }
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            DOMSource source = new DOMSource(document);
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            transformer.transform(source, result);
            String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
            try {
                writer.close();
            }
            catch (Exception ex) {
            }
            return output;
        }
    
    
        /**
         * 生成带有 sign 的 XML 格式字符串
         *
         * @param data Map类型数据
         * @param key API密钥
         * @return 含有sign字段的XML
         */
        public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
            return generateSignedXml(data, key, SignType.MD5);
        }
    
        /**
         * 生成带有 sign 的 XML 格式字符串
         *
         * @param data Map类型数据
         * @param key API密钥
         * @param signType 签名类型
         * @return 含有sign字段的XML
         */
        public static String generateSignedXml(final Map<String, String> data, String key, SignType signType) throws Exception {
            String sign = generateSignature(data, key, signType);
            data.put("sign", sign);
            return mapToXml(data);
        }
    
    
        /**
         * 判断签名是否正确
         *
         * @param xmlStr XML格式数据
         * @param key API密钥
         * @return 签名是否正确
         * @throws Exception
         */
        public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
            Map<String, String> data = xmlToMap(xmlStr);
            if (!data.containsKey("sign") ) {
                return false;
            }
            String sign = data.get("sign");
            return generateSignature(data, key).equals(sign);
        }
    
        /**
         * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
         *
         * @param data Map类型数据
         * @param key API密钥
         * @return 签名是否正确
         * @throws Exception
         */
        public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
            return isSignatureValid(data, key, SignType.MD5);
        }
    
        /**
         * 判断签名是否正确,必须包含sign字段,否则返回false。
         *
         * @param data Map类型数据
         * @param key API密钥
         * @param signType 签名方式
         * @return 签名是否正确
         * @throws Exception
         */
        public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception {
            if (!data.containsKey("sign") ) {
                return false;
            }
            String sign = data.get("sign");
            System.out.println("data+"+data+",key="+key+",signtype="+signType);
            System.out.println("sign="+sign);
            return generateSignature(data, key, signType).equals(sign);
        }
    
        /**
         * 生成签名
         *
         * @param data 待签名数据
         * @param key API密钥
         * @return 签名
         */
        public static String generateSignature(final Map<String, String> data, String key) throws Exception {
            return generateSignature(data, key, SignType.MD5);
        }
    
        /**
         * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
         *
         * @param data 待签名数据
         * @param key API密钥
         * @param signType 签名方式
         * @return 签名
         */
        public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
            Set<String> keySet = data.keySet();
            String[] keyArray = keySet.toArray(new String[keySet.size()]);
            Arrays.sort(keyArray);
            StringBuilder sb = new StringBuilder();
            for (String k : keyArray) {
                if (k.equals("sign")) {
                    continue;
                }
                if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                    sb.append(k).append("=").append(data.get(k).trim()).append("&");
            }
            sb.append("key=").append(key);
            if (SignType.MD5.equals(signType)) {
                return MD5(sb.toString()).toUpperCase();
            }
            else if (SignType.HMACSHA256.equals(signType)) {
                return HMACSHA256(sb.toString(), key);
            }
            else {
                throw new Exception(String.format("Invalid sign_type: %s", signType));
            }
        }
    
    
        /**
         * 获取随机字符串 Nonce Str
         *
         * @return String 随机字符串
         */
        public static String generateNonceStr() {
            return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
        }
    
    
        /**
         * 生成 MD5
         *
         * @param data 待处理数据
         * @return MD5结果
         */
        public static String MD5(String data) throws Exception {
            java.security.MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] array = md.digest(data.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString().toUpperCase();
        }
    
        /**
         * 生成 HMACSHA256
         * @param data 待处理数据
         * @param key 密钥
         * @return 加密结果
         * @throws Exception
         */
        public static String HMACSHA256(String data, String key) throws Exception {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
            sha256_HMAC.init(secret_key);
            byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString().toUpperCase();
        }
    
        /**
         * 日志
         * @return
         */
        public static Logger getLogger() {
            Logger logger = LoggerFactory.getLogger("wxpay java sdk");
            return logger;
        }
    
        /**
         * 获取当前时间戳,单位秒
         * @return
         */
        public static long getCurrentTimestamp() {
            return System.currentTimeMillis()/1000;
        }
    
        /**
         * 获取当前时间戳,单位毫秒
         * @return
         */
        public static long getCurrentTimestampMs() {
            return System.currentTimeMillis();
        }
    
        /**
         * 生成 uuid, 即用来标识一笔单,也用做 nonce_str
         * @return
         */
        public static String generateUUID() {
            return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
        }
    
    }

     

     

     

     

     

     

    前端  wxpay.html

    前端调用这块需要好好看一下,稍微有点绕,不知道其他大神有什么更好的实现方法

     

     

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8">
    		<title>自****</title>
    		<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no">
    		<meta name="apple-mobile-web-app-capable" content="yes">
    		<meta name="apple-mobile-web-app-status-bar-style" content="black">
    		<script src="/************min.js"></script>
    		<link rel="stylesheet" href="/m***in.css">
    	</head>
    	<body leftmargin="0" topmargin="0" rightmargin="0" topmargin="0" style="background: #ffffff;">
            <!--img src="/***.jpg" width="100%" height="100%" style="position:absolute;top:0;left:0;right:100;bottom:500;z-index:-1" /-->
            <div style="margin-top: 80px;text-align: center;width: 100%;">
            	<img src="/****ogo.png" style="width: 280px;height: 60px;"/>
            </div>
            <div style="text-align: center;width: 100%;margin-top: 32px;">
            </div>
            
            <div style="margin-top: 32px;text-align: center;" id="app">
            
            <#if tag>
            	<p>
            	请确认信息:
            	<br/>
            	价格:${price!}元<br/>
            	备注:${info!}<br/>
            	确认信息无误请点击确认付款按钮
            	</p>
            
            <#else>
            	<form action="" method="get" id="payform">
            	<input type="hidden" name="openid" value="${openid!}">
            	<input type="text" style="border:0px;width: 84%;margin-left: 8%;height: 
            	45px;background-color: #cccccc;" placeholder="请输入金额" id="price" v-model="message" name="price" >
            	
            	<input type="text" style="border:0px;margin-top: 10px;width: 84%;
            	margin-left: 8%;height: 45px;background-color: #cccccc;" placeholder="请输入公司名称  " 
            	id="info0" name="info0">
            	<br>
            	<select type="text" id="info1" name="info1"
            	style="border:0px;margin-top: 10px;width: 84%;margin-left: 8%;height: 45px;background-color: #cccccc;"   >
                  <option value="1">综**</option>
                  <option value="2">激8***金</option>
                  <option value="3">房***金</option>
                  <option value="4">门***卡</option>
                  <option value="5">车***</option>
                </select>
            	
            	</form>
            	
    		     <h3 id ="showprice" v-if="message === ''">{{ message}}</h3>
    		     <h3 id ="showprice" v-else="message === ''">¥{{ message}}</h3>
            	
            </#if>	
            	<button style="margin-top: 10px;background-color: #343c8d;width: 84%;margin-left: 8%;height: 45px;border:0px;color:#ffffff;" onclick="sub()">确认付款</button>
            </div>
           <script src="https://cdn.boot******js"></script>
    		    
    		<script>
    		new Vue({
    		  el: '#app',
    		  data: {
    		    message: ''
    		  }
    		})
    		</script>
            <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript" charset="utf-8"></script>
    		<script type="text/javascript">
    		wx.config({
    		    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    		    ${res!},// 必填,签名,见附录1
    		    jsApiList: ['chooseWXPay'], // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    		});
    		wx.ready(function(){
    		});
    		wx.error(function(res){
    			
    		    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
    		});
    		function callpay(){
    			wx.checkJsApi({
    			    jsApiList: ['chooseWXPay'], // 检查微信支付接口是否可用
    			    success: function (res) {
    			    	if(res.checkResult.chooseWXPay){
    			    		wx.chooseWXPay({
    							 ${str!}, // 支付签名
    							 cancel:function(res){
    							    	//微信返回的状态 取消:res.errMsg == "chooseWXPay:cancel"
    							    	//alert("支付取消。");
    							    	location.href="**ycencel";
    							    },
    							    error:function(res){
    							    	//alert("支付失败,请返回重试。");
    							    	location.href="/**ail";
    							    },
    							    success:function(res){
    							    	/*微信返回的状态 成功:res.errMsg == "chooseWXPay:ok"*/
    							    	//alert("支付成***配合。");
    							    	location.href="/****payok";
    							    }
    			    		});
    			    	}
    			    }
    			});
    		}
    		
    		</script>
            <script>
              
            	function sub(){
            	<#if tag>
            	callpay();
            	<#else>
            		var price = document.getElementById("price").value;
            		var info0 = document.getElementById("info0").value;
            		
            		
            		if(!isNaN(price)){
    				   
    				}else{
    				   alert("请填写正确格式!");
            			return;
    				}
            		
            		if(price=="" || price==""||info0=="" || info0==""){
            			alert("请完整填写表单!");
            			return;
            		}
            		document.getElementById("payform").submit();
            	</#if>	
    
            	}
            </script>
        </body>
    </html>

     

     

     

     

     

    展开全文
  • 微信支付回调验证签名java版V3

    千次阅读 2016-09-08 12:38:59
    概要:使用微信支付接口时,微信会返回或回调给商户XML数据,开发者需要验证微信返回的数据是否合法。 特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,防止数据泄漏导致出现“假通知”,造成资金...
  • 第一:首先有两个条件:第二:...微信回调->商户自己的业务逻辑实现第三:具体实现:构造移动端所需参数/*** 构造客户端所需的参数(这里是业务层代码实现,控制层不再罗列)* return 返回map的JSON串*/public Stri...
  • 关于Java微信支付成功,不断回调的解决办法 微信文档里是需要返回:"<return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> " 但是,我给...
  • 一.准备工作 APP绑定微信商户平台获取商户id(mchID)、证书(商户后台下载)、...1.导入微信支付SDK <!--微信支付SDK--> <dependency> <groupId>com.github.wxpay</groupId> <ar...
  • 展开全部1.调用微信接口授权授权这里有两种方式,一种是snsapi_bases,另一32313133353236313431303231363533e78988e69d8331333361326266种是...开发者ID-APPIDredirect_uri就是一个回调地址,当你调用完微信的这个...
  • 用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商户后台系统(需要设置支付回调URL),商户后台系统根据productid生成支付交易,最后微信支付系统发起用户支付流程。商户支付回调URL...
  • Java调用微信支付接口

    2017-08-09 09:43:29
    使用了SSM框架,模拟调用 微信统一下单、查询订单、退款、查询退款 接口,模拟 微信回调
  • 微信支付回调接口代码 微信h5支付页面唤起字符密码界面完成支付   1,写代码之前准备工作 (1):利用开源代码 weixin-java-tools来开发效率很高,免去了很多繁琐的代码开发量; 链接 ...
  • java对接微信支付接口开发的过程是什么?以下是小编整理的java对接微信支付接口实现的方法和过程,有需要的朋友可以学习以下的java对接微信支付接口内容。java对接微信支付接口开发的过程是什么?进入公众号后台--》...
  • 微信支付-商户支付模式一url接口回调-java版,代码清晰,可直接运行
  • 微信支付 – 统一下单接口的一个方法封装。需要的同学们可以参考下。 第三方接口用到了 restTemplate , 需要先进行注入。 注:用到的工具类,放到了文章后面。 /** * @title 微信支付:统一下单接口调用 * @...
  • 微信开放平台有个 不成文的规定(文档里没有说明),就是回调的Activity必须是:你的包名(微信...其他的接口回调的Activity必须是:你的包名(微信demo里是:net.sourceforge.simcpux)+.wxapi.WXEntryActivity.java
  • ---name: 微信退款回调解密req_info失败(我用的是微信支付v2版本的)---### 版本信息- IJPay 版本:最新的- 开发环境:1.8- 支付方式:微信支付- 调用的接口:wxpay/refundNotify### 报错信息 (注意格式化)```String ...
  • 原标题:java实现微信H5支付前面做了app微信支付回调处理,现在需要做微信公众号的支付,花了一天多时间,终于折腾出来了!鉴于坑爹的微信官方没有提供Java版的demo,所以全靠自己按照同样坑爹的文档敲敲敲,所以...
  • 支付宝支付 微信扫码支付 已封装好工具类和谷歌的二维码生成工具类。内附微信回调action 需要的jar 自己去下载。百度到处都是的。
  • 怕忘记,记录一下。然后。微信公众号设置支付目录及授权... 等待用户支付微信回调 --> 接口接收到微信通知 --> 完成支付流程1.用户发起支付请求,重定向至微信提供的授权接口,需携带参数appid 为 公众号的A...
  • 前面做了app微信支付回调处理,现在需要做微信公众号的支付,花了一天多时间,终于折腾出来了!鉴于坑爹的微信官方没有提供Java版的demo,所以全靠自己按照同样坑爹的文档敲敲敲,所以记录下来,以供自己及后来人...
  • 如题。需要用java做个类似微信支付成功后,微信会隔3/8/8.。。。这种时间段去访问回调接口的功能如何实现的。
  • Java 实现微信支付

    2020-09-10 16:09:16
    商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。注意:code_url有效期为2小时,过期后扫码不能再发起...
  • 小黑式烂代码之微信APP支付 + 退款(JAVA实现) APP微信支付java后台_统一下单和回调) ...微信支付接口--支付成功的回调--超详细Demo 微信扫码支付功能(2)---用户扫码支付成功,微信异步回调商...
  • 主要记录微信企业付款...商户平台设置扫码回调接口,即项目的外网可访问地址微信企业付款官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2商户签名以及证书相关官方文档:https:/...
  • 微信支付(商户支付模式一)扫码支付接口回调详解,java版,代码清新,用maven搭建SSM服务器,用dom4j解析xml数据,以及生成xml数据
  • java版本 支付宝支付 微信扫码支付 已封装好工具类和谷歌的二维码生成工具类。内附微信回调action 需要的jar 自己去下载。百度到处都是的。
  • 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....
  • java微信公众号支付

    2017-02-15 15:50:07
    spring+springmvc+mybatis 二.流程 - 第一步,获取用户openid。 - 第二步,点击支付按钮后,调用统一下单接口,获取订单id,并生成 timeStamp、paySign、packages三个...- 第四步,支付回调处理。(微信端异步处理)。

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 133
精华内容 53
关键字:

java微信支付回调接口

java 订阅