java实现微信退款功能

微信退款之前需要在常量中配置退款地址,退款的地址必须是可以直接访问的。(之前的申请商户平台及在开放平台申请账号不在描述)在调起之前需要下载商户平台上的证书将其放在项目src下。

微信退款回调url :微信官方建议在提交退款申请后进行退款回调url配置,便于通知退款的结果。配置在微信商户平台-》交易中心-》退款配置栏进行退款结果回调通知配置。配置的url必须为可以直接访问的类似付款成功回调url。

配置成功后在回调的url中处理退款后的结果。微信给返回的参数如下:

对于加密信息req_info的解密步骤如下。

解密过程中需要先到oracle官网下载对应java版本的sercity包,然后将下载后的包中两个jar复制到jdk/jre/lib/security/包下并覆盖原jar.另外需要在项目中引入一个bcprov-jdk15on-158.jar

退款部分代码:

// 构造向微信发送参数的实体类
  private Unifiedorder unifiedorder = new Unifiedorder();
  // 微信的参数
  private WeixinConfigUtils config = new WeixinConfigUtils();
  public static final String ALGORITHM = "AES/ECB/PKCS7Padding";
  private RefundOrder refundOrder = new RefundOrder();
  @Resource
  private AESDecodeUtil aesDecodeUtil;
@Action("weixinRefund")
  public String weixinRefund() {
    try {
      String out_trade_no = getRequest().getParameter("out_trade_no");
      String refund_fee = getRequest().getParameter("refund_fee");
      aLiPay = aLiPayService.searchALiPayByOutTradeNo(out_trade_no);
      if (aLiPay != null) {
        // 参数组
        String appid = aLiPay.getApp_id();
        String mch_id = config.mch_id;
        String nonce_str = RandCharsUtils.getRandomString(16);
        String out_refund_no = UuIdUtils.getUUID();
        Integer total_fee = aLiPay.getTotalFee();
        // 构造签名
        parameters.put("appid", appid);
        parameters.put("mch_id", mch_id);
        parameters.put("nonce_str", nonce_str);
        parameters.put("out_trade_no", out_trade_no);
        parameters.put("out_refund_no", out_refund_no);
        parameters.put("total_fee", total_fee);
        parameters.put("refund_fee", refund_fee);
        parameters.put("op_user_id", mch_id);
        String sign = WXSignUtils.createSign("UTF-8", parameters);
        // 向微信发送xml消息
        // Unifiedorder unifiedorder = new Unifiedorder();
        unifiedorder.setAppid(appid);
        unifiedorder.setMch_id(mch_id);
        unifiedorder.setSign(sign);
        unifiedorder.setNonce_str(nonce_str);
        unifiedorder.setOut_trade_no(out_trade_no);
        unifiedorder.setOut_refund_no(out_refund_no);
        unifiedorder.setTotal_fee(total_fee);
        unifiedorder.setRefund_fee(Integer.valueOf(refund_fee));
        unifiedorder.setOp_user_id(mch_id);
        String xmlInfo = HttpXmlUtils.refundXml(unifiedorder);
        unifiedorder = null;
        try {
          CloseableHttpResponse response = HttpUtil.Post(
              weixinConstant.REFUND_URL, xmlInfo, true);
          // 输出退款后的信息
          String refundXml = EntityUtils.toString(response.getEntity(), "utf-8");
          Map<String, String> refundOrderMap = HttpXmlUtils.parseRefundXml(refundXml);
          if (refundOrderMap.size()>0) {
            if (refundOrderMap.get("result_code").equals("SUCCESS") && refundOrderMap.get("return_code").equals("SUCCESS")) {
              refundOrder.setAppid(refundOrderMap.get("appid"));
              refundOrder.setMch_id(refundOrderMap.get("mch_id"));
              refundOrder.setTransaction_id(refundOrderMap.get("transaction_id"));
              refundOrder.setOut_trade_no(refundOrderMap.get("out_trade_no"));
              refundOrder.setOut_refund_no(refundOrderMap.get("out_refund_no"));
              refundOrder.setRefund_id(refundOrderMap.get("refund_id"));
              refundOrder.setRefund_fee(Integer.valueOf(refundOrderMap.get("refund_fee")));
              refundOrder.setTatol_fee(Integer.valueOf(refundOrderMap.get("total_fee")));
              refundOrder.setRefund_status(WeixinRefundStatusConstant.APPLY_SUCCESS);
refundOrderService.saveOrder(refundOrder);
      msg.put("stateCode", MsgCode.SUCCESS);
              msg.put("message ", "退款申请成功");
    refundOrderService.saveOrder(refundOrder);
            }else {
              msg.put("stateCode", MsgCode.ERROR);
              msg.put("message ", "退款申请失败");
            }
          }else {
            msg.put("stateCode", MsgCode.ERROR);
            msg.put("message ", "退款申请失败");
          }
          try {
            // 关闭流
            EntityUtils.consume(response.getEntity());
          } finally {
            response.close();
          }
        } catch (Exception e) {
          msg.put("stateCode", MsgCode.SYS_ERROR);
          msg.put("message ", "服务器异常");
        }

      } else {
        msg.put("stateCode", MsgCode.ERROR);
        msg.put("message ", "退款申请失败");
      }
      Struts2Utils.renderJson(JSONObject.toJSONString(msg,
          SerializerFeature.DisableCircularReferenceDetect));
      return NONE;
    } catch (Exception e) {
      log.error(e.getMessage());
      e.printStackTrace();
      return "500";
    }
  }
   /**
   * 微信退款回调url
   * */

  @Action("refundNotifyUrl")
  public String refundNotifyUrl() throws IOException {
    try {
      Map<String, String> resultMap = JdomParseXmlUtils.getWeixinResult(
          Struts2Utils.getRequest(), Struts2Utils.getResponse());
      if (resultMap.get("return_code").equals("SUCCESS")) {
        String reqInfo = resultMap.get("req_info");
        String result = aesDecodeUtil.decode(reqInfo);
        Map<String, String> resultMaps = HttpXmlUtils.parseRefundNotifyXml(result);
        refundOrder = refundOrderService.getOrderByOutRefundNo(resultMaps.get("out_refund_no"));
        if (resultMaps.get("refund_status").equals("SUCCESS")){
          refundOrder.setRefund_status(WeixinRefundStatusConstant.REFUND_SUCCESS);
        }else if (resultMaps.get("refund_status").equals("CHANGE")) {
          refundOrder.setRefund_status(WeixinRefundStatusConstant.REFUND_FAIL);
      }else if (resultMaps.get("refund_status").equals("REFUNDCLOSE")) {
          refundOrder.setRefund_status(WeixinRefundStatusConstant.REFUND_CLOSED);
      }
        refundOrder.setRefund_rew_account(resultMaps.get("refund_recv_account"));
        System.out.println(resultMaps.get("refund_recv_account"));
        refundOrderService.updateOrder(refundOrder);
        refundOrder = null;
        unifiedorder.setReturn_code("SUCCESS");
      }
      unifiedorder.setReturn_code("SUCCESS");
      String refundXml = HttpXmlUtils.refundXml(unifiedorder);
      Struts2Utils.getResponse().getWriter().write(refundXml);
      Struts2Utils.getResponse().getWriter().flush();
      } catch (Exception e) {
      log.error(e.getMessage());
      e.printStackTrace();
      return "500";
    }
    return null;
}
package com.wellness.platfront.common.weixinutil;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
生成随机串
/**
 * nonce_str随即字符串
* @author
 * @date 2017/08/10
 */
public class RandCharsUtils {
  private static SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

  public static String getRandomString(int length) { //length表示生成字符串的长度
    String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
    Random random = new Random();
    StringBuffer sb = new StringBuffer();
    int number = 0;
    for (int i = 0; i < length; i++) {
      number = random.nextInt(base.length());
      sb.append(base.charAt(number));
    }
    return sb.toString();
  } 

  /*
   * 订单开始交易的时间
   */
  public static String timeStart(){
    return df.format(new Date());
  }

  /*
   * 订单开始交易的时间
   */
  public static String timeExpire(){
    Calendar now=Calendar.getInstance();
    now.add(Calendar.MINUTE,30);
    return df.format(now.getTimeInMillis());
  }

}

生成签名的类

package com.wellness.platfront.common.weixinutil;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

/**
 * 微信支付签名
 * @author
 * @date 2017/08/10
 */
public class WXSignUtils {
  /**
   * 微信支付签名算法sign
   * @param characterEncoding
   * @param parameters
   * @return
   */
  @SuppressWarnings("rawtypes")
  public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){
    StringBuffer sb = new StringBuffer();
    Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
    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=" + weixinConstant.KEY);
    String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
    return sign;
  }
}

向微信发送消息的类

package com.wellness.platfront.common.weixinutil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.net.ssl.HttpsURLConnection;

import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.wellness.platfront.business.wechat.service.RefundOrderService;
import com.wellness.platfront.entity.weixin.Transfers;
import com.wellness.platfront.entity.weixin.Unifiedorder;
/**
 * post提交xml格式的参数
 * @author
 * @date 2017/08/10
 */
public class HttpXmlUtils {
  @Resource
  private RefundOrderService refundOrderService;
  public static XStream xStream = new XStream(new DomDriver("UTF-8",
      new XmlFriendlyNameCoder("-_", "_")));
  /**
   * 开始post提交参数到接口
   * 并接受返回
   * @param url
   * @param xml
   * @param method
   * @param contentType
   * @return
   */
  public static String xmlHttpProxy(String url,String xml,String method,String contentType){
    InputStream is = null;
    OutputStreamWriter os = null;
    try {
      URL _url = new URL(url);
      HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
      conn.setDoInput(true);
      conn.setDoOutput(true);
      conn.setRequestProperty("Content-type", "text/xml");
      conn.setRequestProperty("Pragma:", "no-cache");
      conn.setRequestProperty("Cache-Control", "no-cache");
      conn.setRequestMethod("POST");
      os = new OutputStreamWriter(conn.getOutputStream());
      os.write(new String(xml.getBytes(contentType)));
      os.flush();
      //返回值
      is = conn.getInputStream();
      return getContent(is, "utf-8");
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } finally{
      try {
        if(os!=null){os.close();}
        if(is!=null){is.close();}
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return null;
  }
  /**
   * 解析返回的值
   * @param is
   * @param charset
   * @return
   */
  public static String getContent(InputStream is, String charset) {
    String pageString = null;
    InputStreamReader isr = null;
    BufferedReader br = null;
    StringBuffer sb = null;
    try {
      isr = new InputStreamReader(is, charset);
      br = new BufferedReader(isr);
      sb = new StringBuffer();
      String line = null;
      while ((line = br.readLine()) != null) {
        sb.append(line + "\n");
      }
      pageString = sb.toString();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if (is != null){
          is.close();
        }
        if(isr!=null){
          isr.close();
        }
        if(br!=null){
          br.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
      sb = null;
    }
    return pageString;
  }
  /**
   * 解析申请退款之后微信返回的值并进行存库操作
   * @throws IOException
   * @throws JDOMException
   */
  public static Map<String, String> parseRefundXml(String refundXml) throws JDOMException, IOException{
    ParseXMLUtils.jdomParseXml(refundXml);
    StringReader read = new StringReader(refundXml);
    // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
    InputSource source = new InputSource(read);
    // 创建一个新的SAXBuilder
    SAXBuilder sb = new SAXBuilder();
    // 通过输入源构造一个Document
    org.jdom.Document doc;
    doc = (org.jdom.Document) sb.build(source);
    org.jdom.Element root = doc.getRootElement();// 指向根节点
    List<org.jdom.Element> list = root.getChildren();
    Map<String, String> refundOrderMap = new HashMap<String, String>();
    if(list!=null&&list.size()>0){
      for (org.jdom.Element element : list) {
        refundOrderMap.put(element.getName(), element.getText());
      }
      return refundOrderMap;
      }
    return null;
  }
  /**
   * 解析申请退款之后微信退款回调返回的字符串中内容
   * @throws IOException
   * @throws JDOMException
   */
  public static Map<String, String> parseRefundNotifyXml(String refundXml) throws JDOMException, IOException{
    ParseXMLUtils.jdomParseXml(refundXml);
    StringReader read = new StringReader(refundXml);
    // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
    InputSource source = new InputSource(read);
    // 创建一个新的SAXBuilder
    SAXBuilder sb = new SAXBuilder();
    // 通过输入源构造一个Document
    org.jdom.Document doc;
    doc = (org.jdom.Document) sb.build(source);
    org.jdom.Element root = doc.getRootElement();// 指向根节点
    List<org.jdom.Element> list = root.getChildren();
    Map<String, String> resultMap = new HashMap<>();
    if(list!=null&&list.size()>0){
      for (org.jdom.Element element : list){
        resultMap.put(element.getName(), element.getText());
      }
    return resultMap;
    }
    return null;
  }
  /**
   * h5支付时 解析返回的值并返回prepareid
   * @throws IOException
   * @throws JDOMException
   */
  public static Map<String, String> getUrl(Unifiedorder unifiedorder) throws JDOMException, IOException{
    String xmlInfo = HttpXmlUtils.xmlH5Info(unifiedorder);
    String wxUrl = weixinConstant.URL;
    String method = "POST";
    String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();
    ParseXMLUtils.jdomParseXml(weixinPost);
    StringReader read = new StringReader(weixinPost);
    // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
    InputSource source = new InputSource(read);
    // 创建一个新的SAXBuilder
    SAXBuilder sb = new SAXBuilder();
    // 通过输入源构造一个Document
    org.jdom.Document doc;
    doc = (org.jdom.Document) sb.build(source);
    org.jdom.Element root = doc.getRootElement();// 指向根节点
    List<org.jdom.Element> list = root.getChildren();
    String prepayId =null;
    Map<String, String> msg = new HashMap<String, String>();
    if(list!=null&&list.size()>0){
      for (org.jdom.Element element : list) {
      msg.put(element.getName(), element.getText());
      }
      }
    return msg;
  }
  /**
   * 解析返回的值并返回prepareid
   * @throws IOException
   * @throws JDOMException
   */
  public static String getPrepareId(Unifiedorder unifiedorder) throws JDOMException, IOException{
    String xmlInfo = HttpXmlUtils.xmlInfo(unifiedorder);
    String wxUrl = weixinConstant.URL;
    String method = "POST";
    String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();
    ParseXMLUtils.jdomParseXml(weixinPost);
    StringReader read = new StringReader(weixinPost);
    // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
    InputSource source = new InputSource(read);
    // 创建一个新的SAXBuilder
    SAXBuilder sb = new SAXBuilder();
    // 通过输入源构造一个Document
    org.jdom.Document doc;
    doc = (org.jdom.Document) sb.build(source);
    org.jdom.Element root = doc.getRootElement();// 指向根节点
    List<org.jdom.Element> list = root.getChildren();
    String prepayId =null;
    if(list!=null&&list.size()>0){
      for (org.jdom.Element element : list) {
        if ( "prepay_id".equals(element.getName())) {
          prepayId= element.getText();
          break;
        }
      }
      }
    return prepayId;
  }
  /**
   * 向微信发送企业付款请求并解析返回结果
   * @throws IOException
   * @throws JDOMException
   */
  public static Map<String, String> getTransfersMap(Transfers transfers) throws JDOMException, IOException{
    String xmlInfo = HttpXmlUtils.xmlTransfer(transfers);
    String wxUrl = weixinConstant.WITHDRAW_URL;
    String method = "POST";
    String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();
    ParseXMLUtils.jdomParseXml(weixinPost);
    StringReader read = new StringReader(weixinPost);
    // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
    InputSource source = new InputSource(read);
    // 创建一个新的SAXBuilder
    SAXBuilder sb = new SAXBuilder();
    // 通过输入源构造一个Document
    org.jdom.Document doc;
    doc = (org.jdom.Document) sb.build(source);
    org.jdom.Element root = doc.getRootElement();// 指向根节点
    List<org.jdom.Element> list = root.getChildren();
    Map<String, String> transferMap=new HashMap<>();
    if(list!=null&&list.size()>0){
      for (org.jdom.Element element : list) {
        transferMap.put(element.getName(), element.getText());
      }
      }
    return transferMap;
  }
  /**
   * 构造退款xml参数
   * @param xml
   * @return
   */
  public static String refundXml(Unifiedorder unifiedorder){
      xStream.autodetectAnnotations(true);
      xStream.alias("xml", Unifiedorder.class);
      return xStream.toXML(unifiedorder);
  }
  /**
   * 构造企业付款xml参数
   * @param xml
   * @return
   */
  public static String transferXml(Transfers transfers){
      xStream.autodetectAnnotations(true);
      xStream.alias("xml", Transfers.class);
      return xStream.toXML(transfers);
  }
  /**
   * 构造xml参数
   * @param xml
   * @return
   */
  public static String xmlInfo(Unifiedorder unifiedorder){

    if(unifiedorder!=null){
      StringBuffer bf = new StringBuffer();
      bf.append("<xml>");

      bf.append("<appid><![CDATA[");
      bf.append(unifiedorder.getAppid());
      bf.append("]]></appid>");

      bf.append("<mch_id><![CDATA[");
      bf.append(unifiedorder.getMch_id());
      bf.append("]]></mch_id>");

      bf.append("<nonce_str><![CDATA[");
      bf.append(unifiedorder.getNonce_str());
      bf.append("]]></nonce_str>");

      bf.append("<sign><![CDATA[");
      bf.append(unifiedorder.getSign());
      bf.append("]]></sign>");

      bf.append("<body><![CDATA[");
      bf.append(unifiedorder.getBody());
      bf.append("]]></body>");

      bf.append("<detail><![CDATA[");
      bf.append(unifiedorder.getDetail());
      bf.append("]]></detail>");

      bf.append("<attach><![CDATA[");
      bf.append(unifiedorder.getAttach());
      bf.append("]]></attach>");

      bf.append("<out_trade_no><![CDATA[");
      bf.append(unifiedorder.getOut_trade_no());
      bf.append("]]></out_trade_no>");

      bf.append("<total_fee><![CDATA[");
      bf.append(unifiedorder.getTotal_fee());
      bf.append("]]></total_fee>");

      bf.append("<spbill_create_ip><![CDATA[");
      bf.append(unifiedorder.getSpbill_create_ip());
      bf.append("]]></spbill_create_ip>");

      bf.append("<time_start><![CDATA[");
      bf.append(unifiedorder.getTime_start());
      bf.append("]]></time_start>");

      bf.append("<time_expire><![CDATA[");
      bf.append(unifiedorder.getTime_expire());
      bf.append("]]></time_expire>");

      bf.append("<notify_url><![CDATA[");
      bf.append(unifiedorder.getNotify_url());
      bf.append("]]></notify_url>");

      bf.append("<trade_type><![CDATA[");
      bf.append(unifiedorder.getTrade_type());
      bf.append("]]></trade_type>");

      bf.append("</xml>");
      return bf.toString();
    }
    return "";
  }
  /**
   * 构造xml参数
   * @param xml
   * @return
   */
  public static String xmlH5Info(Unifiedorder unifiedorder){
    if(unifiedorder!=null){
      StringBuffer bf = new StringBuffer();
      bf.append("<xml>");

      bf.append("<appid><![CDATA[");
      bf.append(unifiedorder.getAppid());
      bf.append("]]></appid>");

      bf.append("<mch_id><![CDATA[");
      bf.append(unifiedorder.getMch_id());
      bf.append("]]></mch_id>");

      bf.append("<nonce_str><![CDATA[");
      bf.append(unifiedorder.getNonce_str());
      bf.append("]]></nonce_str>");

      bf.append("<sign><![CDATA[");
      bf.append(unifiedorder.getSign());
      bf.append("]]></sign>");

      bf.append("<body><![CDATA[");
      bf.append(unifiedorder.getBody());
      bf.append("]]></body>");

      bf.append("<attach><![CDATA[");
      bf.append(unifiedorder.getAttach());
      bf.append("]]></attach>");

      bf.append("<out_trade_no><![CDATA[");
      bf.append(unifiedorder.getOut_trade_no());
      bf.append("]]></out_trade_no>");

      bf.append("<total_fee><![CDATA[");
      bf.append(unifiedorder.getTotal_fee());
      bf.append("]]></total_fee>");

      bf.append("<spbill_create_ip><![CDATA[");
      bf.append(unifiedorder.getSpbill_create_ip());
      bf.append("]]></spbill_create_ip>");

      bf.append("<notify_url><![CDATA[");
      bf.append(unifiedorder.getNotify_url());
      bf.append("]]></notify_url>");

      bf.append("<trade_type><![CDATA[");
      bf.append(unifiedorder.getTrade_type());
      bf.append("]]></trade_type>");

      bf.append("<scene_info><![CDATA[");
      bf.append(unifiedorder.getScene_info());
      bf.append("]]></scene_info>");

      bf.append("</xml>");
      return bf.toString();
    }
    return "";
  }
  /**
   * 构造退款xml参数
   * @param xml
   * @return
   */
  public static String xmlTransfer(Transfers transfers){

    if(transfers!=null){
      StringBuffer bf = new StringBuffer();
      bf.append("<xml>");

      bf.append("<mch_appid><![CDATA[");
      bf.append(transfers.getMch_appid());
      bf.append("]]></mch_appid>");

      bf.append("<mchid><![CDATA[");
      bf.append(transfers.getMchid());
      bf.append("]]></mchid>");

      bf.append("<nonce_str><![CDATA[");
      bf.append(transfers.getNonce_str());
      bf.append("]]></nonce_str>");

      bf.append("<sign><![CDATA[");
      bf.append(transfers.getSign());
      bf.append("]]></sign>");

      bf.append("<partner_trade_no><![CDATA[");
      bf.append(transfers.getPartner_trade_no());
      bf.append("]]></partner_trade_no>");

      bf.append("<openid><![CDATA[");
      bf.append(transfers.getOpenid());
      bf.append("]]></openid>");

      bf.append("<check_name><![CDATA[");
      bf.append(transfers.getCheck_name());
      bf.append("]]></check_name>");

      bf.append("<amount><![CDATA[");
      bf.append(transfers.getAmount());
      bf.append("]]></amount>");

      bf.append("<desc><![CDATA[");
      bf.append(transfers.getDesc());
      bf.append("]]></desc>");

      bf.append("<spbill_create_ip><![CDATA[");
      bf.append(transfers.getSpbill_create_ip());
      bf.append("]]></spbill_create_ip>");

      bf.append("</xml>");
      return bf.toString();
    }
    return "";
  }
  /**
   * post请求并得到返回结果
   * @param requestUrl
   * @param requestMethod
   * @param output
   * @return
   */
  public static String httpsRequest(String requestUrl, String requestMethod, String output) {
    try{
      URL url = new URL(requestUrl);
      HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
      connection.setDoOutput(true);
      connection.setDoInput(true);
      connection.setUseCaches(false);
      connection.setRequestMethod(requestMethod);
      if (null != output) {
        OutputStream outputStream = connection.getOutputStream();
        outputStream.write(output.getBytes("UTF-8"));
        outputStream.close();
      }
      // 从输入流读取返回内容
      InputStream inputStream = connection.getInputStream();
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
      BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
      String str = null;
      StringBuffer buffer = new StringBuffer();
      while ((str = bufferedReader.readLine()) != null) {
        buffer.append(str);
      }
      bufferedReader.close();
      inputStreamReader.close();
      inputStream.close();
      inputStream = null;
      connection.disconnect();
      return buffer.toString();
    }catch(Exception ex){
      ex.printStackTrace();
    }
    return "";
  }
}

加载证书

package com.wellness.platfront.common.weixinutil;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;

public class HttpUtil {
  /**
   * 发送post请求
   *
   * @param url
   *      请求地址
   * @param outputEntity
   *      发送内容
   * @param isLoadCert
   *      是否加载证书
   */
  public static CloseableHttpResponse Post(String url, String outputEntity, boolean isLoadCert) throws Exception {
    HttpPost httpPost = new HttpPost(url);
    // 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
    httpPost.addHeader("Content-Type", "text/xml");
    httpPost.setEntity(new StringEntity(outputEntity, "UTF-8"));
    if (isLoadCert) {
      // 加载含有证书的http请求
      return HttpClients.custom().setSSLSocketFactory(CertUtil.initCert()).build().execute(httpPost);
    } else {
      return HttpClients.custom().build().execute(httpPost);
    }
  }
}

加载证书的类

package com.wellness.platfront.common.weixinutil;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContexts;

/**
 * 加载证书的类
 * @author
 * @since 2017/08/16
 */

@SuppressWarnings("deprecation")
public class CertUtil {
  private static WeixinConfigUtils config = new WeixinConfigUtils();
  /**
   * 加载证书
   */
  public static SSLConnectionSocketFactory initCert() throws Exception {
    FileInputStream instream = null;
    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    instream = new FileInputStream(new File(weixinConstant.PATH));
    keyStore.load(instream, config.mch_id.toCharArray());

    if (null != instream) {
      instream.close();
    }

    SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore,config.mch_id.toCharArray()).build();
    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

    return sslsf;
  }
}

解密微信退款中返回相关信息的字符串

package com.wellness.platfront.common.weixinutil;

import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Service;

import com.wellness.platfront.common.wechat.utils.MD5;

/**
 * 解密微信退款中返回相关信息的字符串
 * @author
 * @since 2017/09/05
 */
@Service
public class AESDecodeUtil {

   public static final String ALGORITHM = "AES/ECB/PKCS7Padding";
   public String decode(String reqInfo) throws Exception{
    try {
      byte[] decodeBase64 = Base64.decodeBase64(reqInfo);
      String md5Key = MD5.MD5Encode(weixinConstant.KEY);
      Security.addProvider(new BouncyCastleProvider());
      Cipher cipher = Cipher.getInstance(ALGORITHM);
      SecretKey keySpec = new SecretKeySpec(md5Key.getBytes(), "AES"); //生成加密解密需要的Key
      cipher.init(Cipher.DECRYPT_MODE, keySpec);
      byte[] decoded = cipher.doFinal(decodeBase64);
      String result = new String(decoded, "UTF-8");
      return result;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
   }
}

微信解析xml:带有CDATA格式的

package com.wellness.platfront.common.weixinutil;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;

import com.wellness.platfront.entity.weixin.UnifiedorderResult;
import com.wellness.platfront.entity.weixin.WXPayResult;

/**
 * 微信解析xml:带有CDATA格式的
* @author
 * @date 2017/08/10
 */
public class JdomParseXmlUtils {

  /**
   * 1、统一下单获取微信返回
   * 解析的时候自动去掉CDMA
   * @param xml
   */
  @SuppressWarnings("unchecked")
  public static UnifiedorderResult getUnifiedorderResult(String xml){
    UnifiedorderResult unifieorderResult = new UnifiedorderResult();
    try {
      StringReader read = new StringReader(xml);
      // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
      InputSource source = new InputSource(read);
      // 创建一个新的SAXBuilder
      SAXBuilder sb = new SAXBuilder();
      // 通过输入源构造一个Document
      Document doc;
      doc = (Document) sb.build(source);

      Element root = doc.getRootElement();// 指向根节点
      List<Element> list = root.getChildren();

      if(list!=null&&list.size()>0){
        for (Element element : list) {
          System.out.println("key是:"+element.getName()+",值是:"+element.getText());

          if("return_code".equals(element.getName())){
            unifieorderResult.setReturn_code(element.getText());
          }

          if("return_msg".equals(element.getName())){
            unifieorderResult.setReturn_msg(element.getText());
          }

          if("appid".equals(element.getName())){
            unifieorderResult.setAppid(element.getText());
          }

          if("mch_id".equals(element.getName())){
            unifieorderResult.setMch_id(element.getText());
          }

          if("nonce_str".equals(element.getName())){
            unifieorderResult.setNonce_str(element.getText());
          }

          if("sign".equals(element.getName())){
            unifieorderResult.setSign(element.getText());
          }

          if("result_code".equals(element.getName())){
            unifieorderResult.setResult_code(element.getText());
          }

          if("prepay_id".equals(element.getName())){
            unifieorderResult.setPrepay_id(element.getText());
          }

          if("trade_type".equals(element.getName())){
            unifieorderResult.setTrade_type(element.getText());
          }
        }
      }

    } catch (JDOMException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }catch (Exception e) {
      e.printStackTrace();
    }

    return unifieorderResult;
  }

  /**
   * 获取微信回调的参数并将xml解析成map
   * 解析的时候自动去掉CDMA
   * @param xml
   */
  @SuppressWarnings("unchecked")
  public static Map<String, String> getWeixinResult(HttpServletRequest request,HttpServletResponse response){
    Map<String, String> resultMap = new HashMap<>();
     try {
        PrintWriter writer = response.getWriter();
          InputStream inStream = request.getInputStream();
          ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
          byte[] buffer = new byte[1024];
          int len = 0;
          while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
          }
          outSteam.close();
          inStream.close();
          String result = new String(outSteam.toByteArray(), "utf-8");
          StringReader read = new StringReader(result);
          InputSource source = new InputSource(read);
          // 创建一个新的SAXBuilder
          SAXBuilder sb = new SAXBuilder();
          // 通过输入源构造一个Document
          Document doc;
          doc = (Document) sb.build(source);

          Element root = doc.getRootElement();// 指向根节点
          List<Element> list = root.getChildren();

          if(list!=null&&list.size()>0){
            for (Element element : list) {
              resultMap.put(element.getName(), element.getText());
            }
          }
        return resultMap;
        } catch (Exception e) {
          e.printStackTrace();
        }
     return null;
  }

  /**
   * 2、微信回调后参数解析
   * 解析的时候自动去掉CDMA
   * @param xml
   */
  @SuppressWarnings("unchecked")
  public static WXPayResult getWXPayResult(String xml){
    WXPayResult wXPayResult = new WXPayResult();
    try {
      StringReader read = new StringReader(xml);
      // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
      InputSource source = new InputSource(read);
      // 创建一个新的SAXBuilder
      SAXBuilder sb = new SAXBuilder();
      // 通过输入源构造一个Document
      Document doc;
      doc = (Document) sb.build(source);

      Element root = doc.getRootElement();// 指向根节点
      List<Element> list = root.getChildren();

      if(list!=null&&list.size()>0){
        for (Element element : list) {
          if("return_code".equals(element.getName())){
            wXPayResult.setReturn_code(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("appid".equals(element.getName())){
            wXPayResult.setAppid(element.getText());
          }

          if("mch_id".equals(element.getName())){
            wXPayResult.setMch_id(element.getText());
          }

          if("nonce_str".equals(element.getName())){
            wXPayResult.setNonce_str(element.getText());
          }

          if("sign".equals(element.getName())){
            wXPayResult.setSign(element.getText());
          }

          if("result_code".equals(element.getName())){
            wXPayResult.setResult_code(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

          if("return_msg".equals(element.getName())){
            wXPayResult.setReturn_msg(element.getText());
          }

        }
      }

    } catch (JDOMException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }catch (Exception e) {
      e.printStackTrace();
    }

    return wXPayResult;
  }

}
package com.wellness.platfront.common.weixinutil;

/**
 * dom解析
 * @author
 * @date 2017/08/10
 */
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;

public class ParseXMLUtils {

  /**
   * 1、DOM解析
   */
  @SuppressWarnings("rawtypes")
  public static void beginXMLParse(String xml){
    Document doc = null;
    try {
      doc = DocumentHelper.parseText(xml); // 将字符串转为XML

      Element rootElt = doc.getRootElement(); // 获取根节点smsReport

      System.out.println("根节点是:"+rootElt.getName());

      Iterator iters = rootElt.elementIterator("sendResp"); // 获取根节点下的子节点sms

      while (iters.hasNext()) {
        Element recordEle1 = (Element) iters.next();
        Iterator iter = recordEle1.elementIterator("sms");

        while (iter.hasNext()) {
          Element recordEle = (Element) iter.next();
          String phone = recordEle.elementTextTrim("phone"); // 拿到sms节点下的子节点stat值

          String smsID = recordEle.elementTextTrim("smsID"); // 拿到sms节点下的子节点stat值

          System.out.println(phone+":"+smsID);
        }
      }
    } catch (DocumentException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 2、DOM4j解析XML(支持xpath)
   * 解析的时候自动去掉CDMA
   * @param xml
   */
  public static void xpathParseXml(String xml){
    try {
      StringReader read = new StringReader(xml);
      SAXReader saxReader = new SAXReader();
      Document doc = saxReader.read(read);
      String xpath ="/xml/appid";
      System.out.print(doc.selectSingleNode(xpath).getText());
    } catch (DocumentException e) {
      e.printStackTrace();
    }
  }

  /**
   * 3、JDOM解析XML
   * 解析的时候自动去掉CDMA
   * @param xml
   */
  @SuppressWarnings("unchecked")
  public static void jdomParseXml(String xml){
    try {
      StringReader read = new StringReader(xml);
      // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
      InputSource source = new InputSource(read);
      // 创建一个新的SAXBuilder
      SAXBuilder sb = new SAXBuilder();
      // 通过输入源构造一个Document
      org.jdom.Document doc;
      doc = (org.jdom.Document) sb.build(source);

      org.jdom.Element root = doc.getRootElement();// 指向根节点
      List<org.jdom.Element> list = root.getChildren();

      if(list!=null&&list.size()>0){
        for (org.jdom.Element element : list) {
          /*try{
            methodName = element.getName();
            Method m = v.getClass().getMethod("set" + methodName, new Class[] { String.class });
            if(parseInt(methodName)){
              m.invoke(v, new Object[] { Integer.parseInt(element.getText()) });
            }else{
              m.invoke(v, new Object[] { element.getText() });
            }
          }catch(Exception ex){
            ex.printStackTrace();
          }*/

        }
      }

    } catch (JDOMException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static boolean parseInt(String key){
    if(!StringUtils.isEmpty(key)){
      if(key.equals("total_fee")||key.equals("cash_fee")||key.equals("coupon_fee")||key.equals("coupon_count")||key.equals("coupon_fee_0")){
        return true;
      }
    }

    return false;
  }

}

微信支付相关的常量

package com.wellness.platfront.common.weixinutil;
/**
 * 微信支付相关的常量
 * @author yangfuren
 * @since 2017/08/16
 */
public class weixinConstant {
  /**
   * 微信支付API秘钥
   */
  public static final String KEY = "eAO9gDBK7NjqkYEvRFB82CspUTINiWnD";

  /**
   * url
   */
  public static final String URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  /**
   * 退款url
   */
  public static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  /**
   * 证书地址
   */
  public static final String PATH ="";
  /**
   * 付款url
   */
  public static final String WITHDRAW_URL="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
}

微信退款状态常量

package com.wellness.platfront.common.weixinutil;
/**
 * 微信退款状态常量
 * @author
 * @since 2017/09/04
 */
public class WeixinRefundStatusConstant {
  //退款申请成功
  public static final String APPLY_SUCCESS="退款申请成功";
  //退款申请失败
  public static final String APPLY_FAIL="退款申请失败";
  //退款成功
  public static final String REFUND_SUCCESS="退款成功";
  //退款异常
  public static final String REFUND_FAIL="退款异常";
  //退款关闭
  public static final String REFUND_CLOSED="退款关闭";

}

微信退款订单信息

package com.wellness.platfront.entity.weixin;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * 微信退款订单信息
 * @author
 *
 */
@Entity
@Table(name = "weixin_refund_order")
public class RefundOrder implements Serializable{
  private static final long serialVersionUID = 1L;
  //退款订单id
  public Integer refundOrderId;
  //微信公众账号
  public String appid;
  //微信商户号
  public String mch_id;
  //微信订单号
  public String transaction_id;
  //商户订单号
  public String out_trade_no;
  //商户退款单号
  public String out_refund_no;
  //微信退款单号
  public String refund_id;
  //退款金额
  public Integer refund_fee;
  //订单总价格
  public Integer tatol_fee;
  //退款发起时间
  public Date create_time;
  //退款状态  申请退款中 申请退款失败 退款成功 退款异常  退款关闭
  public String refund_status;
  //退款退还账户
  public String refund_rew_account;
  //退款完成时间
  public Date end_time;
  //订单退还方式
    public String refundType;
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "refund_order_id", nullable = false)
  public Integer getRefundOrderId() {
    return refundOrderId;
  }
  public void setRefundOrderId(Integer refundOrderId) {
    this.refundOrderId = refundOrderId;
  }
  @Column(name = "appid", nullable = false)
  public String getAppid() {
    return appid;
  }
  public void setAppid(String appid) {
    this.appid = appid;
  }
  @Column(name = "mch_id", nullable = false)
  public String getMch_id() {
    return mch_id;
  }
  public void setMch_id(String mch_id) {
    this.mch_id = mch_id;
  }
  @Column(name = "transaction_id", nullable = false)
  public String getTransaction_id() {
    return transaction_id;
  }
  public void setTransaction_id(String transaction_id) {
    this.transaction_id = transaction_id;
  }
  @Column(name = "out_trade_no", nullable = false)
  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;
  }
  @Column(name = "out_refund_no", nullable = false)
  public String getOut_refund_no() {
    return out_refund_no;
  }
  public void setOut_refund_no(String out_refund_no) {
    this.out_refund_no = out_refund_no;
  }
  @Column(name = "refund_id", nullable = false)
  public String getRefund_id() {
    return refund_id;
  }
  public void setRefund_id(String refund_id) {
    this.refund_id = refund_id;
  }
  @Column(name = "refund_fee", nullable = false)
  public Integer getRefund_fee() {
    return refund_fee;
  }
  public void setRefund_fee(Integer refund_fee) {
    this.refund_fee = refund_fee;
  }
  @Column(name = "tatol_fee", nullable = false)
  public Integer getTatol_fee() {
    return tatol_fee;
  }
  public void setTatol_fee(Integer tatol_fee) {
    this.tatol_fee = tatol_fee;
  }
  @Column(name = "create_time", nullable = false)
  public Date getCreate_time() {
    return create_time;
  }
  public void setCreate_time(Date create_time) {
    this.create_time = create_time;
  }
  @Column(name = "refund_status", nullable = false)
  public String getRefund_status() {
    return refund_status;
  }
  public void setRefund_status(String refund_status) {
    this.refund_status = refund_status;
  }
  @Column(name = "refund_rew_account")
  public String getRefund_rew_account() {
    return refund_rew_account;
  }
  public void setRefund_rew_account(String refund_rew_account) {
    this.refund_rew_account = refund_rew_account;
  }
  @Column(name = "end_time")
  public Date getEnd_time() {
    return end_time;
  }
  public void setEnd_time(Date end_time) {
    this.end_time = end_time;
  }

  @Column(name = "refund_type")
  public String getRefundType() {
    return refundType;
  }
  public void setRefundType(String refundType) {
    this.refundType = refundType;
  }
}

这个实体类中参数和微信官方需要的参数一致

package com.wellness.platfront.entity.weixin;

import java.io.Serializable;
import com.wellness.platfront.entity.member.Member;

/**
 * 统一下单提交为微信的参数
 * @author
 * @date 2017年08月11日
 */
public class Unifiedorder implements Serializable{
  private static final long serialVersionUID = 1L;
  //微信支付表id
  private Integer weixinId;
  //微信分配的公众账号ID(企业号corpid即为此appId)
  private String appid;
  //商户id
  private String mch_id;
  //终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"
  private String device_info;
  //随机字符串:数字+大写字母的组合,32位
  private String nonce_str;
  //签名
  private String sign;
  //商品或支付单简要描述
  private String body;
  //商品名称明细列表
  private String detail;
  //附加参数(例如:用于区别本商户不同的分店)
  private String attach;
  //商户系统内部的订单号
  private String out_trade_no;
  //货币类型:符合ISO 4217标准的三位字母代码,默认人民币:CNY
  private String fee_type;
  //总金额
  private int total_fee;
  //APP和网页支付提交[用户端ip],Native支付填调用微信支付API的机器IP。
  private String spbill_create_ip;
  //订单生成时间,格式为yyyyMMddHHmmss,
  private String time_start;
  //订单失效时间,格式为yyyyMMddHHmmss,最短失效时间间隔必须大于5分钟[支付宝是30分钟,同样30分钟]
  private String time_expire;
  //商品标记,代金券或立减优惠功能的参数
  private String goods_tag;
  //接收微信支付异步通知回调地址
  private String notify_url;
  //交易类型:JSAPI,NATIVE,APP h5为 MWEB
  private String trade_type;
  //trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。
  private String product_id;
  //no_credit--指定不能使用信用卡支付
  private String limit_pay;
  //trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
  private String openid;
  //商户内部自己的退款单号
  private String out_refund_no;
  //退款总金额单位为分
  private int refund_fee;
  //操作员的id默认为mch_id
  private String op_user_id;
  //微信官方提供的订单号
  private String prepayid;
  //记录所对应的member
  private Member member;
  //返回给微信的状态码(用于支付回调时)
  public String return_code;
  //微信h5支付时候的场景信息官方的信息模板 {"h5_info"://h5支付固定传"h5_info"
  //{"type":"",//场景类型 "wap_url":"",//WAP网站URL地址"wap_name": ""//WAP 网站名}}
  public String scene_info;
  public String getScene_info() {
    return scene_info;
  }
  public void setScene_info(String scene_info) {
    this.scene_info = scene_info;
  }
  public String getReturn_code() {
    return return_code;
  }
  public void setReturn_code(String return_code) {
    this.return_code = return_code;
  }
  public String getAppid() {
    return appid;
  }
  public String getMch_id() {
    return mch_id;
  }
  public String getDevice_info() {
    return device_info;
  }
  public String getNonce_str() {
    return nonce_str;
  }
  public String getSign() {
    return sign;
  }
  public String getBody() {
    return body;
  }
  public String getDetail() {
    return detail;
  }
  public String getAttach() {
    return attach;
  }
  public String getOut_trade_no() {
    return out_trade_no;
  }
  public String getFee_type() {
    return fee_type;
  }
  public int getTotal_fee() {
    return total_fee;
  }
  public String getSpbill_create_ip() {
    return spbill_create_ip;
  }
  public String getTime_start() {
    return time_start;
  }
  public String getTime_expire() {
    return time_expire;
  }
  public String getGoods_tag() {
    return goods_tag;
  }
  public String getNotify_url() {
    return notify_url;
  }
  public String getTrade_type() {
    return trade_type;
  }
  public String getProduct_id() {
    return product_id;
  }
  public String getLimit_pay() {
    return limit_pay;
  }
  public String getOpenid() {
    return openid;
  }
  public void setAppid(String appid) {
    this.appid = appid;
  }
  public void setMch_id(String mch_id) {
    this.mch_id = mch_id;
  }
  public void setDevice_info(String device_info) {
    this.device_info = device_info;
  }
  public void setNonce_str(String nonce_str) {
    this.nonce_str = nonce_str;
  }
  public void setSign(String sign) {
    this.sign = sign;
  }
  public void setBody(String body) {
    this.body = body;
  }
  public void setDetail(String detail) {
    this.detail = detail;
  }
  public void setAttach(String attach) {
    this.attach = attach;
  }
  public void setOut_trade_no(String out_trade_no) {
    this.out_trade_no = out_trade_no;
  }
  public void setFee_type(String fee_type) {
    this.fee_type = fee_type;
  }
  public void setTotal_fee(int total_fee) {
    this.total_fee = total_fee;
  }
  public void setSpbill_create_ip(String spbill_create_ip) {
    this.spbill_create_ip = spbill_create_ip;
  }
  public void setTime_start(String time_start) {
    this.time_start = time_start;
  }
  public void setTime_expire(String time_expire) {
    this.time_expire = time_expire;
  }
  public void setGoods_tag(String goods_tag) {
    this.goods_tag = goods_tag;
  }
  public void setNotify_url(String notify_url) {
    this.notify_url = notify_url;
  }
  public void setTrade_type(String trade_type) {
    this.trade_type = trade_type;
  }
  public void setProduct_id(String product_id) {
    this.product_id = product_id;
  }
  public void setLimit_pay(String limit_pay) {
    this.limit_pay = limit_pay;
  }
  public void setOpenid(String openid) {
    this.openid = openid;
  }
  public String getOut_refund_no() {
    return out_refund_no;
  }
  public void setOut_refund_no(String out_refund_no) {
    this.out_refund_no = out_refund_no;
  }
  public int getRefund_fee() {
    return refund_fee;
  }
  public void setRefund_fee(int refund_fee) {
    this.refund_fee = refund_fee;
  }
  public Integer getWeixinId() {
    return weixinId;
  }
  public void setWeixinId(Integer weixinId) {
    this.weixinId = weixinId;
  }
  public Member getMember() {
    return member;
  }
  public void setMember(Member member) {
    this.member = member;
  }
  public String getPrepayid() {
    return prepayid;
  }
  public void setPrepayid(String prepayid) {
    this.prepayid = prepayid;
  }
  public String getOp_user_id() {
    return op_user_id;
  }
  public void setOp_user_id(String op_user_id) {
    this.op_user_id = op_user_id;
  }

}

统一下单微信返回的参数组(xml)

package com.wellness.platfront.entity.weixin;

/**
 * 统一下单微信返回的参数组(xml)
 * @author
 * @date 2017年08月11日
 */
public class UnifiedorderResult {
  private String appid;//appid
  private String mch_id;//商家id
  private String device_info;//设备号
  private String nonce_str;//随机字符串
  private String sign;//签名
  private String result_code;//错误码
  private String err_code;//错误代码
  private String err_code_des;//错误返回的信息描述
  private String trade_type;//调用接口提交的交易类型,取值如下:JSAPI,NATIVE,APP
  private String prepay_id;//微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
  private String code_url;//trade_type为NATIVE是有返回,可将该参数值生成二维码展示出来进行扫码支付

  private String return_code;//返回状态码SUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
  private String return_msg;//返回信息
  public String getAppid() {
    return appid;
  }
  public String getMch_id() {
    return mch_id;
  }
  public String getDevice_info() {
    return device_info;
  }
  public String getNonce_str() {
    return nonce_str;
  }
  public String getSign() {
    return sign;
  }
  public String getResult_code() {
    return result_code;
  }
  public String getErr_code() {
    return err_code;
  }
  public String getErr_code_des() {
    return err_code_des;
  }
  public String getTrade_type() {
    return trade_type;
  }
  public String getPrepay_id() {
    return prepay_id;
  }
  public String getCode_url() {
    return code_url;
  }
  public void setAppid(String appid) {
    this.appid = appid;
  }
  public void setMch_id(String mch_id) {
    this.mch_id = mch_id;
  }
  public void setDevice_info(String device_info) {
    this.device_info = device_info;
  }
  public void setNonce_str(String nonce_str) {
    this.nonce_str = nonce_str;
  }
  public void setSign(String sign) {
    this.sign = sign;
  }
  public void setResult_code(String result_code) {
    this.result_code = result_code;
  }
  public void setErr_code(String err_code) {
    this.err_code = err_code;
  }
  public void setErr_code_des(String err_code_des) {
    this.err_code_des = err_code_des;
  }
  public void setTrade_type(String trade_type) {
    this.trade_type = trade_type;
  }
  public void setPrepay_id(String prepay_id) {
    this.prepay_id = prepay_id;
  }
  public void setCode_url(String code_url) {
    this.code_url = code_url;
  }
  public String getReturn_code() {
    return return_code;
  }
  public String getReturn_msg() {
    return return_msg;
  }
  public void setReturn_code(String return_code) {
    this.return_code = return_code;
  }
  public void setReturn_msg(String return_msg) {
    this.return_msg = return_msg;
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java版微信和支付宝退款接口

    本文实例为大家分享了java微信退款接口和支付宝退款接口的具体代码,供大家参考,具体内容如下 1.微信退款接口  相对来说我感觉微信的退款接口还是比较好调用的,直接发送httppost请求即可: /** * * 微信退款 * @param transaction_id 微信支付订单号 * @param out_refund_no 商户订单号 * @param total_fee 总金额 * @param refund_fee 退款金额 * @param op_user_id 操作人 * @ret

  • Java开发SSM框架微信退款的实现

    这篇文章是Java微信退款的教程,退款之前用户需要先进行支付,支付之后才可以使用退款.做到退款的同学应该已经是完成了支付了,我写的退款和支付的流程很相似只是所需的参数有所不同. String outTradeNo = request.getParameter("outTradeNo");// 获取商户订单号 Integer totalFee = Integer.parseInt(request.getParameter("totalFee"));// 获取支付金额

  • java实现微信点餐申请微信退款

    应用场景: 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家账号上. 注意事项: 1.交易时间超过一年的订单无法提交退款 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单好和设置不同的退款单号.申请退款总金额不能超过订单金额.一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号. 3.请求频率限制,150qps,即每秒钟正常的申请退

  • Java微信退款开发

    一.下载证书并导入到系统 微信支付接口中,涉及资金回滚的接口会使用到商户证书,包括退款.撤销接口.商家在申请微信支付成功后,可以按照以下路径下载:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->证书下载. 下载的时候需要手机验证及登录密码.下载后找到apiclient_cert.p12这个证书,双击导入,导入的时候提示输入密码,这个密码就是商户ID,且必须是在自己的商户平台下载的证书.否则会出现密码错误的提示: 导入正确的提示: 二.编写代码 首先初

  • java服务器端微信、支付宝支付和退款功能

    工作需要,写了服务器端的支付和退款功能,包含微信和支付宝,网上也有很多demo可以借鉴,我把我的代码放出来,写的比较简单,有问题的欢迎指正,大家一起学习. 微信支付需要调用微信的统一下单接口,而支付宝不用. 我写的时候微信和支付宝都单独写了一个工具类,来调用支付,给前端返回需要的数据. ps:支付是可以不需要服务器端的,不过为了安全一点点,所以前端需要调起支付的字段都直接从服务器端返回,前端拿到字段直接调起支付就可以了. Map<String,String> map = new HashMap

  • java实现微信退款功能

    微信退款之前需要在常量中配置退款地址,退款的地址必须是可以直接访问的.(之前的申请商户平台及在开放平台申请账号不在描述)在调起之前需要下载商户平台上的证书将其放在项目src下. 微信退款回调url :微信官方建议在提交退款申请后进行退款回调url配置,便于通知退款的结果.配置在微信商户平台->交易中心->退款配置栏进行退款结果回调通知配置.配置的url必须为可以直接访问的类似付款成功回调url. 配置成功后在回调的url中处理退款后的结果.微信给返回的参数如下: 对于加密信息req_info的

  • SpringBoot 微信退款功能的示例代码

    一:微信支付证书配置 二:证书读取以及读取后的使用 package com.zhx.guides.assistant.config.wechatpay; import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.H

  • PHP开发实现微信退款功能示例

    本文实例讲述了PHP开发实现微信退款功能.分享给大家供大家参考,具体如下: 最近在调微信退款接口,发现有许多坑,更大家分享一下 ① 要是在测试的时候,网页提示 curl 58 说明 证书的路径出现问题(这里要填物理路径,也就是绝对路径) ② 网页提示curl 52 说明你的证书引入少了,在官方的demo上只有两个证书 apiclient_cert.pem和 apiclient_key.pem  你还需要引入一个证书 rootca.pem,这个证书需要你登录到 你的商户平台上下载 ③ 要是网页提示

  • 小程序微信退款功能实现方法详解【基于thinkPHP】

    本文实例讲述了小程序微信退款功能实现方法.分享给大家供大家参考,具体如下: ☹. 背景 微信开发中,既然涉及到了微信支付,对于合理的购物网站,必定会有用户退款请求 当然,一种方式是登录 微信商户平台,在 交易列表 中进行微信退款操作 但是,如果业务量庞大,作为友好交互,自然需要进行代码实现 微信退款 操作咯 稍作一提,这是针对 小程序退款申请 的方法指导(目测跟公众号退款没啥区别) 理论上,请对应参考文章:小程序微信支付 实例配置详解 编程语言:PHP 使用框架:ThinkPHP3.2.3 (我

  • Java调用微信支付功能的方法示例代码

    Java 使用微信支付 前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用. 因为涉及二维码的前端显示,所以有前端的内容 一. 准备工作 所需微信公众号信息配置 APPID:绑定支付的APPID(必须配置) MCHID:商户号(必须配置) KEY:商户支付密钥,参考开户邮件设置(必须配置) APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) 我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供 二

  • SpringBoot整合Vue实现微信扫码支付以及微信退款功能详解

    直接上代码,在order模块添加依赖 <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency> 在配置类添加申请的商家号信息 #关联的公众号appid weixin.pay.appid=wxXXXXXXX #商户号 weixi

  • PHP实现微信退款功能

    大家好,我是小编,最近在调微信退款接口,发现有许多坑,更大家分享一下 ① 要是在测试的时候,网页提示 curl 58 说明 证书的路径出现问题(这里要填物理路径,也就是绝对路径) ②网页提示curl 52 说明你的证书引入少了,在官方的demo上只有两个证书 apiclient_cert.pem和 apiclient_key.pem  你还需要引入一个证书 rootca.pem,这个证书需要你登录到 你的商户平台上下载 3.要是网页提示  "HTTP/1.1 200 OK Server: ngi

  • java实现微信支付功能

    微信支付的具体实现方法,供大家参考,具体内容如下 工具类(用于在微信支付服务后台生成预支付交易单) 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; /** * * 类说明:除被扫支付场景以外,店铺系统先调用该接口在微信支付服务后台

  • java实现支付宝退款功能

    最近完成的差不多的项目突然需要加退款的流程需求了,所以来小小的实现以下. 其实对比其他的支付和退款来说,支付宝算是特别专业,也是特别简单的一个了. 一.引入支付宝SDK 在这里说一下,其实每种支付都会有一个官方带的SDK,我们可以把这个sdk引入到我们的项目中去,然后我们就可以调用里面的方法和对象,给里面传值,进行我们相应的请求的访问和介入. 首先引入如上图所示的jar包,然后我们就算是成功了一半了. 下载地址 然后我们需要把这个jar包引入到所需要的地方,这里不做过多的描述. 二.找到需要的资

  • Java编程调用微信分享功能示例

    本文实例讲述了Java编程调用微信分享功能.分享给大家供大家参考,具体如下: 这篇文章介绍如何使用java开发微信分享功能,因为工作,已经开发完成,可使用. 如果想要自定义微信的分享功能,首先在自己的页面内首先使用AJAX.下面我具体举例. 首先是在页面内写入请求后台的AJAX /** * 调用微信分享接口 * */ public void WXConfig(){ String url = getPara("href"); WXConfigController scan = new W

随机推荐