• 一、准备页面
    • 1、第一个页面,购票页面
    • 2、第二个页面,详情支付页面
    • 3、第三个页面,支付成功跳转页面
  • 二、准备二维码(测试一下)
  • 三、准备微信参数、环境、HttpClient工具类、雪花算法工具类。
  • 四、开始支付功能编码(下单)
  • 五、开始支付功能编码(查询订单状态)
    • ————————
    • 创作不易,如觉不错,随手点赞,关注,收藏(* ̄︶ ̄),谢谢~~

我们这里只看支付,其他跟支付无关的东西不看

一、准备页面

主要有三个页面

1、第一个页面,购票页面

2、第二个页面,详情支付页面

紫色的三个是跟我们支付有关的

3、第三个页面,支付成功跳转页面

二、准备二维码(测试一下)

1、首先导入一个JS,二维码生成插件 qrious


2、创建一个页面,测试一下,注意一下,这个地址

三、准备微信参数、环境、HttpClient工具类、雪花算法工具类。

1、创建一个weixinpay.properties配置文件,配置微信支付需要的参数,这里的回调地址,我们没有用到。

2、在主XML配置文件加载我们的微信支付配置文件。


3、创建一个微信支付实体类,将我们的数据注入进去。


4、导入微信支付SDK,开发包。


5、导入我们的HttpClient工具类,后面调用微信支付接口会用到。


可能会跟其他的类重名,那就在后面加个Utils


6、加入雪花算法工具类,后面用来生成永远不会重复的订单编号。

四、开始支付功能编码(下单)

1、创建一个WeixinPayService,有两个参数。

2、编写WeixinPayServiceImpl实现类

package com.movie.service.impl;import com.github.wxpay.sdk.WXPayUtil;
import com.movie.service.WeixinPayService;
import com.movie.utils.HttpClientUtils;
import com.movie.vo.WeiXin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.net.www.http.HttpClient;import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** @BelongsProject: MovieSystem* @BelongsPackage: com.movie.service.impl* @Description: TODO*/
@Service
public class WeixinPayServiceImpl implements WeixinPayService {@ResourceWeiXin weiXin;/*** 调用微信接口获取支付的地址** @param out_trade_no 订单号* @param total_fee    金额(分)* @return*/@Overridepublic Map createNative(String out_trade_no, String total_fee) {// 1.创建参数Map<String, String> param = new HashMap();// 创建参数//调用微信支付统一下单的接口,必须转的参数param.put("appid", weiXin.getAppid());// 公众号param.put("mch_id", weiXin.getPartner());// 商户号param.put("nonce_str", WXPayUtil.generateNonceStr());//调用工具类(微信SDK的)。随机字符串param.put("body", "北海市影城电影票");// 商品描述param.put("out_trade_no", out_trade_no);// 商户订单号param.put("total_fee", total_fee);// 总金额(以分为单位)param.put("spbill_create_ip", "127.0.0.1");// IPparam.put("notify_url", "http://test.easyshop.cn");// 回调地址(随便写)param.put("trade_type", "NATIVE");// 交易类型,NATIVE类型表示扫码支持try {// 2.生成要发送的xml(将Map集合转为XML格式),因为微信要的是XML格式String xmlParam = WXPayUtil.generateSignedXml(param, weiXin.getPartnerkey());//使用HttpClient远程调用工具//https://api.mch.weixin.qq.com/pay/unifiedorder  这个是微信支付的接口HttpClientUtils client = new HttpClientUtils("https://api.mch.weixin.qq.com/pay/unifiedorder");client.setHttps(true);client.setXmlParam(xmlParam);client.post();// 3.获得结果// result是服务器返回的结果,是XML格式的String result = client.getContent();//将服务器返回的结果,XML转为MapMap<String, String> resultMap = WXPayUtil.xmlToMap(result);//封装返回值Map<String, String> map = new HashMap<>();map.put("code_url", resultMap.get("code_url"));// 支付地址map.put("total_fee", total_fee);// 总金额map.put("out_trade_no", out_trade_no);// 订单号return map;} catch (Exception e) {e.printStackTrace();return new HashMap<>();}}}

注释都写得很清楚了,就不多做解释了,我们调用这个方法需要给它传递两个参数,一个是订单号、一个是总金额(就是我们微信扫码付款的金额)。最后创建一个Map,把支付地址,总金额,订单号返回。

3、编写BuyTicketController

package com.movie.web;import com.movie.bean.Users;
import com.movie.service.BuyTicketService;
import com.movie.service.TicketService;
import com.movie.service.WeixinPayService;
import com.movie.utils.CommomResult;
import com.movie.utils.IdWorker;
import com.movie.vo.PlayVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;@Controller
public class BuyTicketController {@AutowiredBuyTicketService buyTicketService;@AutowiredWeixinPayService weixinPayService;@AutowiredTicketService ticketService;/*** 跳转支付页面,生成二维码** @param play_id* @param seats* @return*/@RequestMapping(value = "/buy_toPay", method = RequestMethod.POST)public String toPay(Integer play_id, String seats, Model model, HttpSession session) {//要购买的电影的座位号session.setAttribute("seats",seats);//根据电源id查找出电影的详细信息PlayVo vo = buyTicketService.findPlayVoById(play_id);//一张票的价格Double money = vo.getMoney();//以,进行分割,看看买了几张片StringBuffer stringBuffer = new StringBuffer();String[] arrays = seats.split(",");//待支付金额,总金额Double sumMoney = money * arrays.length;//循环遍历,加上排、座for (String s : arrays) {s = s.replace("-", "排") + "座";stringBuffer.append(s + " ");}model.addAttribute("seats", stringBuffer.toString());model.addAttribute("vo", vo);model.addAttribute("sumMoney", sumMoney);//2.生成一个永远不会重复的订单编号IdWorker worker = new IdWorker();long id = worker.nextId();String orderId = id+"";//调用微信接口,获取二维码支付地址Map<String, String> map = weixinPayService.createNative(orderId, "1"); //微信接口支付金额默认是以分为单位//微信要支付的地址,把这个地址生成二维码String code_url = map.get("code_url");model.addAttribute("code_url", code_url);//用户支付的订单号model.addAttribute("orderId", orderId);return "user_film_pay";}
}

注释都写得很清楚了,就不多做解释了,把得到的支付地址跟订单号存放在model,给它返回回去。


4、页面显示二维码

5、测试一下:


OK,没有问题

五、开始支付功能编码(查询订单状态)

我们扫码支付可以了,那么问题来了,我们扫码了之后,页面怎么知道它支付了还是没支付呢?

这就要查询订单的支付状态了,根据订单号查询订单的支付状态,看看它执行成功了还是失败。

1、在service下添加一个查询订单状态的方法

2、同上面一样,实现它

/*** 根据订单号查询订单的支付状态* @param out_trade_no* @return*/@Overridepublic Map queryPayStatus(String out_trade_no) {Map param = new HashMap();param.put("appid", weiXin.getAppid());// 公众账号IDparam.put("mch_id", weiXin.getPartner());// 商户号param.put("out_trade_no", out_trade_no);// ----->订单号param.put("nonce_str", WXPayUtil.generateNonceStr());// 随机字符串//查询订单支付状态接口String url = "https://api.mch.weixin.qq.com/pay/orderquery";try {String xmlParam = WXPayUtil.generateSignedXml(param, weiXin.getPartnerkey());HttpClientUtils client = new HttpClientUtils(url);client.setHttps(true);client.setXmlParam(xmlParam);//发送POS请求client.post();//调用接口返回的结果String result = client.getContent();//把返回的XML文件格式转为MapMap<String, String> map = WXPayUtil.xmlToMap(result);System.out.println("---------------服务器端接口返回的支付结果:-----------------------");if(map!=null){Set<Map.Entry<String, String>> entries = map.entrySet();for (Map.Entry<String, String> entry : entries) {System.out.println(entry.getKey()+"--->"+entry.getValue());}}return map;} catch (Exception e) {e.printStackTrace();return null;}}

传递一个订单号,返回Map结果


3、编写Controller,跟之前的Controller是同一个类

流程是这样的:
       我们传递一个订单号,会调用service去查询订单的状态,会返回一个Map。我们对Map进行判断,如果Map不为空,并且里面的 trade_state 的值为 SUCCESS ,则说明支付成功。
       如果Map为空,则说明支付异常,失败。
       那么还有一个问题,如果用户打开了页面,但是他就是不扫码支付呢?我们的请求只发送一次查询,是不是不合适啊?我们可以给它来一个线程,让它每3秒钟执行一次,来一个循环,时间为5分钟,如果5分钟内没有扫码,则支付超时。

/*** 根据订单号查询订单支付的状态--轮询订单支付状态接口** @param out_trade_no* @return*/@ResponseBody@RequestMapping("/pay_queryPayStatus")public CommomResult queryPayStatus(String out_trade_no,Integer play_id,HttpSession session) {CommomResult commonResult = null;try {//查询支付的订单号是:1320615983324332000System.out.println("查询支付的订单号是:"+out_trade_no);System.out.println("查询支付的订单play_id:"+play_id);String seats=(String)session.getAttribute("seats");// 3-4,5-6,7-8Users loginUser=(Users) session.getAttribute("loginUser");commonResult = null;int x = 0;while (true) {//查询订单支付状态Map map = weixinPayService.queryPayStatus(out_trade_no);if (map != null) {if (map.get("trade_state").equals("SUCCESS")) {// 如果成功//支付成功,把支付成功的数据,存入数据中,后期可以查看订单String[] seatNumers = seats.split(",");for (String seatName : seatNumers) {int seat_id = ticketService.getSeatIdBySeatName(seatName);//插入到订单表 ticket表中ticketService.addTicket(out_trade_no,play_id,loginUser.getUser_id(),seat_id);}commonResult = new CommomResult(200, "支付成功");break;}}if (map == null) {commonResult = new CommomResult(500, "支付出现异常!失败");break;}try {Thread.sleep(3000);//睡眠3秒钟,每3秒钟执行一次} catch (InterruptedException e) {e.printStackTrace();}//为了不让循环无休止地运行,我们定义一个循环变量,如果这个变量超过了这个值则退出循环,设置时间为5分钟x++;if (x >= 60) {commonResult = new CommomResult(502, "支付超时!");break;}}} catch (Exception e) {commonResult = new CommomResult(500, "支付异常!");e.printStackTrace();} finally {}return commonResult;}


4、编写页面

我们什么时候开始调用Controller查询订单状态的方法呢?那当然是在页面一打开,二维码出来就开始调用了


5、启动测试一下:

等到5分钟没有支付,超时

点击确认,页面刷新,扫码支付

支付成功,跳到成功页面

————————

创作不易,如觉不错,随手点赞,关注,收藏(* ̄︶ ̄),谢谢~~

SSM项目————整合微信支付相关推荐

  1. Springboot----项目整合微信支付(引入延迟队列实现订单过期取消以及商户主动查单)

    前言 目前更新的是Springboot项目整合微信支付系列的文章,可以在我的主页中找到该系列其他文章,这一系列的文章将会系统介绍如何在项目中引入微信支付的下单.关单.处理回调通知等功能.由于前面创作经 ...

  2. SpringBoot整合微信支付开发在线教育视频网站(完整版)

    目录 ├─code.zip ├─第 1 章项目介绍和前期准备 │  ├─1-1 SpringBoot整合微信支付开发在线教育视频站点介绍.TS │  ├─1-2 中大型公司里面项目开发流程讲解.TS ...

  3. 关于微店整合微信支付时出现的的各种问题的记录 php版

    由于公司项目的需要,需要在项目里整合微信支付,公司原有的项目中已有老版本的支付功能,在此不作讨论.我需要作的就是加入新版本的支付功能 让项目里可以支持新老两种版本的功能.在微信官方下载到了新版支付的p ...

  4. 项目整合微信扫码登录功能

    项目整合微信登录功能 一.准备工作 https://open.weixin.qq.com 1.注册 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5 ...

  5. 微信支付php详解 php,ThinkPHP框架整合微信支付之刷卡模式图文详解

    本文实例讲述了ThinkPHP框架整合微信支付之刷卡模式.分享给大家供大家参考,具体如下: 大家好,这篇文章是继微信支付之Native 扫码支付 模式二之后的微信支付系列教程第四篇:微信刷卡支付 本教 ...

  6. Thinkphp3.2整合微信支付

    2019独角兽企业重金招聘Python工程师标准>>> [2016/08/04]本篇文章內容沒有在維護了,一年前寫下來的不知道微信的接口有沒有改變,想要實際應用的可以看下白俊遥 朋友 ...

  7. 微信服务号开发-整合微信支付

    最近的项目在对接微信支付,所以抽出一些时间,将方法总结一下: 欢迎加群交流:724225958 官方开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi. ...

  8. SSM项目整合Quartz

    一.背景 SSM项目中要用到定时器,初期使用Timer,后来用spring 的schedule,都比较简单,所以功能比较单一而且他们不能动态的配置时间.后来就研究quartz,准备整合到项目中.Qua ...

  9. springboot整合微信支付

    讲解微信支付V3接口真实开发代码,非demo 使用微信支付需要开通微信支付商户号:微信支付 - 中国领先的第三方支付平台 | 微信支付提供安全快捷的支付方式 微信支付提供多种支付功能,包括[JSAPI ...

最新文章

  1. 揭密 extern C
  2. HTML特殊编码转换
  3. 关于OpenCV的Mat画图问题
  4. zabbix_server
  5. word 文字超出表格边框怎么办
  6. ios识别人脸自动拍照_iOS 相机流人脸识别(一)-人脸框检测(基于iOS原生)
  7. 内网渗透思路学习——靶场实战——暗月项目七
  8. 测试nb信号的软件_NB-IOT测试仪NB测试仪无线网络信号质量检测网络信号故障定位...
  9. Excel小技巧之:如何在表格内插入水印
  10. 【PS专题】PS钢笔压力有感叹号怎么消除
  11. Python为什么这么多人说好?
  12. 微信跳一跳游戏外挂(mac电脑+android手机)
  13. 巴黎出差及场测攻略V1.3
  14. IE浏览器弹出另存为文件(可以自主选择存储路径)对话框
  15. 将 Cpar 文件导入 2019 版的 Carsim 后,无法打开 video+plot 是什么问题?
  16. Caliburn.Micro 杰的入门教程3,事件和参数
  17. 考研学校的爬虫(自己写的可能会有点菜
  18. 小红书用户画像分析_用户画像分析会成为第一品牌竞争力吗?
  19. 2022氟化工艺考试试题及答案
  20. 2021威海高考成绩查询电话,2021威海高考成绩查询系统

热门文章

  1. Python爬取斗鱼直播网站信息
  2. jvm虚拟机规范 紧接上文的
  3. 熬夜爆肝整理 400 页 《Python 修炼之道》,一本高分原创高清电子书送给你!
  4. opencv学习-碰壁小球
  5. 面试积累-Redis-Redis主要消耗什么物理资源?
  6. 华为宣布鸿蒙升级,华为宣布鸿蒙系统升级至2.0版本 明年华为手机全面支持
  7. 网络分析流量FIN_WAIT_2状态解释
  8. fsl左右海马体分割+freesurfer合并
  9. JVM-Java高墙之内存模型
  10. Cisco Firepower 9300 Series FTD Software 7.2.0 ASA Software 9.18.1