java 微信支付实现
生活随笔
收集整理的這篇文章主要介紹了
java 微信支付实现
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、業(yè)務(wù)需求
實(shí)現(xiàn)app微信支付,后端需要做生成預(yù)支付單,響應(yīng)支付結(jié)果
二、業(yè)務(wù)流程
查看官方文檔
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3
三、實(shí)現(xiàn)方法
3.1 創(chuàng)建微信工具類??ConstantUtil
public class ConstantUtil {/*** 微信開(kāi)發(fā)平臺(tái)應(yīng)用ID*/public static final String APP_ID="wx2421b1c4370ec43b";/*** 應(yīng)用對(duì)應(yīng)的憑證*/public static final String APP_SECRET="1add1a30ac87aa2db72f57a2375d8fec";/*** 應(yīng)用對(duì)應(yīng)的密鑰*/public static final String APP_KEY="1add1a30ac87aa2db72f57a2375d8fec";/*** 微信支付商戶號(hào)*/public static final String MCH_ID="10000100";/*** 商品描述*/public static final String BODY="充值";/*** 商戶號(hào)對(duì)應(yīng)的密鑰*/public static final String PARTNER_key="*******"; /*** 商戶id*/public static final String PARTNER_ID="*******"; /*** 常量固定值*/public static final String GRANT_TYPE="client_credential";/*** 獲取預(yù)支付id的接口url*/public static String GATEURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";/*** 微信服務(wù)器回調(diào)通知url*/public static String NOTIFY_URL="http://url"; //可以訪問(wèn)的url/*** 微信服務(wù)器查詢訂單url*/public static String ORDER_QUERY="https://api.mch.weixin.qq.com/pay/orderquery";}
3.2 生成預(yù)支付訂單
Map<String, Object> getOrder(@RequestParam(value = "totalFee") String totalFee, @RequestParam(value = "deviceInfo") String deviceInfo,@RequestParam(value = "attach") String attach,HttpServletRequest request, HttpServletResponse response)throws Exception {Map<String, Object> map = new HashMap<String, Object>();// 獲取生成預(yù)支付訂單的請(qǐng)求類PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response); // String totalFee = request.getParameter("total_fee");int total_fee = (int) (Float.valueOf(totalFee) * 100);System.out.println("total:" + total_fee);System.out.println("total_fee:" + total_fee);prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID);prepayReqHandler.setParameter("body", ConstantUtil.BODY);prepayReqHandler.setParameter("mch_id", ConstantUtil.MCH_ID);prepayReqHandler.setParameter("device_info", deviceInfo); //卡號(hào)prepayReqHandler.setParameter("attach", attach);//套餐值String nonce_str = WXUtil.getNonceStr();prepayReqHandler.setParameter("nonce_str", nonce_str);prepayReqHandler.setParameter("notify_url", ConstantUtil.NOTIFY_URL);out_trade_no = String.valueOf(UUID.next());prepayReqHandler.setParameter("out_trade_no", out_trade_no);prepayReqHandler.setParameter("spbill_create_ip", request.getRemoteAddr());String timestamp = WXUtil.getTimeStamp();prepayReqHandler.setParameter("time_start", timestamp);System.out.println(String.valueOf(total_fee));prepayReqHandler.setParameter("total_fee", String.valueOf(total_fee));prepayReqHandler.setParameter("trade_type", "APP");/*** 注意簽名(sign)的生成方式,具體見(jiàn)官方文檔(傳參都要參與生成簽名,且參數(shù)名按照字典序排序,最后接上APP_KEY,轉(zhuǎn)化成大寫(xiě))*/prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign());prepayReqHandler.setGateUrl(ConstantUtil.GATEURL);String prepayid = prepayReqHandler.sendPrepay();// 若獲取prepayid成功,將相關(guān)信息返回客戶端if (prepayid != null && !prepayid.equals("")) {String signs = "appid=" + ConstantUtil.APP_ID + "&noncestr=" + nonce_str + "&package=Sign=WXPay&partnerid="+ ConstantUtil.PARTNER_ID + "&prepayid=" + prepayid + "×tamp=" + timestamp + "&key="+ ConstantUtil.APP_KEY;map.put("code", 0);map.put("info", "success");map.put("prepayid", prepayid);/*** 簽名方式與上面類似*/map.put("sign", MD5Util.MD5Encode(signs, "utf8").toUpperCase());map.put("appid", ConstantUtil.APP_ID);map.put("device_info", deviceInfo);map.put("attach", attach);map.put("timestamp", timestamp); //等于請(qǐng)求prepayId時(shí)的time_startmap.put("noncestr", nonce_str); //與請(qǐng)求prepayId時(shí)值一致map.put("package", "Sign=WXPay"); //固定常量map.put("partnerid", ConstantUtil.PARTNER_ID);} else {map.put("code", 1);map.put("info", "獲取prepayid失敗");}return map;}
? 3.3? 異步通知客戶結(jié)果
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");System.out.println("微信支付通知結(jié)果:" + result);Map<String, String> map = null;try {/*** 解析微信通知返回的信息*/map = XMLUtil.doXMLParse(result);} catch (JDOMException e) {// TODO Auto-generated catch block e.printStackTrace();}
官方文檔中特別提醒:商戶系統(tǒng)對(duì)于支付結(jié)果通知的內(nèi)容一定要做簽名驗(yàn)證,并校驗(yàn)返回的訂單金額是否與商戶側(cè)的訂單金額一致,防止數(shù)據(jù)泄漏導(dǎo)致出現(xiàn)“假通知”,造成資金損失
支付結(jié)果通知內(nèi)容做簽名驗(yàn)證
//支付成功后sign校驗(yàn)
String appid=map.get("appid");
String transaction_id=map.get("transaction_id");
String nonce_str =map.get("nonce_str");
String bank_type =map.get("bank_type");
String openid=map.get("openid");
String sign =map.get("sign");
String fee_type =map.get("fee_type");
String mch_id =map.get("mch_id");
String cash_fee =map.get("cash_fee");
String device_info =map.get("device_info");
String out_trade_no =map.get("out_trade_no");
String total_fee =map.get("total_fee");
String trade_type =map.get("trade_type");
String result_code =map.get("result_code");
String attach =map.get("attach");
String time_end =map.get("time_end");
String is_subscribe =map.get("is_subscribe");
String return_code=map.get("return_code");
PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);
prepayReqHandler.setParameter("appid",appid);
prepayReqHandler.setParameter("attach",attach);
prepayReqHandler.setParameter("bank_type",bank_type);
prepayReqHandler.setParameter("cash_fee",cash_fee);
prepayReqHandler.setParameter("device_info",device_info);
prepayReqHandler.setParameter("fee_type",fee_type);
prepayReqHandler.setParameter("is_subscribe",is_subscribe);
prepayReqHandler.setParameter("mch_id",mch_id);
prepayReqHandler.setParameter("nonce_str",nonce_str);
prepayReqHandler.setParameter("openid",openid);
prepayReqHandler.setParameter("out_trade_no",out_trade_no);
prepayReqHandler.setParameter("result_code",result_code);
prepayReqHandler.setParameter("return_code",return_code);
prepayReqHandler.setParameter("time_end",time_end);
prepayReqHandler.setParameter("total_fee",total_fee);
prepayReqHandler.setParameter("trade_type",trade_type);
prepayReqHandler.setParameter("transaction_id",transaction_id);
String endSigns =prepayReqHandler.createMD5Sign(); //支付結(jié)果通知的內(nèi)容 簽名校驗(yàn)
? 商戶金額的查詢
PrepayIdRequestHandler orderQueryHandler = new PrepayIdRequestHandler(request, response);orderQueryHandler.setParameter("appid",appid);orderQueryHandler.setParameter("mch_id",mch_id);orderQueryHandler.setParameter("out_trade_no",out_trade_no);orderQueryHandler.setParameter("nonce_str",nonce_str);orderQueryHandler.setParameter("sign",orderQueryHandler.createMD5Sign());orderQueryHandler.setGateUrl(ConstantUtil.ORDER_QUERY);String resXml = "";WeixinOrderBean orderBean =orderQueryHandler.selectOrder();
應(yīng)答微信
if(sign.equals(endSigns) && Integer.parseInt(total_fee)==orderBean.getTotal_fee()){ // 簽名通過(guò)并且返回的訂單的金額與商戶金額相同// 若支付成功,則告知微信服務(wù)器收到通知if (map.get("return_code").equals("SUCCESS")) {System.out.println("充值成功!");//PayRecord payRecord=payRecordService.get(Long.valueOf(map.get("out_trade_no")));System.out.println("訂單號(hào):" + Long.valueOf(map.get("out_trade_no")));String iccids = map.get("device_info");String monthNum = map.get("attach");//根據(jù)自己的業(yè)務(wù)處理int count =trafficCardListService.selectExistTrafficCardByOutTradeNo(map.get("out_trade_no")); //查詢商戶訂單號(hào)是否存在if(count==0){//不存在就插入List<MsisdnOrderBean> msisdnOrderList = trafficCardListService.selectTrafficCardRechargeResult(iccids, monthNum);if (msisdnOrderList.size() > 0) {for (MsisdnOrderBean msisdnOrderBean : msisdnOrderList) {msisdnOrderBean.setOutTradeNo(map.get("out_trade_no"));msisdnOrderBean.setDate(map.get("time_end"));msisdnOrderBean.setIccids(map.get("device_info"));// msisdnOrderBean.setTotalFee(Integer.parseInt(map.get("total_fee")));msisdnOrderBean.setTotalFee(BigDecimal.valueOf(Integer.parseInt(map.get("total_fee"))).divide(new BigDecimal(100)).doubleValue());msisdnOrderBean.setTransactionId(map.get("transaction_id"));msisdnOrderBean.setTrafficNo(DateUtils.getNowDataTime() + ApiUtils.getFourRandom()); //年月日時(shí)分秒+四位隨機(jī)數(shù) trafficCardListService.insertTrafficCardList(msisdnOrderBean);}}}resXml = XMLUtil.setXML("SUCCESS", "OK");} else {resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"+ "<return_msg><![CDATA[通知簽名驗(yàn)證失敗]]></return_msg>" + "</xml> ";logger.info("通知簽名驗(yàn)證失敗");}}else{resXml =XMLUtil.setXML("FAIL", "簽名不一致");}writer.write(resXml);writer.flush();writer.close();
運(yùn)用到的 PrepayIdRequestHandler? 工具類
public class PrepayIdRequestHandler extends RequestHandler {public PrepayIdRequestHandler(HttpServletRequest request,HttpServletResponse response) {super(request, response);}public String createMD5Sign() {StringBuffer sb = new StringBuffer();Set es = super.getAllParameters().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();sb.append(k + "=" + v + "&");}String params=sb.append("key="+ConstantUtil.APP_KEY).substring(0);String sign = MD5Util.MD5Encode(params, "utf8");return sign.toUpperCase();}// 提交預(yù)支付public String sendPrepay() throws Exception {String prepayid = "";Set es=super.getAllParameters().entrySet();Iterator it=es.iterator();StringBuffer sb = new StringBuffer("<xml>");while(it.hasNext()){Map.Entry entry = (Map.Entry) it.next();String k = (String) entry.getKey();String v = (String) entry.getValue();sb.append("<"+k+">"+v+"</"+k+">");}sb.append("</xml>");String params=sb.substring(0);System.out.println("請(qǐng)求參數(shù):"+params);String requestUrl = super.getGateUrl();System.out.println("請(qǐng)求url:"+requestUrl);TenpayHttpClient httpClient = new TenpayHttpClient();httpClient.setReqContent(requestUrl);String resContent = "";if (httpClient.callHttpPost(requestUrl, params)) {resContent = httpClient.getResContent();System.out.println("獲取prepayid的返回值:"+resContent);Map<String,String> map=XMLUtil.doXMLParse(resContent);if(map.containsKey("prepay_id"))prepayid=map.get("prepay_id");}return prepayid;}// 查詢訂單public WeixinOrderBean selectOrder() throws Exception {Set es=super.getAllParameters().entrySet();Iterator it=es.iterator();StringBuffer sb = new StringBuffer("<xml>");while(it.hasNext()){Map.Entry entry = (Map.Entry) it.next();String k = (String) entry.getKey();String v = (String) entry.getValue();sb.append("<"+k+">"+v+"</"+k+">");}sb.append("</xml>");String params=sb.substring(0);System.out.println("請(qǐng)求參數(shù):"+params);String requestUrl = super.getGateUrl();System.out.println("請(qǐng)求url:"+requestUrl);TenpayHttpClient httpClient = new TenpayHttpClient();httpClient.setReqContent(requestUrl);String resContent = "";WeixinOrderBean orderBean =new WeixinOrderBean();if (httpClient.callHttpPost(requestUrl, params)) {resContent = httpClient.getResContent();Map<String,String> map=XMLUtil.doXMLParse(resContent);if(map.size()>0){orderBean.setAppid(map.get("appid"));orderBean.setAttach(map.get("attach"));orderBean.setDevice_info(map.get("device_info"));orderBean.setBank_type(map.get("bank_type"));orderBean.setMch_id(map.get("mch_id"));orderBean.setNonce_str(map.get("nonce_str"));orderBean.setTotal_fee(Integer.parseInt(map.get("total_fee")));orderBean.setTrade_state(map.get("trade_state"));}}return orderBean;} }?
轉(zhuǎn)載于:https://www.cnblogs.com/jihaibo/p/9036423.html
總結(jié)
以上是生活随笔為你收集整理的java 微信支付实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pycharm中from xx impo
- 下一篇: 爬虫批量下载全站小说并自动保存