生成付款二维码
一, 微信网站扫码支付介绍
1, 扫码支付文档
微信开发官方文档:
有关微信支付的流程图微信官方已经说的很清楚了, 这里也无需其它解释. 这边采用微信支付扫码模式二 (不依赖商户平台设置回调 url), 所以在生成二维码之前
要先调用微信统一下单支付接口, 获得 code_url, 再通过谷歌二维码工具将 code_url 生成二维码图片.
2, 名称理解
在微信扫码支付功能开发之前, 首先要获得微信认证而得到的一些信息如下:
开发者账户信息
公众号 appid: wx0pi2m4x6we76140w
公众号 appsecret: x82552d8w0y1i161lp9o7821s5d7osry
商户号 mer_id: 5731202714
支付 key: PL9wT9n9Ljav4zSN66J0bmzT1Yl54429
3, 和微信支付交互方式
(1),post 方式提交
(2),xml 格式的协议
(3), 签名算法 MD5
(4), 接口交易单位为 分
(5), 交易类型: JSAPI-- 公众号支付, NATIVE-- 原生扫码支付, App--App 支付
(6), 商户订单号规则:
商户支付的订单号由商户自定义生成, 仅支持使用字母, 数字, 中划线 -, 下划线_, 竖线 |, 星号 * 这些英文半角字符的组合, 请勿使用汉字或全角等特殊字符,
微信支付要求商户订单号保持唯一性
(7), 安全规范:
签名算法:
校验工具:
(8), 采用微信支付扫码模式二 (不依赖商户平台设置回调 url)
二, 实战开发
1, 点击购买商品调用接口
接口需要接收购买商品 ID, 用户 ID, 返回的就是二维码图片供用户扫码支付.
- /**
- * 订单接口
- */
- @RestController
- @RequestMapping("/API/v1/order")
- public class OrderController {
- @Autowired
- private VideoOrderService videoOrderService;
- /**
- * 用户点击购买下单接口
- */
- @GetMapping("buy")
- public void saveOrder(@RequestParam(value = "video_id",required = true)int videoId,
- HttpServletRequest request,
- HttpServletResponse response) throws Exception {
- /**
- * 实际开发需要获取用户 id 和用户当前 ip, 这里临时写死的配置
- * String ip = IpUtils.getIpAddr(request);
- * int userId = request.getAttribute("user_id");
- */
- int userId = 1;
- String ip = "120.25.1.43";
- //1, 根据用户 id 和商品 id 生成订单
- VideoOrderDto videoOrderDto = new VideoOrderDto();
- videoOrderDto.setUserId(userId);
- videoOrderDto.setVideoId(videoId);
- videoOrderDto.setIp(ip);
- //2, 保存订单同时返回 codeUrl
- String codeUrl = videoOrderService.save(videoOrderDto);
- if(codeUrl == null) {
- throw new NullPointerException();
- }
- //3, 通过 google 工具生成二维码供用户扫码支付
- try{
- //3,1 生成二维码配置
- Map<EncodeHintType,Object> hints = new HashMap<>();
- //3,2 设置纠错等级
- hints.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.L);
- //3,3 编码类型
- hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
- BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl,BarcodeFormat.QR_CODE,400,400,hints);
- OutputStream out = response.getOutputStream();
- MatrixToImageWriter.writeToStream(bitMatrix,"PNG",out);
- }catch (Exception e){
- e.printStackTrace();
- }
- }
- }
2, 进入 VideoOrderService 具体业务实现类
该类的主要业务逻辑是:
(1) 通过商品 ID 查询是否有该商品信息
(2) 通过用户 ID 查询是否存在该用户
(3) 如果上面两步没有问题, 则生成用户订单信息保存到数据库中
- @Override
- @Transactional(propagation = Propagation.REQUIRED)
- public String save(VideoOrderDto videoOrderDto) throws Exception {
- //1, 查找商品信息 (这里商品指的是视频课程)
- Video video = videoMapper.findById(videoOrderDto.getVideoId());
- //2, 查找用户信息
- User user = userMapper.findByid(videoOrderDto.getUserId());
- //3, 生成订单, 插入数据库
- VideoOrder videoOrder = new VideoOrder();
- videoOrder.setTotalFee(video.getPrice());
- videoOrder.setVideoImg(video.getCoverImg());
- videoOrder.setVideoTitle(video.getTitle());
- videoOrder.setCreateTime(new Date());
- videoOrder.setVideoId(video.getId());
- videoOrder.setState(0);
- videoOrder.setUserId(user.getId());
- videoOrder.setHeadImg(user.getHeadImg());
- videoOrder.setNickname(user.getName());
- videoOrder.setDel(0);
- videoOrder.setIp(videoOrderDto.getIp());
- videoOrder.setOutTradeNo(CommonUtils.generateUUID());
- videoOrderMapper.insert(videoOrder);
- //4, 获取 codeurl
- String codeUrl = unifiedOrder(videoOrder);
- return codeUrl;
- }
3, 回调微信统一下单接口, 获取 codeurl 方法主要逻辑
微信官方统一下单接口文档说明:
(1) 根据接口需求添加所需参数: 比如 appid,mch_id,body 等等......
(2)sign 签名获取: 具体获取规则官方已经说明: https://pay.weixin.qq.com/wiki/doc/API/native.PHP?chapter=4_3
(3) 通过工具类将 map 集合转为 xml 格式字符串
(4) 回调微信统一下单接口, 接口地址: https://API.mch.weixin.qq.com/pay/unifiedorder
(5) 如果上一步成功 (成功标志返回 SUSSCUSS), 则将返回成功的 xml 格式再通过工具类转为 map
(6) 通过 key=code_url, 获取 value 字符串, 这也是最终生成二维码的字符串. code_url 格式大致为: weixin://wxpay/s/An4baqw
接下来只要将 code_url 值变成二维码就可以供用户扫码付款了.
4, 测试
调用 http://localhost:8081/API/v1/order/buy?video_id=1 接口
成功返回二维码: code_url 有效期是两个小时
微信扫码之后: 看到具体信息
再看数据库该商品信息:
GitHub 源码
GitHub: https://GitHub.com/yudiandemingzi/wechatpay
我只是偶尔安静下来, 对过去的种种思忖一番. 那些曾经的旧时光里即便有过天真愚钝, 也不值得谴责. 毕竟, 往后的日子, 还很长. 不断鼓励自己,
天一亮, 又是崭新的起点, 又是未知的征程 (上校 16)
来源: https://www.cnblogs.com/qdhxhz/p/9708534.html