• 微信支付业务代码流程


    目录

    1.流程图

    2.引入依赖:

    3.创建一个Httpclient的工具类-默认浏览器进行远程调用

    4.使用mybatis-plus生成类,接口等

    5.后端

    6.前端


    1.流程图

     微信接口:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1icon-default.png?t=M666https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

    2.引入依赖:

    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    3. <modelVersion>4.0.0modelVersion>
    4. <parent>
    5. <groupId>org.springframework.bootgroupId>
    6. <artifactId>spring-boot-starter-parentartifactId>
    7. <version>2.7.2version>
    8. <relativePath/>
    9. parent>
    10. <groupId>com.wzhgroupId>
    11. <artifactId>maven-jenkinsartifactId>
    12. <version>0.0.1-SNAPSHOTversion>
    13. <name>maven-jenkinsname>
    14. <description>Demo project for Spring Bootdescription>
    15. <properties>
    16. <java.version>1.8java.version>
    17. properties>
    18. <dependencies>
    19. <dependency>
    20. <groupId>org.springframework.bootgroupId>
    21. <artifactId>spring-boot-starterartifactId>
    22. dependency>
    23. <dependency>
    24. <groupId>org.projectlombokgroupId>
    25. <artifactId>lombokartifactId>
    26. <optional>trueoptional>
    27. dependency>
    28. <dependency>
    29. <groupId>org.springframework.bootgroupId>
    30. <artifactId>spring-boot-starter-testartifactId>
    31. <scope>testscope>
    32. dependency>
    33. <dependency>
    34. <groupId>org.springframework.bootgroupId>
    35. <artifactId>spring-boot-starter-webartifactId>
    36. dependency>
    37. <dependency>
    38. <groupId>com.github.wxpaygroupId>
    39. <artifactId>wxpay-sdkartifactId>
    40. <version>0.0.3version>
    41. dependency>
    42. <dependency>
    43. <groupId>org.apache.httpcomponentsgroupId>
    44. <artifactId>httpclientartifactId>
    45. <version>4.5.3version>
    46. dependency>
    47. <dependency>
    48. <groupId>com.baomidougroupId>
    49. <artifactId>mybatis-plus-boot-starterartifactId>
    50. <version>3.5.2version>
    51. dependency>
    52. <dependency>
    53. <groupId>com.alibabagroupId>
    54. <artifactId>druid-spring-boot-starterartifactId>
    55. <version>1.2.8version>
    56. dependency>
    57. <dependency>
    58. <groupId>mysqlgroupId>
    59. <artifactId>mysql-connector-javaartifactId>
    60. <scope>runtimescope>
    61. dependency>
    62. <dependency>
    63. <groupId>com.baomidougroupId>
    64. <artifactId>mybatis-plus-generatorartifactId>
    65. <version>3.5.2version>
    66. dependency>
    67. <dependency>
    68. <groupId>org.freemarkergroupId>
    69. <artifactId>freemarkerartifactId>
    70. <version>2.3.31version>
    71. dependency>
    72. <dependency>
    73. <groupId>com.spring4allgroupId>
    74. <artifactId>swagger-spring-boot-starterartifactId>
    75. <version>1.9.1.RELEASEversion>
    76. dependency>
    77. <dependency>
    78. <groupId>com.github.xiaoymingroupId>
    79. <artifactId>swagger-bootstrap-uiartifactId>
    80. <version>1.9.6version>
    81. dependency>
    82. <dependency>
    83. <groupId>com.fasterxml.jackson.datatypegroupId>
    84. <artifactId>jackson-datatype-jsr310artifactId>
    85. dependency>
    86. dependencies>
    87. <build>
    88. <plugins>
    89. <plugin>
    90. <groupId>org.springframework.bootgroupId>
    91. <artifactId>spring-boot-maven-pluginartifactId>
    92. <configuration>
    93. <excludes>
    94. <exclude>
    95. <groupId>org.projectlombokgroupId>
    96. <artifactId>lombokartifactId>
    97. exclude>
    98. excludes>
    99. configuration>
    100. plugin>
    101. plugins>
    102. build>
    103. project>

    3.创建一个Httpclient的工具类-默认浏览器进行远程调用

    1. package com.wzh.util;
    2. import org.apache.http.Consts;
    3. import org.apache.http.HttpEntity;
    4. import org.apache.http.NameValuePair;
    5. import org.apache.http.client.ClientProtocolException;
    6. import org.apache.http.client.entity.UrlEncodedFormEntity;
    7. import org.apache.http.client.methods.*;
    8. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    9. import org.apache.http.conn.ssl.SSLContextBuilder;
    10. import org.apache.http.conn.ssl.TrustStrategy;
    11. import org.apache.http.entity.StringEntity;
    12. import org.apache.http.impl.client.CloseableHttpClient;
    13. import org.apache.http.impl.client.HttpClients;
    14. import org.apache.http.message.BasicNameValuePair;
    15. import org.apache.http.util.EntityUtils;
    16. import javax.net.ssl.SSLContext;
    17. import java.io.IOException;
    18. import java.security.cert.CertificateException;
    19. import java.security.cert.X509Certificate;
    20. import java.text.ParseException;
    21. import java.util.HashMap;
    22. import java.util.LinkedList;
    23. import java.util.List;
    24. import java.util.Map;
    25. /**
    26. * http请求客户端
    27. *
    28. * @author 必须引入httpclient的依赖:在java端模拟浏览器的效果。
    29. *
    30. */
    31. public class HttpClient {
    32. private String url;
    33. private Map param;
    34. private int statusCode;
    35. private String content;
    36. private String xmlParam;
    37. private boolean isHttps;
    38. public boolean isHttps() {
    39. return isHttps;
    40. }
    41. public void setHttps(boolean isHttps) {
    42. this.isHttps = isHttps;
    43. }
    44. public String getXmlParam() {
    45. return xmlParam;
    46. }
    47. public void setXmlParam(String xmlParam) {
    48. this.xmlParam = xmlParam;
    49. }
    50. public HttpClient(String url, Map param) {
    51. this.url = url;
    52. this.param = param;
    53. }
    54. public HttpClient(String url) {
    55. this.url = url;
    56. }
    57. public void setParameter(Map map) {
    58. param = map;
    59. }
    60. public void addParameter(String key, String value) {
    61. if (param == null)
    62. param = new HashMap();
    63. param.put(key, value);
    64. }
    65. public void post() throws ClientProtocolException, IOException {
    66. HttpPost http = new HttpPost(url);
    67. setEntity(http);
    68. execute(http);
    69. }
    70. public void put() throws ClientProtocolException, IOException {
    71. HttpPut http = new HttpPut(url);
    72. setEntity(http);
    73. execute(http);
    74. }
    75. public void get() throws ClientProtocolException, IOException {
    76. if (param != null) {
    77. StringBuilder url = new StringBuilder(this.url);
    78. boolean isFirst = true;
    79. for (String key : param.keySet()) {
    80. if (isFirst)
    81. url.append("?");
    82. else
    83. url.append("&");
    84. url.append(key).append("=").append(param.get(key));
    85. }
    86. this.url = url.toString();
    87. }
    88. HttpGet http = new HttpGet(url);
    89. execute(http);
    90. }
    91. /**
    92. * set http post,put param
    93. */
    94. private void setEntity(HttpEntityEnclosingRequestBase http) {
    95. if (param != null) {
    96. List nvps = new LinkedList();
    97. for (String key : param.keySet())
    98. nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
    99. http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
    100. }
    101. if (xmlParam != null) {
    102. http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
    103. }
    104. }
    105. private void execute(HttpUriRequest http) throws ClientProtocolException,
    106. IOException {
    107. CloseableHttpClient httpClient = null;
    108. try {
    109. if (isHttps) {
    110. SSLContext sslContext = new SSLContextBuilder()
    111. .loadTrustMaterial(null, new TrustStrategy() {
    112. // 信任所有
    113. public boolean isTrusted(X509Certificate[] chain,
    114. String authType)
    115. throws CertificateException {
    116. return true;
    117. }
    118. }).build();
    119. SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
    120. sslContext);
    121. httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
    122. .build();
    123. } else {
    124. httpClient = HttpClients.createDefault();
    125. }
    126. CloseableHttpResponse response = httpClient.execute(http);
    127. try {
    128. if (response != null) {
    129. if (response.getStatusLine() != null)
    130. statusCode = response.getStatusLine().getStatusCode();
    131. HttpEntity entity = response.getEntity();
    132. // 响应内容
    133. content = EntityUtils.toString(entity, Consts.UTF_8);
    134. }
    135. } finally {
    136. response.close();
    137. }
    138. } catch (Exception e) {
    139. e.printStackTrace();
    140. } finally {
    141. httpClient.close();
    142. }
    143. }
    144. public int getStatusCode() {
    145. return statusCode;
    146. }
    147. public String getContent() throws ParseException, IOException {
    148. return content;
    149. }
    150. }

    4.使用mybatis-plus生成类,接口等

    1. package com.wzh;
    2. import com.baomidou.mybatisplus.generator.FastAutoGenerator;
    3. import com.baomidou.mybatisplus.generator.config.OutputFile;
    4. import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
    5. import java.util.Collections;
    6. /**
    7. * @ProjectName: springboot-vue0809
    8. * @Package: com.wzh
    9. * @ClassName: Generator
    10. * @Author: 王振华
    11. * @Description:
    12. * @Date: 2022/8/9 17:21
    13. * @Version: 1.0
    14. */
    15. public class Generator {
    16. public static void main(String[] args) {
    17. FastAutoGenerator.create("jdbc:mysql://localhost:3306/weixin?serverTimezone=Asia/Shanghai", "root", "123456")
    18. .globalConfig(builder -> {
    19. builder.author("王振华") // 设置作者
    20. .enableSwagger() // 开启 swagger 模式
    21. .fileOverride() // 覆盖已生成文件
    22. .outputDir(".\\src\\main\\java\\"); // 指定输出目录
    23. })
    24. .packageConfig(builder -> {
    25. builder.parent("com.wzh") // 设置父包名
    26. //.moduleName("") // 设置父包模块名
    27. .pathInfo(Collections.singletonMap(OutputFile.xml, "src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径
    28. })
    29. .strategyConfig(builder -> {
    30. builder.addInclude( "t_order","t_pay_log")// 设置需要生成的表名
    31. .addTablePrefix("t_"); // 设置过滤表前缀
    32. })
    33. .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
    34. .execute();
    35. }
    36. }

    5.后端

    config配置类:

    解决跨域:

    1. package com.wzh.config;
    2. import org.springframework.context.annotation.Bean;
    3. import org.springframework.context.annotation.Configuration;
    4. import org.springframework.web.cors.CorsConfiguration;
    5. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    6. import org.springframework.web.filter.CorsFilter;
    7. @Configuration
    8. public class CorsConfig {
    9. // 当前跨域请求最大有效时长。这里默认1天
    10. private static final long MAX_AGE = 24 * 60 * 60;
    11. @Bean
    12. public CorsFilter corsFilter() {
    13. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    14. CorsConfiguration corsConfiguration = new CorsConfiguration();
    15. corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
    16. corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
    17. corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
    18. corsConfiguration.setMaxAge(MAX_AGE);
    19. source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
    20. return new CorsFilter(source);
    21. }
    22. }

    mybatis-plus添加修改自动生成:

    1. package com.wzh.config;
    2. import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    3. import io.swagger.models.auth.In;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.apache.ibatis.reflection.MetaObject;
    6. import org.springframework.stereotype.Component;
    7. import java.time.LocalDateTime;
    8. /**
    9. * @ProjectName: springboot-vue0809
    10. * @Package: com.wzh.system.config
    11. * @ClassName: MyMetaObjectHandler
    12. * @Author: 王振华
    13. * @Description:
    14. * @Date: 2022/8/10 15:43
    15. * @Version: 1.0
    16. */
    17. @Slf4j
    18. @Component
    19. public class MyMetaObjectHandler implements MetaObjectHandler {
    20. //当添加时自动填充的值
    21. @Override
    22. public void insertFill(MetaObject metaObject) {
    23. log.info("start insert fill ....");
    24. //this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
    25. // 切记这里是表的列名 不是实体类的属性名
    26. this.strictInsertFill(metaObject, "gmtCreate", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
    27. this.strictInsertFill(metaObject, "gmtModified", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
    28. this.strictInsertFill(metaObject, "payTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
    29. this.strictInsertFill(metaObject, "isDeleted", () -> 0, Integer.class);
    30. // 或者
    31. //this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    32. }
    33. //当修改时自动填充的值
    34. @Override
    35. public void updateFill(MetaObject metaObject) {
    36. log.info("start update fill ....");
    37. //this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
    38. // 或者
    39. this.strictUpdateFill(metaObject, "gmtModified", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
    40. this.strictUpdateFill(metaObject, "status", () -> 1, Integer.class); // 起始版本 3.3.3(推荐)
    41. // 或者
    42. //this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    43. }
    44. }

    application配置文件

    1. server.port=8081
    2. spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
    3. spring.datasource.druid.url=jdbc:mysql://localhost:3306/weixin?serverTimezone=Asia/Shanghai&characterEncoding=utf8
    4. spring.datasource.druid.username=root
    5. spring.datasource.druid.password=123456
    6. logging.level.com.wzh.weixinpay.dao=debug
    7. # 微信的appid 商家id 密钥---申请你无法申请 因为需要营业执照
    8. weixin.appid=wx8011d27c
    9. weixin.mch_id=153611
    10. weixin.api_key=Cc158380615838062

    controller控制层:

    1. package com.wzh.controller;
    2. import com.wzh.service.IOrderService;
    3. import com.wzh.vo.CommonResult;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.web.bind.annotation.PathVariable;
    6. import org.springframework.web.bind.annotation.PostMapping;
    7. import org.springframework.web.bind.annotation.RequestMapping;
    8. import org.springframework.web.bind.annotation.RestController;
    9. import javax.annotation.Resource;
    10. /**
    11. * @ProjectName: maven-jenkins
    12. * @Package: com.wzh.controller
    13. * @ClassName: OrderController
    14. * @Author: 王振华
    15. * @Description:
    16. * @Date: 2022/8/12 22:21
    17. * @Version: 1.0
    18. */
    19. @RestController
    20. @RequestMapping("order")
    21. public class OrderController {
    22. @Autowired
    23. private IOrderService orderService;
    24. /**
    25. * 创建订单,生成二维码
    26. * @param orderNo
    27. * @return
    28. */
    29. @PostMapping("createNavite/{orderNo}")
    30. public CommonResult createNative(@PathVariable String orderNo){
    31. return orderService.createNavite(orderNo);
    32. }
    33. /**
    34. * 查询订单状态
    35. * @param orderNo
    36. * @return
    37. */
    38. @PostMapping("queryPayStatus/{orderNo}")
    39. public CommonResult queryPayStatus(@PathVariable String orderNo){
    40. return orderService.queryPayStatus(orderNo);
    41. }
    42. }

    service:

    1. package com.wzh.service;
    2. import com.wzh.entity.Order;
    3. import com.baomidou.mybatisplus.extension.service.IService;
    4. import com.wzh.vo.CommonResult;
    5. /**
    6. *

    7. * 订单 服务类
    8. *

    9. *
    10. * @author 王振华
    11. * @since 2022-08-12
    12. */
    13. public interface IOrderService extends IService {
    14. CommonResult createNavite(String orderNo);
    15. CommonResult queryPayStatus(String orderNo);
    16. }

     实现类:

    1. package com.wzh.service.impl;
    2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    3. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    4. import com.github.wxpay.sdk.WXPay;
    5. import com.github.wxpay.sdk.WXPayUtil;
    6. import com.sun.media.jfxmedia.logging.Logger;
    7. import com.wzh.entity.Order;
    8. import com.wzh.entity.PayLog;
    9. import com.wzh.mapper.OrderMapper;
    10. import com.wzh.mapper.PayLogMapper;
    11. import com.wzh.service.IOrderService;
    12. import com.wzh.service.IPayLogService;
    13. import com.wzh.util.HttpClient;
    14. import com.wzh.vo.CommonResult;
    15. import org.springframework.beans.factory.annotation.Autowired;
    16. import org.springframework.beans.factory.annotation.Value;
    17. import org.springframework.stereotype.Service;
    18. import javax.annotation.Resource;
    19. import java.math.BigDecimal;
    20. import java.text.SimpleDateFormat;
    21. import java.time.LocalDateTime;
    22. import java.util.Date;
    23. import java.util.HashMap;
    24. import java.util.Map;
    25. /**
    26. * @ProjectName: maven-jenkins
    27. * @Package: com.wzh.service.impl
    28. * @ClassName: OrderServiceImpl
    29. * @Author: 王振华
    30. * @Description:
    31. * @Date: 2022/8/12 22:28
    32. * @Version: 1.0
    33. */
    34. @Service
    35. public class OrderServiceImpl extends ServiceImpl implements IOrderService {
    36. @Autowired
    37. private OrderMapper orderMapper;
    38. @Resource
    39. private PayLogMapper payLogMapper;
    40. @Value("${weixin.appid}")
    41. private String appId;
    42. @Value("${weixin.mch_id}")
    43. private String mchId;
    44. @Value("${weixin.api_key}")
    45. private String apiKey;
    46. public CommonResult createNavite(String orderNo) {
    47. //1.根据订单号查询出订单信息
    48. QueryWrapper wrapper = new QueryWrapper<>();
    49. wrapper.eq("order_no", orderNo);
    50. wrapper.eq("status", 0);
    51. Order order = orderMapper.selectOne(wrapper);
    52. if (order != null) {
    53. try {
    54. //设置请求的参数----格式为xml格式
    55. Map params = new HashMap<>();//请求参数
    56. params.put("appid", appId);
    57. params.put("mch_id", mchId);
    58. params.put("nonce_str", WXPayUtil.generateNonceStr());
    59. params.put("body", order.getCourseTitle());
    60. params.put("out_trade_no", orderNo);
    61. //0.01未来换成真实的金额
    62. params.put("total_fee", new BigDecimal(0.01).multiply(new BigDecimal(100)).longValue() + "");
    63. params.put("spbill_create_ip", "127.0.0.1");//未来写成项目部署的ip
    64. params.put("notify_url", "http://localhost:8081/pay/back");
    65. params.put("trade_type", "NATIVE");
    66. //创建HttpClient对象 作用远程调用
    67. HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
    68. //支持https协议
    69. client.setHttps(true);
    70. //设置请求的参数
    71. client.setXmlParam(WXPayUtil.generateSignedXml(params, apiKey));
    72. //发送请求
    73. client.post();
    74. //获取请求的响应结果
    75. String content = client.getContent();
    76. System.out.println(content);
    77. Map map = WXPayUtil.xmlToMap(content);
    78. if (map.get("result_code").equals("SUCCESS")) {
    79. Map result = new HashMap<>();
    80. result.put("codeUrl", map.get("code_url"));
    81. result.put("price", order.getTotalFee());
    82. result.put("orderNo", orderNo);
    83. return new CommonResult(2000, "生成二维码成功", result);
    84. }
    85. } catch (Exception e) {
    86. }
    87. }
    88. return new CommonResult(5000, "订单失效", null);
    89. }
    90. @Override
    91. public CommonResult queryPayStatus(String orderNo) {
    92. try {
    93. //1.根据订单状态查询微信的支付情况
    94. HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
    95. Map params = new HashMap<>();
    96. params.put("appid", appId);
    97. params.put("mch_id", mchId);
    98. params.put("out_trade_no", orderNo);
    99. params.put("nonce_str", WXPayUtil.generateNonceStr());
    100. //支持https协议
    101. client.setHttps(true);
    102. //设置请求的参数
    103. client.setXmlParam(WXPayUtil.generateSignedXml(params, apiKey));
    104. //发送请求
    105. client.post();
    106. //获取请求的响应结果
    107. String content = client.getContent();
    108. //System.out.println(content);
    109. Map map = WXPayUtil.xmlToMap(content);
    110. if(map.get("trade_state").equals("SUCCESS")){
    111. //修改订单状态
    112. Order order = new Order();
    113. //order.setStatus(1);
    114. //order.setGmtModified(LocalDateTime.now());
    115. QueryWrapper wrapper = new QueryWrapper<>();
    116. wrapper.eq("order_no",orderNo);
    117. wrapper.eq("status",0);
    118. int update = orderMapper.update(order, wrapper);
    119. //TODO 往支付记录表中添加支付记录
    120. QueryWrapper wrapper1 = new QueryWrapper<>();
    121. wrapper1.eq("order_no",orderNo);
    122. wrapper1.eq("status",1);
    123. Order order1 = orderMapper.selectOne(wrapper1);
    124. if(order1!=null){
    125. PayLog payLog = new PayLog(null,orderNo,null,order1.getTotalFee(),map.get("transaction_id"),map.get("trade_state"),0,map.get("attach"),null,null,null);
    126. int insert = payLogMapper.insert(payLog);
    127. }
    128. return new CommonResult(2000,"支付成功",null);
    129. }else if(map.get("trade_state").equals("NOTPAY")){
    130. return new CommonResult(3000,"订单未支付",null);
    131. }
    132. }catch (Exception e){
    133. e.printStackTrace();
    134. }
    135. return new CommonResult(5000,"支付失败",null);
    136. }
    137. }

    mapper:

    1. package com.wzh.mapper;
    2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    3. import com.wzh.entity.Order;
    4. public interface OrderMapper extends BaseMapper {
    5. }

    entity:

    1. package com.wzh.entity;
    2. import com.baomidou.mybatisplus.annotation.*;
    3. import java.io.Serializable;
    4. import java.math.BigDecimal;
    5. import java.time.LocalDateTime;
    6. import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
    7. import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    8. import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
    9. import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
    10. import io.swagger.annotations.ApiModel;
    11. import io.swagger.annotations.ApiModelProperty;
    12. import io.swagger.models.auth.In;
    13. import lombok.AllArgsConstructor;
    14. import lombok.Data;
    15. import lombok.NoArgsConstructor;
    16. /**
    17. *

    18. * 订单
    19. *

    20. *
    21. * @author 王振华
    22. * @since 2022-08-12
    23. */
    24. @Data
    25. @NoArgsConstructor
    26. @AllArgsConstructor
    27. @TableName("t_order")
    28. @ApiModel(value = "Order对象", description = "订单")
    29. public class Order implements Serializable {
    30. private static final long serialVersionUID = 1L;
    31. @TableId(type = IdType.ASSIGN_ID)
    32. private String id;
    33. @ApiModelProperty("订单号")
    34. private String orderNo;
    35. @ApiModelProperty("课程id")
    36. private String courseId;
    37. @ApiModelProperty("课程名称")
    38. private String courseTitle;
    39. @ApiModelProperty("课程封面")
    40. private String courseCover;
    41. @ApiModelProperty("讲师名称")
    42. private String teacherName;
    43. @ApiModelProperty("会员id")
    44. private String memberId;
    45. @ApiModelProperty("会员昵称")
    46. private String nickname;
    47. @ApiModelProperty("会员手机")
    48. private String mobile;
    49. @ApiModelProperty("订单金额(分)")
    50. private Double totalFee;
    51. @ApiModelProperty("支付类型(0:微信 1:支付宝)")
    52. private Integer payType;
    53. @ApiModelProperty("订单状态(0:未支付 1:已支付)")
    54. @TableField(fill = FieldFill.UPDATE,value = "status")
    55. private Integer status;
    56. @ApiModelProperty("逻辑删除 1(true)已删除, 0(false)未删除")
    57. @TableLogic
    58. private Integer isDeleted;
    59. @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    60. @JsonSerialize(using = LocalDateTimeSerializer.class)
    61. @ApiModelProperty("创建时间")
    62. private LocalDateTime gmtCreate;
    63. @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    64. @JsonSerialize(using = LocalDateTimeSerializer.class)
    65. @TableField(fill = FieldFill.UPDATE,value = "gmt_modified")
    66. @ApiModelProperty("更新时间")
    67. private LocalDateTime gmtModified;
    68. }
    1. package com.wzh.entity;
    2. import com.baomidou.mybatisplus.annotation.*;
    3. import java.io.Serializable;
    4. import java.math.BigDecimal;
    5. import java.time.LocalDateTime;
    6. import io.swagger.annotations.ApiModel;
    7. import io.swagger.annotations.ApiModelProperty;
    8. import lombok.AllArgsConstructor;
    9. import lombok.Data;
    10. import lombok.NoArgsConstructor;
    11. /**
    12. *

    13. * 支付日志表
    14. *

    15. *
    16. * @author 王振华
    17. * @since 2022-08-12
    18. */
    19. @Data
    20. @NoArgsConstructor
    21. @AllArgsConstructor
    22. @TableName("t_pay_log")
    23. @ApiModel(value = "PayLog对象", description = "支付日志表")
    24. public class PayLog implements Serializable {
    25. private static final long serialVersionUID = 1L;
    26. @TableId(type = IdType.ASSIGN_ID)
    27. private String id;
    28. @ApiModelProperty("订单号")
    29. private String orderNo;
    30. @TableField(fill = FieldFill.INSERT,value = "pay_time")
    31. @ApiModelProperty("支付完成时间")
    32. private LocalDateTime payTime;
    33. @ApiModelProperty("支付金额(分)")
    34. private Double totalFee;
    35. @ApiModelProperty("交易流水号")
    36. private String transactionId;
    37. @ApiModelProperty("交易状态")
    38. private String tradeState;
    39. @ApiModelProperty("支付类型(0:微信 1:支付宝)")
    40. private Integer payType;
    41. @ApiModelProperty("其他属性")
    42. private String attr;
    43. @TableLogic
    44. @TableField(fill = FieldFill.INSERT,value = "is_deleted")
    45. @ApiModelProperty("逻辑删除 1(true)已删除, 0(false)未删除")
    46. private Integer isDeleted;
    47. @TableField(fill = FieldFill.INSERT,value = "gmt_create")
    48. @ApiModelProperty("创建时间")
    49. private LocalDateTime gmtCreate;
    50. @TableField(fill = FieldFill.INSERT_UPDATE,value = "gmt_modified")
    51. @ApiModelProperty("更新时间")
    52. private LocalDateTime gmtModified;
    53. }

    vo:

    1. package com.wzh.vo;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. /**
    6. * @ProjectName: maven-jenkins
    7. * @Package: com.wzh.vo
    8. * @ClassName: CommonResult
    9. * @Author: 王振华
    10. * @Description:
    11. * @Date: 2022/8/12 22:23
    12. * @Version: 1.0
    13. */
    14. @Data
    15. @NoArgsConstructor
    16. @AllArgsConstructor
    17. public class CommonResult {
    18. private Integer code;
    19. private String msg;
    20. private Object result;
    21. }

    6.前端

    先在cmd 命令窗口创建vue工程,并引入element-ui插件和axios依赖, 参考Vue高级篇—实现前后端分离_挂在树上的猴子的博客-CSDN博客

     

    1. <template>
    2. <div id="app">
    3. <el-button type="primary" @click="pay">支付el-button>
    4. <el-dialog
    5. title="收银台"
    6. :visible.sync="dialogVisible"
    7. width="30%"
    8. >
    9. <div style="text-align: center">
    10. <p>微信支付 {{payResult.price}} 元p>
    11. <div style="border: 1px solid red;width: 220px;padding: 10px;margin: 0px auto">
    12. <vue-qr
    13. :text="payResult.codeUrl"
    14. :margin="0"
    15. colorDark="green"
    16. :logoSrc="require('@/assets/logo.png')"
    17. colorLight="#fff"
    18. :size="200"
    19. >
    20. vue-qr>
    21. div>
    22. div>
    23. <el-divider>el-divider>
    24. <div style="font-size: 13px">
    25. 提示:<br>
    26. 支付成功前请勿手动关闭页面<br>
    27. 二维码两小时内有效,请及时扫码支付<br>
    28. div>
    29. el-dialog>
    30. div>
    31. template>
    32. <script>
    33. import vueQr from 'vue-qr'
    34. export default {
    35. name: 'app',
    36. components: {
    37. vueQr
    38. },
    39. data() {
    40. return {
    41. //得到响应的结果
    42. orderNo: "e334ce2a6b1d4b8686",
    43. payResult: {
    44. price: 0,//支付金额
    45. //借助vue-qr 可以把二维码地址转换为二维码图片
    46. codeUrl: "",//二维码的地址
    47. },
    48. timer1:"",
    49. dialogVisible: false,//弹出款
    50. }
    51. },
    52. methods: {
    53. //创建二维码
    54. pay() {
    55. this.dialogVisible = true
    56. this.$http.post("/order/createNavite/" + this.orderNo).then(result => {
    57. this.payResult = result.data.result;
    58. this.timer1 = setInterval(() => {
    59. this.queryPayStatus();
    60. }, 3000)
    61. })
    62. },
    63. //根据订单号查询支付状态
    64. queryPayStatus(){
    65. this.$http.post("/order/queryPayStatus/"+this.orderNo).then(result=>{
    66. if(result.data.code===2000){
    67. this.dialogVisible=false;
    68. //清除定时器
    69. clearInterval(this.time1);
    70. this.time1=null;
    71. this.$message.success("支付成功")
    72. }
    73. })
    74. }
    75. }
    76. }
    77. script>
    78. <style>
    79. style>
  • 相关阅读:
    [附源码]JAVA毕业设计桔子酒店客房管理系统(系统+LW)
    LuatOS-SOC接口文档(air780E)--os - os操作
    大数据分析案例-基于SVM支持向量机算法构建手机价格分类预测模型
    SVM 用于将数据分类为两分类或多分类(Matlab代码实现)
    普林斯顿微积分读本第一章--函数、反函数
    C //例4.6 要求按照考试成绩的等级输出百分制分数段,A等为85分以上,B等为70~84分,C等为60~69分,D等为60分以下。成绩的等级由键盘输入。
    ESP8266-Arduino编程实例-三路红外寻迹传感器驱动
    【go语言开发】gorm库连接和操作mysql,实现一个简单的用户注册和登录
    华为OD 高效的任务规划(200分)【java】A卷+B卷
    华为OD:跳房子I
  • 原文地址:https://blog.csdn.net/weixin_68509156/article/details/126356438