(先补充一下,app唤醒微信支付失败的话,在确保没错的情况下,建议换一个手机或者重新下载微信,不知道是微信缓存还是什么原因)
1、先申请好开发环境
app支付不需要公众号,所以申请好开发商号和开发平台的app应用即可,获取到如下图的几个
还有就是在申请应用的时候记得设置正确的应用包名和应用签名。
2、可以查看微信开发文档(https://pay.weixin.qq.com/)。
controller层
/** * @description: 微信支付开始下单 * @date: 2021/6/7 */ @GetMapping("/createOrder") public JsonData createOrder(@RequestParam(value = "videoId", required = true) int videoId, @RequestParam(value = "userId", required = true) int userId, HttpServletRequest request, HttpServletResponse response) throws Exception { Map<String, String> map = videoOrderService.wxSave(videoId, userId,request); // if (codeUrl == null) { // throw new NullPointerException(); // } return JsonData.buildSuccess(map,"微信支付获取codeUrl")}
serviceImpl层
需要先引入pom文件
<dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency>
/** * 微信生成订单 * * @param videoId * @param userId */ @Override public Map<String, String> wxSave(int videoId, int userId,HttpServletRequest request) throws Exception { Video video = videoMapper.selectById(videoId); //AppUser appUser = appUserMapper.selectById(userId); //生成订单 VideoOrder videoOrder = new VideoOrder(); videoOrder.setVideoId(video.getId()); videoOrder.setOutTradeNo(CommonUtils.generateUUID());
//未支付的状态 videoOrder.setState(0); videoOrder.setCreateTime(new Date()); videoOrder.setTotalFee(video.getPrice()); videoOrder.setVideoId(video.getId()); videoOrder.setVideoTitle(video.getTitle()); videoOrder.setVideoImg(video.getCoverImg()); videoOrder.setUserId(userId);
//先生成订单信息,支付状态设置为未支付 Map<String, String> codeUrl = unifiedOrder(videoOrder,request); return codeUrl; }
private Map<String, String> unifiedOrder(VideoOrder videoOrder,HttpServletRequest request) throws Exception { //生成未支付订单 int insert = videoOrderMapper.insert(videoOrder); //这些字段都可以在开发文档上找到,尽量直接复制,以免打错 SortedMap<String,String> params = new TreeMap<>(); params.put("appid",weChatConfig.getAppid()); params.put("mch_id",weChatConfig.getMchId()); params.put("nonce_str",CommonUtils.generateUUID()); params.put("body",videoOrder.getVideoTitle()); params.put("out_trade_no",videoOrder.getOutTradeNo()); params.put("total_fee",String.valueOf(1)); params.put("spbill_create_ip",getRealIp(request)); params.put("notify_url",weChatConfig.getNotifyUrl()); params.put("trade_type","APP"); //生成签名/这里也可以用微信支付的自带的工具类,WXPayUtil.generateSignedXml(params,weChatConfig.getKey()); String sign = WxPayUtil.createSign(params,weChatConfig.getKey()); params.put("sign",sign); String payXml = WxPayUtil.mapToXml(params); System.out.println(payXml); //统一下单 String orderStr = HttpUtils.doPost(weChatConfig.getUnifiedOrderUrl(),payXml,4000); if(null == orderStr) { return null; } Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr); System.out.println(unifiedOrderMap.toString()); //unifiedOrderMap.put("timestamp",String.valueOf(System.currentTimeMillis()/1000)); Long timeStamp = System.currentTimeMillis() / 1000; SortedMap<String, String> ps = new TreeMap(); ps.put("appid", unifiedOrderMap.get("appid")); ps.put("partnerid", weChatConfig.getMchId()); ps.put("noncestr", unifiedOrderMap.get("nonce_str")); ps.put("package","Sign=WXPay"); ps.put("prepayid",unifiedOrderMap.get("prepay_id")); ps.put("timestamp", String.valueOf(timeStamp)); //二次签名 String sign2 = WxPayUtil.createSign(ps,weChatConfig.getKey()); ps.put("sign",sign2); String s = WxPayUtil.mapToXml(ps); System.out.println(s); System.out.println(ps.toString()); return ps; }
统一下单封装方法
/** * 封装post * @return */ public static String doPost(String url, String data,int timeout){ CloseableHttpClient httpClient = HttpClients.createDefault(); //超时设置 RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout) //连接超时 .setConnectionRequestTimeout(timeout)//请求超时 .setSocketTimeout(timeout) .setRedirectsEnabled(true) //允许自动重定向 .build(); HttpPost httpPost = new HttpPost(url); httpPost.setConfig(requestConfig); httpPost.addHeader("Content-Type","text/html; chartset=UTF-8"); if(data != null && data instanceof String){ //使用字符串传参 StringEntity stringEntity = new StringEntity(data,"UTF-8"); httpPost.setEntity(stringEntity); } try{ CloseableHttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); if(httpResponse.getStatusLine().getStatusCode() == 200){ String result = EntityUtils.toString(httpEntity); return result; } }catch (Exception e){ e.printStackTrace(); }finally { try{ httpClient.close(); }catch (Exception e){ e.printStackTrace(); } } return null; }