java實現(xiàn)微信退款功能
微信退款之前需要在常量中配置退款地址,退款的地址必須是可以直接訪問的。(之前的申請商戶平臺及在開放平臺申請賬號不在描述)在調(diào)起之前需要下載商戶平臺上的證書將其放在項目src下。

微信退款回調(diào)url :微信官方建議在提交退款申請后進行退款回調(diào)url配置,便于通知退款的結(jié)果。配置在微信商戶平臺-》交易中心-》退款配置欄進行退款結(jié)果回調(diào)通知配置。配置的url必須為可以直接訪問的類似付款成功回調(diào)url。

配置成功后在回調(diào)的url中處理退款后的結(jié)果。微信給返回的參數(shù)如下:

對于加密信息req_info的解密步驟如下。

解密過程中需要先到oracle官網(wǎng)下載對應(yīng)java版本的sercity包,然后將下載后的包中兩個jar復(fù)制到j(luò)dk/jre/lib/security/包下并覆蓋原jar.另外需要在項目中引入一個bcprov-jdk15on-158.jar

退款部分代碼:
// 構(gòu)造向微信發(fā)送參數(shù)的實體類
private Unifiedorder unifiedorder = new Unifiedorder();
// 微信的參數(shù)
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) {
// 參數(shù)組
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();
// 構(gòu)造簽名
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);
// 向微信發(fā)送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 {
// 關(guān)閉流
EntityUtils.consume(response.getEntity());
} finally {
response.close();
}
} catch (Exception e) {
msg.put("stateCode", MsgCode.SYS_ERROR);
msg.put("message ", "服務(wù)器異常");
}
} 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";
}
}
/**
* 微信退款回調(diào)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();//所有參與傳參的參數(shù)按照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;
}
}
向微信發(fā)送消息的類
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格式的參數(shù)
* @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提交參數(shù)到接口
* 并接受返回
* @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);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
org.jdom.Document doc;
doc = (org.jdom.Document) sb.build(source);
org.jdom.Element root = doc.getRootElement();// 指向根節(jié)點
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;
}
/**
* 解析申請退款之后微信退款回調(diào)返回的字符串中內(nèi)容
* @throws IOException
* @throws JDOMException
*/
public static Map<String, String> parseRefundNotifyXml(String refundXml) throws JDOMException, IOException{
ParseXMLUtils.jdomParseXml(refundXml);
StringReader read = new StringReader(refundXml);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
org.jdom.Document doc;
doc = (org.jdom.Document) sb.build(source);
org.jdom.Element root = doc.getRootElement();// 指向根節(jié)點
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);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
org.jdom.Document doc;
doc = (org.jdom.Document) sb.build(source);
org.jdom.Element root = doc.getRootElement();// 指向根節(jié)點
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);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
org.jdom.Document doc;
doc = (org.jdom.Document) sb.build(source);
org.jdom.Element root = doc.getRootElement();// 指向根節(jié)點
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;
}
/**
* 向微信發(fā)送企業(yè)付款請求并解析返回結(jié)果
* @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);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
org.jdom.Document doc;
doc = (org.jdom.Document) sb.build(source);
org.jdom.Element root = doc.getRootElement();// 指向根節(jié)點
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;
}
/**
* 構(gòu)造退款xml參數(shù)
* @param xml
* @return
*/
public static String refundXml(Unifiedorder unifiedorder){
xStream.autodetectAnnotations(true);
xStream.alias("xml", Unifiedorder.class);
return xStream.toXML(unifiedorder);
}
/**
* 構(gòu)造企業(yè)付款xml參數(shù)
* @param xml
* @return
*/
public static String transferXml(Transfers transfers){
xStream.autodetectAnnotations(true);
xStream.alias("xml", Transfers.class);
return xStream.toXML(transfers);
}
/**
* 構(gòu)造xml參數(shù)
* @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 "";
}
/**
* 構(gòu)造xml參數(shù)
* @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 "";
}
/**
* 構(gòu)造退款xml參數(shù)
* @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請求并得到返回結(jié)果
* @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();
}
// 從輸入流讀取返回內(nèi)容
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 {
/**
* 發(fā)送post請求
*
* @param url
* 請求地址
* @param outputEntity
* 發(fā)送內(nèi)容
* @param isLoadCert
* 是否加載證書
*/
public static CloseableHttpResponse Post(String url, String outputEntity, boolean isLoadCert) throws Exception {
HttpPost httpPost = new HttpPost(url);
// 得指明使用UTF-8編碼,否則到API服務(wù)器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;
}
}
解密微信退款中返回相關(guān)信息的字符串
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;
/**
* 解密微信退款中返回相關(guān)信息的字符串
* @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、統(tǒng)一下單獲取微信返回
* 解析的時候自動去掉CDMA
* @param xml
*/
@SuppressWarnings("unchecked")
public static UnifiedorderResult getUnifiedorderResult(String xml){
UnifiedorderResult unifieorderResult = new UnifiedorderResult();
try {
StringReader read = new StringReader(xml);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
Document doc;
doc = (Document) sb.build(source);
Element root = doc.getRootElement();// 指向根節(jié)點
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;
}
/**
* 獲取微信回調(diào)的參數(shù)并將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);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
Document doc;
doc = (Document) sb.build(source);
Element root = doc.getRootElement();// 指向根節(jié)點
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、微信回調(diào)后參數(shù)解析
* 解析的時候自動去掉CDMA
* @param xml
*/
@SuppressWarnings("unchecked")
public static WXPayResult getWXPayResult(String xml){
WXPayResult wXPayResult = new WXPayResult();
try {
StringReader read = new StringReader(xml);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
Document doc;
doc = (Document) sb.build(source);
Element root = doc.getRootElement();// 指向根節(jié)點
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); // 將字符串轉(zhuǎn)為XML
Element rootElt = doc.getRootElement(); // 獲取根節(jié)點smsReport
System.out.println("根節(jié)點是:"+rootElt.getName());
Iterator iters = rootElt.elementIterator("sendResp"); // 獲取根節(jié)點下的子節(jié)點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節(jié)點下的子節(jié)點stat值
String smsID = recordEle.elementTextTrim("smsID"); // 拿到sms節(jié)點下的子節(jié)點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);
// 創(chuàng)建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入
InputSource source = new InputSource(read);
// 創(chuàng)建一個新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
// 通過輸入源構(gòu)造一個Document
org.jdom.Document doc;
doc = (org.jdom.Document) sb.build(source);
org.jdom.Element root = doc.getRootElement();// 指向根節(jié)點
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;
}
}
微信支付相關(guān)的常量
package com.wellness.platfront.common.weixinutil;
/**
* 微信支付相關(guān)的常量
* @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";
}
微信退款狀態(tài)常量
package com.wellness.platfront.common.weixinutil;
/**
* 微信退款狀態(tài)常量
* @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="退款異常";
//退款關(guān)閉
public static final String REFUND_CLOSED="退款關(guān)閉";
}
微信退款訂單信息
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;
//退款發(fā)起時間
public Date create_time;
//退款狀態(tài) 申請退款中 申請退款失敗 退款成功 退款異常 退款關(guān)閉
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;
}
}
這個實體類中參數(shù)和微信官方需要的參數(shù)一致
package com.wellness.platfront.entity.weixin;
import java.io.Serializable;
import com.wellness.platfront.entity.member.Member;
/**
* 統(tǒng)一下單提交為微信的參數(shù)
* @author
* @date 2017年08月11日
*/
public class Unifiedorder implements Serializable{
private static final long serialVersionUID = 1L;
//微信支付表id
private Integer weixinId;
//微信分配的公眾賬號ID(企業(yè)號corpid即為此appId)
private String appid;
//商戶id
private String mch_id;
//終端設(shè)備號(門店號或收銀設(shè)備ID),注意:PC網(wǎng)頁或公眾號內(nèi)支付請傳"WEB"
private String device_info;
//隨機字符串:數(shù)字+大寫字母的組合,32位
private String nonce_str;
//簽名
private String sign;
//商品或支付單簡要描述
private String body;
//商品名稱明細列表
private String detail;
//附加參數(shù)(例如:用于區(qū)別本商戶不同的分店)
private String attach;
//商戶系統(tǒng)內(nèi)部的訂單號
private String out_trade_no;
//貨幣類型:符合ISO 4217標準的三位字母代碼,默認人民幣:CNY
private String fee_type;
//總金額
private int total_fee;
//APP和網(wǎng)頁支付提交[用戶端ip],Native支付填調(diào)用微信支付API的機器IP。
private String spbill_create_ip;
//訂單生成時間,格式為yyyyMMddHHmmss,
private String time_start;
//訂單失效時間,格式為yyyyMMddHHmmss,最短失效時間間隔必須大于5分鐘[支付寶是30分鐘,同樣30分鐘]
private String time_expire;
//商品標記,代金券或立減優(yōu)惠功能的參數(shù)
private String goods_tag;
//接收微信支付異步通知回調(diào)地址
private String notify_url;
//交易類型:JSAPI,NATIVE,APP h5為 MWEB
private String trade_type;
//trade_type=NATIVE,此參數(shù)必傳。此id為二維碼中包含的商品ID,商戶自行定義。
private String product_id;
//no_credit--指定不能使用信用卡支付
private String limit_pay;
//trade_type=JSAPI,此參數(shù)必傳,用戶在商戶appid下的唯一標識
private String openid;
//商戶內(nèi)部自己的退款單號
private String out_refund_no;
//退款總金額單位為分
private int refund_fee;
//操作員的id默認為mch_id
private String op_user_id;
//微信官方提供的訂單號
private String prepayid;
//記錄所對應(yīng)的member
private Member member;
//返回給微信的狀態(tài)碼(用于支付回調(diào)時)
public String return_code;
//微信h5支付時候的場景信息官方的信息模板 {"h5_info"://h5支付固定傳"h5_info"
//{"type":"",//場景類型 "wap_url":"",//WAP網(wǎng)站URL地址"wap_name": ""http://WAP 網(wǎng)站名}}
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;
}
}
統(tǒng)一下單微信返回的參數(shù)組(xml)
package com.wellness.platfront.entity.weixin;
/**
* 統(tǒng)一下單微信返回的參數(shù)組(xml)
* @author
* @date 2017年08月11日
*/
public class UnifiedorderResult {
private String appid;//appid
private String mch_id;//商家id
private String device_info;//設(shè)備號
private String nonce_str;//隨機字符串
private String sign;//簽名
private String result_code;//錯誤碼
private String err_code;//錯誤代碼
private String err_code_des;//錯誤返回的信息描述
private String trade_type;//調(diào)用接口提交的交易類型,取值如下:JSAPI,NATIVE,APP
private String prepay_id;//微信生成的預(yù)支付回話標識,用于后續(xù)接口調(diào)用中使用,該值有效期為2小時
private String code_url;//trade_type為NATIVE是有返回,可將該參數(shù)值生成二維碼展示出來進行掃碼支付
private String return_code;//返回狀態(tài)碼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;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot詳細講解如何創(chuàng)建及刷新Spring容器bean
前面看spring源碼時可以發(fā)現(xiàn)refresh()方法十分重要。在這個方法中會加載beanDefinition,同時創(chuàng)建bean對象。那么在springboot中有沒有使用這個refresh()方法呢2022-06-06
Java Volatile應(yīng)用單例模式實現(xiàn)過程解析
這篇文章主要介紹了Java Volatile應(yīng)用單例模式實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11
詳解Spring boot上配置與使用mybatis plus
這篇文章主要介紹了詳解Spring boot上配置與使用mybatis plus,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05
在MyBatis中使用 # 和 $ 書寫占位符的區(qū)別說明
這篇文章主要介紹了在MyBatis中使用 # 和 $ 書寫占位符的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10

