国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

微信APP支付——支付流程說明及示例

2019-11-09 17:14:48
字體:
來源:轉載
供稿:網友

微信APP支付——支付流程說明及示例

官方示例圖

微信支付官方文檔地址:https://pay.weixin.QQ.com/wiki/doc/api/app/app.php?chapter=8_3 官方流程圖:

商戶系統和微信支付系統主要交互說明:步驟1:用戶在商戶APP中選擇商品,提交訂單,選擇微信支付。步驟2:商戶后臺收到用戶支付單,調用微信支付統一下單接口。參見【統一下單API】。步驟3:統一下單接口返回正常的PRepay_id,再按簽名規范重新生成簽名后,將數據傳輸給APP。參與簽名的字段名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay步驟4:商戶APP調起微信支付。api參見本章節【app端開發步驟說明】步驟5:商戶后臺接收支付通知。api參見【支付結果通知API】步驟6:商戶后臺查詢支付結果。,api參見【查詢訂單API】

個人實際應用后的理解及實現

生成訂單(與支付寶不太一樣,訂單的生成是在微信支付系統中生成,而不是本地系統)。app調用接口。異步接收返回通知,并根據結果處理自己的業務邏輯。

生成訂單

組裝統一下單接口參數(一個xml字符串)。調用支付接口,發送接口參數,創建預付單。如果成功,則會返回一個有效的prepay_id,這是app調用微信支付的一個關鍵參數。將結果返回給APP端,APP端發起調用一些細節要注意,微信的單位是“分”,支付寶的單位是“元”,所以共用訂單的話要統一單位。如果出現“body不是UTF8編碼”,則是在使用URL發起請求時,統一接口編碼。 關鍵代碼(UTF-8部分):// 獲取URLConnection對象對應的輸出流out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(),"UTF-8"));// 發送請求參數out.print(param);

app調用接口

參考官方集成文檔:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5

異步接收返回通知,并根據結果處理自己的業務邏輯。

微信異步通知的返回地址是在生成訂單時發送的參數里包含的(notify_url)。接收到異步消息。返回結果是一個xml字符串 。將返回的xml解析到map集合中。驗證返回的數據(訂單是否存在,訂單狀態是否已經為成功,金額是否正常等)驗證通過,處理自己的業務邏輯(修改訂單狀態等)。由于是跟金錢掛鉤的,日志要寫得完善,我本地即寫庫也寫日志,所以代碼比較亂,不用的刪除即可。

注意問題

各個階段生成的前面是不一樣的,參見TenpayUtil類。下單和返回都需要是一個參數有序的(ASCII正序)xml。預留位置,后續更新

代碼

處理類VipWXPayController

import java.io.IOException;import java.io.PrintWriter;import java.math.BigDecimal;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap;import javax.annotation.Resource;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import net.sf.json.JSONObject;import org.apache.commons.lang.StringUtils;import org.apache.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;/** * 【會員管理】 微信支付 * @author pzr * */@SuppressWarnings({"unchecked"})@Controller@RequestMapping("/vipWXPay")public class VipWXPayController { @Resource private VipOrderMapper vipOrderMapper; @Resource private VipPriceMapper vipPriceMapper; @Resource private UserMapper userMapper; @Resource private VipWxpayAsynNotifyMapper vipWxpayAsynNotifyMapper; @Resource private VipPayNotifyMapper vipPayNotifyMapper; @Resource private VipPayService vipPayService; // 支付信息處理日志 /** * 支付日志 */ Logger payLogger = Logger.getLogger("pay-log"); /** * 微信支付的回調 * @return */ @RequestMapping(value = "/wxPay.do",method={RequestMethod.GET,RequestMethod.POST}) @ResponseBody public void wxPay(HttpServletRequest request,HttpServletResponse response){ payLogger.info("【=================================微信回調通知開始======================================】"); payLogger.info("【微信回調通知】正在接收微信回調報文......"); String resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> "; try { ServletInputStream in = request.getInputStream(); int size = request.getContentLength(); byte[] bdata = new byte[size]; in.read(bdata); String xmlstring = new String(bdata,TenpayUtil.getCharacterEncoding(request, response)); if(!StringUtils.isEmpty(xmlstring)){ payLogger.info("【微信回調通知】微信回調報文接收成功"); Map<String,String> paramMap = XmlUtil.parseXmlToMap(xmlstring); //打印返回結果// for(Map.Entry<String,String> entry : paramMap.entrySet()){// System.out.println(entry.getKey()+":"+entry.getValue());// } String result_code = paramMap.get("result_code").toString(); if("SUCCESS".equals(result_code.toUpperCase())){ //通過訂單id和訂單編號獲取指定的訂單信息 //存儲反饋信息,不要 注釋掉就可以了 VipWxpayAsynNotify vwan = saveSourceNotify(paramMap); VipOrder vo = new VipOrder(); vo.setId(paramMap.get("attach")); vo.setOrderNum(paramMap.get("out_trade_no")); payLogger.info("本地訂單號【"+vo.getOrderNum()+"】【微信回調通知】支付成功"); vo = vipOrderMapper.findByIdOrderNum(vo); payLogger.info("本地訂單號【"+vo.getOrderNum()+"】【微信回調通知】驗證請求真實性......"); boolean flag = checkTrue(vwan,vo);//驗證是否是微信返回的信息,防止“假請求” if(flag){ //存儲到后臺 支付通知表里 savePayNotify(vwan, vo); payLogger.info("用戶【"+vo.getUserName()+"】本地訂單號【"+vo.getOrderNum()+"】【微信回調通知】驗證通過,業務處理中......"); vipPayService.vipHandle(vo); payLogger.info("用戶【"+vo.getUserName()+"】本地訂單號【"+vo.getOrderNum()+"】【微信回調通知】業務處理完成"); }else{ payLogger.info("本地訂單號【"+vo.getOrderNum()+"】【微信回調通知】驗證未通過"); } }else{ payLogger.info("【微信回調通知】支付失敗,報錯信息【"+paramMap.get("return_msg").toString()+"】"); } resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "; }else{ payLogger.info("【微信回調通知】支付失敗,回調報文為空"); resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> "; } } catch (Exception e) { payLogger.info("【微信回調通知】內部異常"); e.printStackTrace(); }finally{ try { sendToCFT(resXml,response); } catch (IOException e) { e.printStackTrace(); } } payLogger.info("【=================================微信回調通知結束======================================】"); } /** * 保存支付通知 * @param vwan * @param vo */ private void savePayNotify(VipWxpayAsynNotify vwan, VipOrder vo) { VipPayNotify vipPayNotify = new VipPayNotify(); vipPayNotify.setGoodsId(vo.getGoodsId()); vipPayNotify.setGoodsName(vo.getGoodsName()); vipPayNotify.setOrderCreatetime(vo.getCreatetime()); vipPayNotify.setOrderNum(vo.getOrderNum());//訂單編號 vipPayNotify.setPayAmount(fenToYuan(vwan.getTotal_fee()));//總金額,單位是元,微信需要轉換 vipPayNotify.setPayState(vipPayService.getPayState(vwan.getReturn_code(),VipOrder.PAYMODE_WX));//返回狀態 vipPayNotify.setBusinessId(Integer.parseInt(vwan.getId())); vipPayNotify.setPayType(VipOrder.PAYMODE_WX); vipPayNotify.setUserId(vo.getUserId()); vipPayNotify.setUserName(vo.getUserName()); vipPayNotifyMapper.add(vipPayNotify); } /** * 存儲微信的原始回調信息 * @param paramMap * @return */ private VipWxpayAsynNotify saveSourceNotify(Map<String, String> paramMap) { //存儲到原始表 VipWxpayAsynNotify saveObj = new VipWxpayAsynNotify(); saveObj.setAppid(paramMap.get("appid")); saveObj.setAttach(paramMap.get("attach")); saveObj.setBank_type(paramMap.get("bank_type")); saveObj.setCash_fee(paramMap.get("cash_fee")); saveObj.setCash_fee_type(paramMap.get("cash_fee_type")); saveObj.setCoupon_count(paramMap.get("coupon_count")); saveObj.setCoupon_fee(paramMap.get("coupon_fee")); saveObj.setDevice_info(paramMap.get("device_info")); saveObj.setErr_code(paramMap.get("err_code")); saveObj.setErr_code_des(paramMap.get("err_code_des")); saveObj.setFee_type(paramMap.get("fee_type")); saveObj.setIs_subscribe(paramMap.get("is_subscribe")); saveObj.setMch_id(paramMap.get("mch_id")); saveObj.setNonce_str(paramMap.get("nonce_str")); saveObj.setOpenid(paramMap.get("openid")); saveObj.setOut_trade_no(paramMap.get("out_trade_no")); saveObj.setReturn_code(paramMap.get("return_code")); saveObj.setReturn_msg(paramMap.get("return_msg")); saveObj.setSign(paramMap.get("sign")); saveObj.setTime_end(paramMap.get("time_end")); saveObj.setTotal_fee(paramMap.get("total_fee")); saveObj.setTrade_type(paramMap.get("trade_type")); saveObj.setTransaction_id(paramMap.get("transaction_id")); vipWxpayAsynNotifyMapper.add(saveObj); return saveObj; } /** * 驗證數據真實性 * @param vaan * @return */ private boolean checkTrue(VipWxpayAsynNotify vwan,VipOrder vo) { //一、需要驗證該通知數據中的out_trade_no是否為商戶系統中創建的訂單號 //如果不存在則說明反饋的訂單號和訂單id對不上 if(vo == null){ payLogger.info("【微信回調通知】【訂單驗證失敗】未獲取本地訂單"); return false; } payLogger.info("【微信回調通知】【訂單驗證成功】獲取本地訂單"); //驗證訂單是否已經完成,避免重復執行會員購買業務 if(vo.getPayState().equals(VipOrder.PAYSTATE_SUCCESS) || vo.getPayState().equals(VipOrder.PAYSTATE_FINISHED)){ payLogger.info("【微信回調通知】【訂單驗證失敗】訂單已完成支付,訂單狀態為【"+vo.getPayState()+"】"); return false; } payLogger.info("【微信回調通知】【訂單驗證成功】訂單狀態正常,訂單狀態為【"+vo.getPayState()+"】"); //二、判斷total_amount是否確實為該訂單的實際金額(即商戶訂單創建時的金額) if(!YuanTofen(vo).equals(vwan.getTotal_fee())){ payLogger.info("【微信回調通知】【訂單驗證失敗】訂單金額異常,本地訂單金額【"+YuanTofen(vo)+"】,回調訂單金額【"+vwan.getTotal_fee()+"】"); return false; } payLogger.info("【微信回調通知】【訂單驗證成功】訂單金額正常,訂單金額為【"+vwan.getTotal_fee()+"】"); return true; } /** * 生成預支付單 * 商戶系統先調用該接口在微信支付服務后臺生成預支付交易單 * 返回正確的預支付交易回話標識后再在APP里面調起支付 * @param vipPriceId 套餐id * @param username 用戶名稱 * @param request * @param response * @return */ @RequestMapping(value = "/createOrder.do") @ResponseBody public JSONObject createOrder(@RequestParam("id") String vipPriceId, @RequestParam("username") String username, HttpServletRequest request, HttpServletResponse response ) { payLogger.info("【=================================微信訂單創建開始======================================】"); payLogger.info("用戶【" + username + "】開始創建微信訂單......"); User user = userMapper.findByName(username);//通過用戶名獲取用戶 VipPrice vipPrice = vipPriceMapper.findById(vipPriceId);//通過套餐id獲取套餐 VipOrder vo = vipPayService.addVipOrder(user, vipPrice,VipOrder.PAYMODE_WX);//創建訂單 JSONObject jsonCode = wXHandle(request, response, vo);//微信的訂單處理 payLogger.info("用戶【" + username + "】創建微信訂單成功,本地訂單號【"+vo.getOrderNum()+"】"); payLogger.info("【=================================微信訂單創建結束======================================】"); return jsonCode; } /** * 創建訂單,微信操作 * @param request * @param response * @param vo * @return */ private JSONObject wXHandle(HttpServletRequest request, HttpServletResponse response, VipOrder vo) { JSONObject jsonCode = new JSONObject(); payLogger.info("用戶【" + vo.getUserName() + "】【微信操作】【統一下單API】參數開始生成......"); String orderInfo = getOrderReqData(response, request, vo); payLogger.info("用戶【" + vo.getUserName() + "】【微信操作】【統一下單API】參數生成成功"); String orderJsonStr = ""; try { payLogger.info("用戶【" + vo.getUserName() + "】【微信操作】【統一下單API】開始調用......"); orderJsonStr = HttpRequest.sendPost(ConstantUtil.PAY_ORDER_URL, orderInfo); Map<String, String> mapOrder = XmlUtil.doXMLParse(orderJsonStr); if (mapOrder.get("return_code").toString().equals("SUCCESS")) { payLogger.info("用戶【" + vo.getUserName() + "】【微信操作】【統一下單API】調用成功,生成預付單"); //時間戳 String timestamp = OrderReqDataUtil.getTimeStamp(); jsonCode.put("appid",mapOrder.get("appid").toString()); jsonCode.put("partnerid", ConstantUtil.MCH_ID); jsonCode.put("prepay_id", mapOrder.get("prepay_id").toString()); jsonCode.put("packageValue", ConstantUtil.PACKAGE); jsonCode.put("timeStamp", timestamp); jsonCode.put("nonceStr", mapOrder.get("nonce_str")); jsonCode.put("sign",getAppSign(mapOrder,timestamp)); } else { jsonCode.put("msg", "errorCode"); payLogger.info("用戶【" + vo.getUserName() + "】【微信操作】【統一下單API】調用失敗,報錯信息【"+mapOrder.get("return_msg").toString()+"】"); } } catch (Exception e) { jsonCode.put("msg", "errorCode"); payLogger.info("用戶【" + vo.getUserName() + "】【微信操作】【統一下單API】內部異常"); e.printStackTrace(); } return jsonCode; } /** * 獲取APP調用微信支付的簽名 * @param mapOrder * @param timestamp * @return */ private String getAppSign(Map<String, String> mapOrder, String timestamp) { SortedMap<String, String> appParam = new TreeMap<String, String>(); appParam.put("appid", mapOrder.get("appid").toString()); appParam.put("noncestr", mapOrder.get("nonce_str")); appParam.put("package", "Sign=WXPay"); appParam.put("partnerid", ConstantUtil.MCH_ID); appParam.put("prepayid", mapOrder.get("prepay_id").toString()); appParam.put("timestamp", timestamp); return TenpayUtil.genAppSignMap(appParam); } /** * 統一下單 * 獲取請求參數組裝 * * @param strUrl * @return String */ private String getOrderReqData(HttpServletResponse response,HttpServletRequest request,VipOrder vo) { //使用有序集合 SortedMap<String, String> dataObj = new TreeMap<String, String>(); dataObj.put("appid", ConstantUtil.APP_ID);// 獲取appid參數 dataObj.put("mch_id", ConstantUtil.MCH_ID);// 微信支付分配的商戶號 dataObj.put("device_info", ConstantUtil.DEVICE_INFO);//終端設備號(門店號或收銀設備ID),默認請傳"WEB" dataObj.put("nonce_str", OrderReqDataUtil.getNonceStr());// 獲取隨機字符串 dataObj.put("body", vo.getGoodsName());// 商品或支付單簡要描述 dataObj.put("detail", getDetail(vo));// 商品詳情 //主要傳送訂單id dataObj.put("attach", vo.getId());// 附加數據,在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數據 dataObj.put("out_trade_no", vo.getOrderNum());// 戶系統內部的訂單號,32個字符內、可包含字母 dataObj.put("fee_type", ConstantUtil.FEE_TYPE);//貨幣類型 默認人民幣:CNY dataObj.put("total_fee", YuanTofen(vo));//訂單總金額 訂單金額; dataObj.put("spbill_create_ip", OrderReqDataUtil.getIpAddr(request));// APP和網頁支付提交用戶端ip // dataObj.put("time_start", // OrderReqDataUtil.getDateTime("yyyyMMddHHmmss"));//訂單生成時間 // dataObj.put("time_expire", // OrderReqDataUtil.getDateTime("yyyyMMddHHmmss"));//訂單失效時間,必須大于5分鐘 dataObj.put("notify_url", ConstantUtil.NOTIFY_URL);// 接收微信支付異步通知回調地址,通知url必須為直接可訪問的url,不能攜帶參數。 dataObj.put("trade_type", ConstantUtil.TRADE_TYPE);//支付類型 取值如下:JSAPI,NATIVE,APP dataObj.put("sign", TenpayUtil.genServerSign(dataObj));// 獲取簽名 //打印// for(Map.Entry<String, String> entry : dataObj.entrySet()){// System.out.println(entry.getKey()+":"+entry.getValue());// } // 生成xml參數字符串 String resObj = XmlUtil.getRequestXml(dataObj); return resObj; } /** * 獲取詳情json字符串 * @param vo */ private String getDetail(VipOrder vo) { WXDetail wxDetail = new WXDetail(); List<WXGoodsInfo> goodsInfoList = new ArrayList<WXGoodsInfo>(); WXGoodsInfo wxGoodsInfo = new WXGoodsInfo(); wxGoodsInfo.setBody(vo.getGoodsName()); wxGoodsInfo.setGoods_id(vo.getOrderNum()); wxGoodsInfo.setGoods_name(vo.getGoodsName()); wxGoodsInfo.setPrice(YuanTofen(vo));//總價格 wxGoodsInfo.setQuantity("1");//商品數量 goodsInfoList.add(wxGoodsInfo); wxDetail.setGoods_detail(goodsInfoList); //轉為json格式 JSONObject detailObject = JSONObject.fromObject(wxDetail); return detailObject.toString(); } /** * 獲取微信價格 * 原始價格為單位為元,微信單位為分,所以需要轉換 * @param vo * @return */ private String YuanTofen(VipOrder vo) { BigDecimal sourcePrice = new BigDecimal(vo.getCurrentPrice());//原始價格 單位元 BigDecimal b2 = new BigDecimal("100");//將元換算為分的單位 100 String tfee=Double.toString(sourcePrice.multiply(b2).doubleValue()); // 訂單金額 String total_fee = tfee.substring(0, tfee.indexOf(".")); return total_fee; } /** * 將分轉換為元 如:1 分= 0.01元 * @param price * @return */ private String fenToYuan(String price){ BigDecimal sourcePrice = new BigDecimal(price);//原始價格 單位元 BigDecimal b2 = new BigDecimal("100");//將元換算為分的單位 100 String tfee=Double.toString(sourcePrice.divide(b2).doubleValue()); // 訂單金額 return tfee; } /** * 給微信返回信息,通知接收情況 * @param msg * @param response * @throws IOException */ private void sendToCFT(String msg,HttpServletResponse response) throws IOException { String strHtml = msg; PrintWriter out = response.getWriter(); out.println(strHtml); out.flush(); out.close(); } }

基礎參數類 ConstantUtil

/** * 微信支付配置 * @author pzr * */public class ConstantUtil { /** * 商戶id */ public static String MCH_ID = "11111"; // 商戶號 // 商戶號 /** * 應用id,appId */ public static String APP_ID = "11111"; // 微信開發平臺應用id /** * APP_SECRET */ public static String APP_SECRET = "111111"; // 應用對應的憑證 /** * 秘鑰 */ public static String APP_KEY = "111111"; // 商戶號對應的密鑰 /** * 擴展字段 */ public static String PACKAGE = "Sign=WXPay"; // 擴展字段 暫填寫固定值Sign=WXPay /** * 設備號 */ public static String DEVICE_INFO = "WEB";// 設備號 終端設備號(門店號或收銀設備ID),默認請傳"WEB" /** * 通知回調接口路徑 */ public static String NOTIFY_URL = "http://11111"; /** * 鈔票類型 人民幣 */ public static String FEE_TYPE = "CNY"; /** * 交易類型 */ public static String TRADE_TYPE = "APP";//交易類型 /** * 固定的,統一下單后調用的生成預付單接口 */ public static String PAY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";}

工具類 OrderReqDataUtil

import java.text.SimpleDateFormat;import java.util.Date;import java.util.Random;import javax.servlet.http.HttpServletRequest;public class OrderReqDataUtil { public static void main(String args[]){ System.out.println(getRandomStringByLength(32)); } /** * 生成指定長度的隨機字符串 * @param length * @return */ public static String getRandomStringByLength(int length) { String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } /** * 生成隨機字符串 * * @return */ public static String getNonceStr() { Random random = new Random(); return md5Util.MD5Encode(String.valueOf(random.nextInt(10000)), "UTF-8"); } public static String getTimeStamp() { return String.valueOf(System.currentTimeMillis() / 1000); } public static String getDateTime(String format) { String temp_str = ""; Date dt = new Date(); // 最后的aa表示“上午”或“下午” HH表示24小時制 如果換成hh表示12小時制 SimpleDateFormat sdf = new SimpleDateFormat(format); temp_str = sdf.format(dt); return temp_str; } public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; }}

工具類 TenpayUtil

import java.text.SimpleDateFormat;import java.util.Date;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.SortedMap;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 微信支付工具 * @author pzr * */public class TenpayUtil { private static Object Server; private static String QRfromGoogle; /** * 把對象轉換成字符串 * * @param obj * @return String 轉換成字符串,若對象為null,則返回空字符串. */ public static String toString(Object obj) { if (obj == null) return ""; return obj.toString(); } /** * 把對象轉換為int數值. * * @param obj * 包含數字的對象. * @return int 轉換后的數值,對不能轉換的對象返回0。 */ public static int toInt(Object obj) { int a = 0; try { if (obj != null) a = Integer.parseInt(obj.toString()); } catch (Exception e) { } return a; } /** * 獲取當前時間 yyyyMMddHHmmss * * @return String */ public static String getCurrTime() { Date now = new Date(); SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss"); String s = outFormat.format(now); return s; } /** * 獲取當前日期 yyyyMMdd * * @param date * @return String */ public static String formatDate(Date date) { SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); String strDate = formatter.format(date); return strDate; } /** * 取出一個指定長度大小的隨機正整數. * * @param length * int 設定所取出隨機數的長度。length小于11 * @return int 返回生成的隨機數。 */ public static int buildRandom(int length) { int num = 1; double random = Math.random(); if (random < 0.1) { random = random + 0.1; } for (int i = 0; i < length; i++) { num = num * 10; } return (int) ((random * num)); } /** * 獲取編碼字符集 * * @param request * @param response * @return String */ public static String getCharacterEncoding(HttpServletRequest request, HttpServletResponse response) { if (null == request || null == response) { return "gbk"; } String enc = request.getCharacterEncoding(); if (null == enc || "".equals(enc)) { enc = response.getCharacterEncoding(); } if (null == enc || "".equals(enc)) { enc = "gbk"; } return enc; } /** * Url編碼 * @param content * @return */ public static String URLencode(String content) { String URLencode; URLencode = replace(Server.equals(content), "+", "%20"); return URLencode; } private static String replace(boolean equals, String string, String string2) { return null; } /** * 獲取unix時間,從1970-01-01 00:00:00開始的秒數 * * @param date * @return long */ public static long getUnixTime(Date date) { if (null == date) { return 0; } return date.getTime() / 1000; } public static String QRfromGoogle(String chl) { int widhtHeight = 300; String EC_level = "L"; int margin = 0; String QRfromGoogle; chl = URLencode(chl); QRfromGoogle = "http://chart.apis.google.com/chart?chs=" + widhtHeight + "x" + widhtHeight + "&cht=qr&chld=" + EC_level + "|" + margin + "&chl=" + chl; return QRfromGoogle; } /** * 時間轉換成字符串 * * @param date * 時間 * @param formatType * 格式化類型 * @return String */ public static String date2String(Date date, String formatType) { SimpleDateFormat sdf = new SimpleDateFormat(formatType); return sdf.format(date); } /** * 生成【調用統一下單API】階段的簽名 * 按參數名稱a-z排序, * 遇到空值的參數不參加簽名。 * MD5加密并轉換為大寫 */ public static String genServerSign(SortedMap<String, String> packageParams) { StringBuffer sb = new StringBuffer(); Set es = packageParams.entrySet(); Iterator it = es.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); String k = (String) entry.getKey(); String v = (String) entry.getValue(); if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + ConstantUtil.APP_KEY); System.out.println("md5 sb:" + sb); //MD5加密并全部轉換為大寫 String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); return sign; } /** * 生成【APP客戶端調用微信支付】階段簽名 * @param params * @return */ public static String genAppSignMap(SortedMap<String, String> appParams) { StringBuilder sb = new StringBuilder(); for(Map.Entry<String, String> entry : appParams.entrySet()){ sb.append(entry.getKey()); sb.append('='); sb.append(entry.getValue()); sb.append('&'); } sb.append("key="); sb.append(ConstantUtil.APP_KEY);//秘鑰 String appSign = MD5Util.MD5Encode(sb.toString(),"utf-8"); return appSign; } /** * 生成【APP客戶端調用微信支付】階段簽名 * @param params * @return */ public static String genAppSign(List<Param> params) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < params.size(); i++) { sb.append(params.get(i).getKey()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append("key="); sb.append(ConstantUtil.APP_KEY);//秘鑰 String appSign = MD5Util.MD5Encode(sb.toString(),"utf-8"); return appSign; }}

商品集合對象 WXDetail 只是為了組裝成需要的json格式可以直接用jsonArray

import java.util.List;public class WXDetail { /** * 微信商品詳情集合對象 */ private List<WXGoodsInfo> goods_detail; public List<WXGoodsInfo> getGoods_detail() { return goods_detail; } public void setGoods_detail(List<WXGoodsInfo> goods_detail) { this.goods_detail = goods_detail; }}

商品詳情對象 WXGoodsInfo

/** * 微信商品訂單詳情 * @author pzr * */public class WXGoodsInfo { /** * 【必填】商品編號 */ private String goods_id; /** * 【可選】微信支付定義的統一商品編號 */ private String wxpay_goods_id; /** * 【必填】商品名稱 */ private String goods_name; /** * 【必填】商品數量 */ private String quantity; /** * 【必填】商品單價 單位分 */ private String price; /** * 【可選】商品類目id */ private String goods_category; /** * 【可選】商品描述信息 長度1000 */ private String body; public String getGoods_id() { return goods_id; } public void setGoods_id(String goods_id) { this.goods_id = goods_id; } public String getWxpay_goods_id() { return wxpay_goods_id; } public void setWxpay_goods_id(String wxpay_goods_id) { this.wxpay_goods_id = wxpay_goods_id; } public String getGoods_name() { return goods_name; } public void setGoods_name(String goods_name) { this.goods_name = goods_name; } public String getQuantity() { return quantity; } public void setQuantity(String quantity) { this.quantity = quantity; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getGoods_category() { return goods_category; } public void setGoods_category(String goods_category) { this.goods_category = goods_category; } public String getBody() { return body; } public void setBody(String body) { this.body = body; }}

工具類 XmlUtil

import java.io.IOException;import java.io.InputStream;import java.io.StringReader;import java.io.UnsupportedEncodingException;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.SortedMap;import org.jdom2.Document;import org.jdom2.Element;import org.jdom2.JDOMException;import org.jdom2.input.SAXBuilder;import org.xml.sax.InputSource;public class XmlUtil { /** * 解析xml,返回第一級元素鍵值對。如果第一級元素有子節點,則此節點的值是子節點的xml數據。 * * @param strxml * @return * @throws JDOMException * @throws IOException */ public static Map<String, String> doXMLParse(String strxml) throws JDOMException, IOException { if (null == strxml || "".equals(strxml)) { return null; } Map<String, String> m = new HashMap<String, String>(); InputStream in = HttpClientUtil.String2Inputstream(strxml); SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(in); Element root = doc.getRootElement(); List list = root.getChildren(); Iterator it = list.iterator(); while (it.hasNext()) { Element e = (Element) it.next(); String k = e.getName(); String v = ""; List children = e.getChildren(); if (children.isEmpty()) { v = e.getTextNormalize(); } else { v=getChildrenText(children); } m.put(k, v); } // 關閉流 in.close(); return m; } /** * 獲取子結點的xml * * @param children * @return String */ public static String getChildrenText(List children) { StringBuffer sb = new StringBuffer(); if (!children.isEmpty()) { Iterator it = children.iterator(); while (it.hasNext()) { Element e = (Element) it.next(); String name = e.getName(); String value = e.getTextNormalize(); List list = e.getChildren(); sb.append("<" + name + ">"); if (!list.isEmpty()) { sb.append(getChildrenText(list)); } sb.append(value); sb.append("</" + name + ">"); } } return sb.toString(); } /** * 獲取xml編碼字符集 * * @param strxml * @return * @throws IOException * @throws JDOMException */ public static String getXMLEncoding(String strxml) throws JDOMException, IOException { InputStream in = HttpClientUtil.String2Inputstream(strxml); SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(in); in.close(); return (String) doc.getProperty("encoding"); } /** * @author wjj * @date 2016-06-01下午2:32:05 * @Description:將請求參數轉換為xml格式的string * @param parameters 請求參數 * @return */ public static String getRequestXml(SortedMap<String,String> parameters){ StringBuffer sb = new StringBuffer(); sb.append("<xml>"); Set es = parameters.entrySet(); Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); String v = (String)entry.getValue(); if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) { sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">"); }else { sb.append("<"+k+">"+v+"</"+k+">"); } } sb.append("</xml>"); String result =sb.toString();// try {// result = new String(result.getBytes("UTF-8"), "ISO-8859-1");// } catch (UnsupportedEncodingException e) {// e.printStackTrace();// } return result; } /** * XML轉為Map * @param xml * @return */ public static Map parseXmlToMap(String xml) { Map retMap = new HashMap(); try { StringReader read = new StringReader(xml); // 創建新的輸入源SAX 解析器將使用 InputSource 對象來確定如何讀取 XML 輸入 InputSource source = new InputSource(read); // 創建一個新的SAXBuilder SAXBuilder sb = new SAXBuilder(); // 通過輸入源構造一個Document Document doc = sb.build(source); Element root = (Element) doc.getRootElement();// 指向根節點 List<Element> es = root.getChildren(); if (es != null && es.size() != 0) { for (Element element : es) { retMap.put(element.getName(), element.getValue()); } } } catch (Exception e) { e.printStackTrace(); } return retMap; } }
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 崇文区| 新丰县| 渭源县| 浦江县| 吉安县| 台湾省| 无棣县| 抚州市| 公主岭市| 长沙县| 睢宁县| 天台县| 商洛市| 牡丹江市| SHOW| 兴国县| 和田县| 酒泉市| 东方市| 当雄县| 彭水| 桐庐县| 孟津县| 大余县| 江源县| 洛宁县| 凭祥市| 汤阴县| 呼伦贝尔市| 涡阳县| 三河市| 宿迁市| 历史| 彭州市| 宿州市| 平果县| 合作市| 原平市| 新民市| 秦安县| 科尔|