微信支付-公众号支付

xiaoxiao2021-02-28  47

微信支付的步骤集合一样的

1、统一下单

2、支付结果通知

3、查询订单

一、统一下单

统一下单需要的参数 查看对应网址https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

其中需要用到openid,openid的获取要先获取授权code,然后通过code获取openid

获取code 我用的是静默授权

     /**微信网页授权获取CODE**/     public static String WEB_OAUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";

//弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息     public static final String SNSAPI_USERINFO = "snsapi_userinfo";     //不弹出授权页面,直接跳转,只能获取用户openid 静默授权     public static final String SNSAPI_BASE = "snsapi_base";

@RequestMapping(params = "getCode",method ={RequestMethod.GET, RequestMethod.POST})     public void getCode(HttpServletRequest request,HttpServletResponse response) throws Exception{         参数根据自己的需求,自己传的什么获取什么,这些是我要用的。可以不用传参数         String goodsid = request.getParameter("goodsId");         //String type=request.getParameter("type");        // String priceInterval=request.getParameter("priceInterval");                  //获取商品价格 绿色字的获取授权code必须填的 1跳转路径;2APPID;3用户授权         String pprice = request.getParameter("pprice");

获取到一个资源重定向到这个资源路径中去,只能用微信浏览器打开

        String resource=oauthurl( ConfigUtil.getProperty("weChat_redirect_URI")+"&goodsid="+goodsid+"&pprice="+pprice+"&type="+type+"&priceInterval="+priceInterval, ConfigUtil.getProperty("appId"),OAuth2Util.SNSAPI_BASE);     System.out.println(resource);     response.sendRedirect(resource);     }

//授权路径做编码

public static String oauthurl(String targetUrl, String appid,String scope) {         String shareurl = "";         String encodeTargetURL = "";         try {             encodeTargetURL = URLEncoder.encode(targetUrl, "UTF-8");         } catch (UnsupportedEncodingException e) {             //这种一般不做处理             e.printStackTrace();         }         shareurl = WeiXinOpens.WEB_OAUTH_URL.replace("APPID", appid).replace("REDIRECT_URI", encodeTargetURL).replace("SCOPE", scope);         return shareurl;     }

      /**      * 通过code获取openid 统一生成订单。这个方法就是上面获取code时填写的跳转路径      * @param request      * @param response      * @return      * @throws Exception      */     @RequestMapping(params = "buyCourse",method ={RequestMethod.GET, RequestMethod.POST})     public ModelAndView buyCourse(HttpServletRequest request,             HttpServletResponse response) throws Exception {         JSONObject object = null;         //获取openID         String openId = ResourceUtil.getUserOpenId();         String orderid=UUIDGenerator.generate();          String appid = ConfigUtil.getProperty("appId");          String secret = ConfigUtil.getProperty("appSecret");

//获取code

        String code =request.getParameter("code");         String type=request.getParameter("type");         //获取订阅周期,每个月按30天算,年按365天。当type=4dates不等于0时保存到期时间         String priceInterval=request.getParameter("priceInterval");         //判断openID是否为空,为空根据code获取token和openID         if(null==openId||"".equals(openId)){         Map<String,Object> maptoken = new RemoteWeixinMethod().getOauth2AccessToken(new Oauth2CodePojo(appid, secret, code));                  openId = (String)maptoken.get("openid");         }         request.getSession().setAttribute(WeiXinConstants.USER_OPENID, openId);         //终端IP         String remoteAddr = request.getRemoteAddr();         //获取商品ID         String goodsid = request.getParameter("goodsid");         //加入订单详情         GoodsInfomationEntity goodsInfomation=goodsInfomationDao.getByEbookId(goodsid);         //获取商品价格         String price = request.getParameter("pprice");         BigDecimal coursePrice =new BigDecimal(price);             String sn = orderid;             OrderEntity orderEntity    = orderDao.getorder(openId, goodsid);                                      // 调用pay包中的方法生成微信预支付信息                     //商品描述                     String description = "课程购买";                     //统一下单生成课程购买订单,并返回微信需要的预支付信息 得到prepayid                     Map<String,String> map =weixinPrePay.weixinPrePay(sn, coursePrice, description, remoteAddr,openId);                     //获取订单信息反给页面 把通过prepayid进行二次签名的信息返给页面                     object = weixinPrePay.getPayParam(map);                     String returnCode = map.get("return_code");                     if(returnCode.equalsIgnoreCase("FAIL")){                         String return_msg=object.getString("return_msg");                         request.setAttribute("return_msg", return_msg);                         return new ModelAndView("weixin/guanjia/minimail/pay");                     }else{                         if(null==orderEntity){                         OrderEntity newCartOrder = new OrderEntity();                         newCartOrder.setOrderid(sn);                         newCartOrder.setOpenid(openId);                         newCartOrder.setGoodsid(goodsid);                         newCartOrder.setPaymode(1l);                         newCartOrder.setStatus(0l);                         newCartOrder.setPrice(coursePrice);                         List<OrderEntity> orderEntityList=orderDao.getByStatus();                         if(null!=orderEntityList){                             //删除没有支付的订单及详情                             for (OrderEntity orderEntity2 : orderEntityList) {                                 OrderDetailEntity orderDetailEntity=orderDetailDao.getorderDetail(orderEntity2.getId());                                 orderService.delete(orderEntity2);                                 if(null!=orderDetailEntity){                                     orderdetailService.delete(orderDetailEntity);                                     }                             }                                                  }                         orderService.save(newCartOrder);                         OrderDetailEntity orderDetail=new OrderDetailEntity();                         orderDetail.setAuther(goodsInfomation.getAuther());                         orderDetail.setAutherid(goodsInfomation.getAutherid());                         orderDetail.setGoodsid(goodsid);                         orderDetail.setGoodsname(goodsInfomation.getGoodname());                         orderDetail.setPicture(goodsInfomation.getPicture());                         orderDetail.setPprice(coursePrice);                         orderDetail.setOrderid(newCartOrder.getId());                         orderdetailService.save(orderDetail);                         }else{                             orderEntity.setId(orderEntity.getId());                             orderService.saveOrUpdate(orderEntity);                         }                         //获取得到的结果传入前台页面 调起支付                         String weixinappid=object.getString("appid");                         String partnerid=object.getString("partnerid");                         String packagewx=object.getString("package");                         String noncestr=object.getString("noncestr");                         String timestamp=object.getString("timestamp");                         String sign=object.getString("sign");                         request.setAttribute("appid", weixinappid);                         //收款方                         request.setAttribute("partnerid", partnerid);                         request.setAttribute("package", packagewx);                         request.setAttribute("noncestr", noncestr);                         request.setAttribute("timestamp", timestamp);                         request.setAttribute("sign", sign);                         request.setAttribute("pprice", coursePrice);                         request.setAttribute("orderid", sn);                         request.setAttribute("openId", openId);                         request.setAttribute("goodsid", goodsid);                         request.setAttribute("type", type);                         request.setAttribute("priceInterval", priceInterval);                         request.setAttribute("picture", goodsInfomation.getPicture());                         request.setAttribute("cxUrl", ConfigUtil.getProperty("weixin_cxUrl"));                         request.setAttribute("appPictureUrl",ConfigUtil.getProperty("APP_Picture_url"));

//跳到支付页面

                        return new ModelAndView("weixin/guanjia/minimail/pay");                                      }     }

统一下单,获取签名,与调起时的二次生成签名

public class WinxinAppPrePay {     private PayCommonUtil payCommonUtil;     public String norifyUrl;     public Map<String, String> weixinPrePay(String sn, BigDecimal totalAmount,             String description, String remoteAddr,String openid) {         SortedMap parameterMap = new TreeMap();         //公众账号ID         parameterMap.put("appid", this.payCommonUtil.getAppId());         //商户号         parameterMap.put("mch_id", this.payCommonUtil.getMchId());         //设备号         parameterMap.put("device_info", this.payCommonUtil.getDeviceInfo());         //随机字符串         parameterMap.put("nonce_str", this.payCommonUtil.getRandomString(32));         //签名类型         parameterMap.put("sign_type", "MD5");         try {             //如:小张南山店-超市             description = new String(description.getBytes("utf-8"));         } catch (UnsupportedEncodingException e1) {             e1.printStackTrace();         }         parameterMap.put("body",                 StringUtils.abbreviate(description.replaceAll(                         "[^0-9a-zA-Z\\u4e00-\\u9fa5 ]", ""), 600));         //商户订单号         parameterMap.put("out_trade_no", sn);         //用户标识         parameterMap.put("openid", openid);         //标价币种         parameterMap.put("fee_type", "CNY");         BigDecimal total = totalAmount.multiply(new BigDecimal(100));         DecimalFormat df = new DecimalFormat("0");         //标价金额         parameterMap.put("total_fee", df.format(total));         //终端IP         parameterMap.put("spbill_create_ip", remoteAddr);         //异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。         parameterMap.put("notify_url", this.norifyUrl);         //交易类型         parameterMap.put("trade_type", "JSAPI");         //通过签名算法计算得出的签名值,详见签名生成算法 第一次签名         String sign = this.payCommonUtil.createSign("UTF-8", parameterMap);         parameterMap.put("sign", sign);         //请求xml组装         String requestXML = this.payCommonUtil.getRequestXml(parameterMap);         System.out.println(requestXML);         //统一下单 获取prepay_id         String result = this.payCommonUtil.httpsRequest(                 "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",                 requestXML);         System.out.println(result);         Map map = null;         try {             map = this.payCommonUtil.doXMLParse(result);         } catch (IOException e) {             e.printStackTrace();         } catch (JDOMException e) {             e.printStackTrace();         }         return map;     }     public JSONObject getPayParam(Map<String, String> map) {         JSONObject payPamams = new JSONObject();         if ((map.containsKey("return_code"))                 && (((String) map.get("return_code")).equals("SUCCESS"))) {             String appid = (String) map.get("appid");             String partnerid = (String) map.get("mch_id");             String prepayid = (String) map.get("prepay_id");             String noncestr = this.payCommonUtil.getRandomString(32);             String timestamp = (System.currentTimeMillis() / 1000L) + "";             SortedMap parameterMap = new TreeMap();             parameterMap.put("appId", appid);                          parameterMap.put("package", "prepay_id=" + prepayid);             //随机字符串             parameterMap.put("nonceStr", noncestr);             parameterMap.put("signType", "MD5");             parameterMap.put("timeStamp", timestamp);             System.out.println("签名准备参数"+parameterMap);

           //二次签名 把下面红色字的信息返给统一下单那块,然后传到页面上

            String sign = this.payCommonUtil.createSign("UTF-8", parameterMap);             payPamams.put("appid", appid);             //商户号             payPamams.put("partnerid", partnerid);             payPamams.put("package", "prepay_id=" + prepayid);             payPamams.put("noncestr", noncestr);             payPamams.put("timestamp", timestamp);             payPamams.put("signtype", "MD5");             //签名             payPamams.put("sign", sign);             System.out.println("生成签名后"+payPamams.getString("sign"));             return payPamams;         }         String return_msg = (String) map.get("return_msg");         payPamams.put("return_msg", return_msg);         return payPamams;     }     public PayCommonUtil getPayCommonUtil() {         return this.payCommonUtil;     }     public void setPayCommonUtil(PayCommonUtil payCommonUtil) {         this.payCommonUtil = payCommonUtil;     }     public String getNorifyUrl() {         return this.norifyUrl;     }     public void setNorifyUrl(String norifyUrl) {         this.norifyUrl = norifyUrl;     }

//支付页面 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/context/mytags.jsp"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="yes" name="apple-mobile-web-app-capable"> <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' /> <title>商品支付</title> <!--2017年6月27日,zq--> <style type="text/css">       body{ margin:0px auto; padding:0px; background:#EBEBEB; font-family:"微软雅黑"; font-size:14px;}     .bodydiv{ max-width: 500px; margin: auto;}     .acty2{width:98%; height:auto; background:#FFF;  margin:auto; margin-top: 10px ;padding:5px 0px;box-shadow: 0px 0px 5px #000000;} .acty2 .diva{width:98%;  height:auto;  margin: auto;} .acty2  .tup{ width: 100%;  background: #FF9900;} .acty2  .diva .p1{ font-size:14px;  line-height:16px;} .acty2  .diva .p2{ font-size:14px;  line-height:14px; padding-left: 10px; color: #FF0000;} .acty2  .diva .p2 .span1{font-size:12px; text-decoration:line-through; line-height:10px; color:#737373; padding-left: 10px;} .acty2  .diva .p2 .span2{font-size:13px; float: right;color:#737373;margin-right: 20px;} a{ text-decoration:none; color: #000000;} p{font-size:14px;} span{font-size:14px;} .clear{ clear:both;} </style>   </head> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript" src="<%=basePath %>/shop/js/mui.min.js"></script> <script type="text/javascript">       function onBridgeReady() {         WeixinJSBridge.invoke('getBrandWCPayRequest', {           "appId" : "${appid}",//"wx2421b1c4370ec43b", //公众号名称,由商户传入             "timeStamp" : "${timestamp}",//"1395712654", //时间戳,自1970年以来的秒数             "nonceStr" : "${noncestr}",//"e61463f8efa94090b1f366cccfbbb444", //随机串             "package" : "${package}",//"prepay_id=u802345jgfjsdfgsdg888",           "signType" : "MD5",//"MD5", //微信签名方式:             "paySign" : "${sign}",//"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名         }, function(res) { // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回  ok,但并不保证它绝对可靠。            /* alert(res.err_msg); */            if (res.err_msg == "get_brand_wcpay_request:ok") {             //支付成功后跳转到支付结果查询修改订单状态             window.location.href ="${cxUrl}&orderid=${orderid}&goodsid=${goodsid}&priceInterval=${priceInterval}&type=${type}&price=${pprice}";             /* request.getRequestDispatcher("${cxUrl}&orderid=${orderid}").forward(request,response); */             /* response.sendRedirect("${cxUrl}&orderid=${orderid}");  window.location.href ="${cxUrl}&orderid=${orderid}" */           }           if (res.err_msg == "get_brand_wcpay_request:cancel") {           }           if (res.err_msg == "get_brand_wcpay_request:fail") {         /* alert(JSON.stringify(res)); */           }         });       }             function callpay() {         if (typeof WeixinJSBridge == "undefined") {           if (document.addEventListener) {             document.addEventListener('WeixinJSBridgeReady', onBridgeReady,                 false);           } else if (document.attachEvent) {             document.attachEvent('WeixinJSBridgeReady', onBridgeReady);             document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);           }         } else {           onBridgeReady();         }       }          mui.init();     var oldback = mui.back;     mui.back = function() {         mui.currentWebview.opener().show('none');         alert("要返回上一页咯");         oldback();     }      </script> <body> <div class="bodydiv">     <div class="acty2">             <div class="diva">                 <div class="tup">                     <img src="${appPictureUrl}${picture}" width="100%" />                 </div>                 <p class="p2">支付金额:¥${pprice}</p>             </div>         <div class="clear"></div>     </div>         <input style="width:100%; background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" value="立即支付" type="button" οnclick="callpay()" >     </div> </body> </html>

转载请注明原文地址: https://www.6miu.com/read-78580.html

最新回复(0)