微信支付业务代码流程

目录

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.引入依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wzh</groupId>
    <artifactId>maven-jenkins</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven-jenkins</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--微信需要的依赖-->
        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>

        <!--java端发送请求  在java端模拟浏览器远程访问微信的接口-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>
        <dependency>
            <groupId>com.spring4all</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
            <version>1.9.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

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

package com.wzh.util;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * http请求客户端
 * 
 * @author 必须引入httpclient的依赖:在java端模拟浏览器的效果。
 * 
 */
public class HttpClient {
   private String url;
   private Map<String, String> param;
   private int statusCode;
   private String content;
   private String xmlParam;
   private boolean isHttps;
   public boolean isHttps() {
      return isHttps;
   }
   public void setHttps(boolean isHttps) {
      this.isHttps = isHttps;
   }
   public String getXmlParam() {
      return xmlParam;
   }
   public void setXmlParam(String xmlParam) {
      this.xmlParam = xmlParam;
   }
   public HttpClient(String url, Map<String, String> param) {
      this.url = url;
      this.param = param;
   }
   public HttpClient(String url) {
      this.url = url;
   }
   public void setParameter(Map<String, String> map) {
      param = map;
   }
   public void addParameter(String key, String value) {
      if (param == null)
         param = new HashMap<String, String>();
      param.put(key, value);
   }
   public void post() throws ClientProtocolException, IOException {
      HttpPost http = new HttpPost(url);
      setEntity(http);
      execute(http);
   }
   public void put() throws ClientProtocolException, IOException {
      HttpPut http = new HttpPut(url);
      setEntity(http);
      execute(http);
   }
   public void get() throws ClientProtocolException, IOException {
      if (param != null) {
         StringBuilder url = new StringBuilder(this.url);
         boolean isFirst = true;
         for (String key : param.keySet()) {
            if (isFirst)
               url.append("?");
            else
               url.append("&");
            url.append(key).append("=").append(param.get(key));
         }
         this.url = url.toString();
      }
      HttpGet http = new HttpGet(url);
      execute(http);
   }
   /**
    * set http post,put param
    */
   private void setEntity(HttpEntityEnclosingRequestBase http) {
      if (param != null) {
         List<NameValuePair> nvps = new LinkedList<NameValuePair>();
         for (String key : param.keySet())
            nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
         http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
      }
      if (xmlParam != null) {
         http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
      }
   }
   private void execute(HttpUriRequest http) throws ClientProtocolException,
         IOException {
      CloseableHttpClient httpClient = null;
      try {
         if (isHttps) {
            SSLContext sslContext = new SSLContextBuilder()
                  .loadTrustMaterial(null, new TrustStrategy() {
                     // 信任所有
                     public boolean isTrusted(X509Certificate[] chain,
                           String authType)
                           throws CertificateException {
                        return true;
                     }
                  }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                  sslContext);
            httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
                  .build();
         } else {
            httpClient = HttpClients.createDefault();
         }
         CloseableHttpResponse response = httpClient.execute(http);
         try {
            if (response != null) {
               if (response.getStatusLine() != null)
                  statusCode = response.getStatusLine().getStatusCode();
               HttpEntity entity = response.getEntity();
               // 响应内容
               content = EntityUtils.toString(entity, Consts.UTF_8);
            }
         } finally {
            response.close();
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         httpClient.close();
      }
   }
   public int getStatusCode() {
      return statusCode;
   }
   public String getContent() throws ParseException, IOException {
      return content;
   }
}

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

package com.wzh;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Collections;

/**
 * @ProjectName: springboot-vue0809
 * @Package: com.wzh
 * @ClassName: Generator
 * @Author: 王振华
 * @Description:
 * @Date: 2022/8/9 17:21
 * @Version: 1.0
 */
public class Generator {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/weixin?serverTimezone=Asia/Shanghai", "root", "123456")
                .globalConfig(builder -> {
                    builder.author("王振华") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir(".\\src\\main\\java\\"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.wzh") // 设置父包名
                            //.moduleName("") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.xml, "src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude( "t_order","t_pay_log")// 设置需要生成的表名
                            .addTablePrefix("t_"); // 设置过滤表前缀
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();

    }
}

5.后端

config配置类:

解决跨域:

package com.wzh.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
 
    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;
 
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        corsConfiguration.setMaxAge(MAX_AGE);
        source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

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

package com.wzh.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @ProjectName: springboot-vue0809
 * @Package: com.wzh.system.config
 * @ClassName: MyMetaObjectHandler
 * @Author: 王振华
 * @Description:
 * @Date: 2022/8/10 15:43
 * @Version: 1.0
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    //当添加时自动填充的值
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
        //  切记这里是表的列名  不是实体类的属性名
        this.strictInsertFill(metaObject, "gmtCreate", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        this.strictInsertFill(metaObject, "gmtModified", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        this.strictInsertFill(metaObject, "payTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        this.strictInsertFill(metaObject, "isDeleted", () -> 0, Integer.class);

        // 或者
        //this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }
    //当修改时自动填充的值
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        //this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
        // 或者
        this.strictUpdateFill(metaObject, "gmtModified", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        this.strictUpdateFill(metaObject, "status", () -> 1, Integer.class); // 起始版本 3.3.3(推荐)
        // 或者
        //this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)

    }
}

application配置文件

server.port=8081
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/weixin?serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.druid.username=root
spring.datasource.druid.password=123456

logging.level.com.wzh.weixinpay.dao=debug

# 微信的appid 商家id 密钥---申请你无法申请 因为需要营业执照

weixin.appid=wx8011d27c
weixin.mch_id=153611
weixin.api_key=Cc158380615838062

controller控制层:

package com.wzh.controller;

import com.wzh.service.IOrderService;
import com.wzh.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @ProjectName: maven-jenkins
 * @Package: com.wzh.controller
 * @ClassName: OrderController
 * @Author: 王振华
 * @Description:
 * @Date: 2022/8/12 22:21
 * @Version: 1.0
 */
@RestController
@RequestMapping("order")
public class OrderController {

    @Autowired
    private IOrderService orderService;

    /**
     * 创建订单,生成二维码
     * @param orderNo
     * @return
     */
    @PostMapping("createNavite/{orderNo}")
    public CommonResult createNative(@PathVariable String orderNo){
        return orderService.createNavite(orderNo);
    }

    /**
     * 查询订单状态
     * @param orderNo
     * @return
     */
    @PostMapping("queryPayStatus/{orderNo}")
    public CommonResult queryPayStatus(@PathVariable String orderNo){
        return orderService.queryPayStatus(orderNo);
    }
}

service:

package com.wzh.service;

import com.wzh.entity.Order;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wzh.vo.CommonResult;

/**
 * <p>
 * 订单 服务类
 * </p>
 *
 * @author 王振华
 * @since 2022-08-12
 */
public interface IOrderService extends IService<Order> {
    CommonResult createNavite(String orderNo);

    CommonResult queryPayStatus(String orderNo);

}

 实现类:

package com.wzh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.sun.media.jfxmedia.logging.Logger;
import com.wzh.entity.Order;
import com.wzh.entity.PayLog;
import com.wzh.mapper.OrderMapper;
import com.wzh.mapper.PayLogMapper;
import com.wzh.service.IOrderService;
import com.wzh.service.IPayLogService;
import com.wzh.util.HttpClient;
import com.wzh.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ProjectName: maven-jenkins
 * @Package: com.wzh.service.impl
 * @ClassName: OrderServiceImpl
 * @Author: 王振华
 * @Description:
 * @Date: 2022/8/12 22:28
 * @Version: 1.0
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Resource
    private PayLogMapper payLogMapper;

    @Value("${weixin.appid}")
    private String appId;

    @Value("${weixin.mch_id}")
    private String mchId;

    @Value("${weixin.api_key}")
    private String apiKey;

    public CommonResult createNavite(String orderNo) {
        //1.根据订单号查询出订单信息
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("order_no", orderNo);
        wrapper.eq("status", 0);
        Order order = orderMapper.selectOne(wrapper);
        if (order != null) {
            try {
                //设置请求的参数----格式为xml格式
                Map<String, String> params = new HashMap<>();//请求参数
                params.put("appid", appId);
                params.put("mch_id", mchId);
                params.put("nonce_str", WXPayUtil.generateNonceStr());
                params.put("body", order.getCourseTitle());
                params.put("out_trade_no", orderNo);
                //0.01未来换成真实的金额
                params.put("total_fee", new BigDecimal(0.01).multiply(new BigDecimal(100)).longValue() + "");
                params.put("spbill_create_ip", "127.0.0.1");//未来写成项目部署的ip
                params.put("notify_url", "http://localhost:8081/pay/back");
                params.put("trade_type", "NATIVE");

                //创建HttpClient对象 作用远程调用
                HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
                //支持https协议
                client.setHttps(true);
                //设置请求的参数
                client.setXmlParam(WXPayUtil.generateSignedXml(params, apiKey));
                //发送请求
                client.post();
                //获取请求的响应结果
                String content = client.getContent();
                System.out.println(content);

                Map<String, String> map = WXPayUtil.xmlToMap(content);
                if (map.get("result_code").equals("SUCCESS")) {
                    Map<String, Object> result = new HashMap<>();
                    result.put("codeUrl", map.get("code_url"));
                    result.put("price", order.getTotalFee());
                    result.put("orderNo", orderNo);
                    return new CommonResult(2000, "生成二维码成功", result);
                }
            } catch (Exception e) {

            }
        }
        return new CommonResult(5000, "订单失效", null);
    }

    @Override
    public CommonResult queryPayStatus(String orderNo) {
        try {
            //1.根据订单状态查询微信的支付情况
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            Map<String, String> params = new HashMap<>();
            params.put("appid", appId);
            params.put("mch_id", mchId);
            params.put("out_trade_no", orderNo);
            params.put("nonce_str", WXPayUtil.generateNonceStr());
            //支持https协议
            client.setHttps(true);
            //设置请求的参数
            client.setXmlParam(WXPayUtil.generateSignedXml(params, apiKey));
            //发送请求
            client.post();
            //获取请求的响应结果
            String content = client.getContent();
            //System.out.println(content);

            Map<String, String> map = WXPayUtil.xmlToMap(content);
            if(map.get("trade_state").equals("SUCCESS")){
                //修改订单状态
                Order order = new Order();
                //order.setStatus(1);
                //order.setGmtModified(LocalDateTime.now());
                QueryWrapper<Order> wrapper = new QueryWrapper<>();
                wrapper.eq("order_no",orderNo);
                wrapper.eq("status",0);
                int update = orderMapper.update(order, wrapper);
                //TODO 往支付记录表中添加支付记录
                QueryWrapper<Order> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("order_no",orderNo);
                wrapper1.eq("status",1);
                Order order1 = orderMapper.selectOne(wrapper1);
                if(order1!=null){
                    PayLog payLog = new PayLog(null,orderNo,null,order1.getTotalFee(),map.get("transaction_id"),map.get("trade_state"),0,map.get("attach"),null,null,null);
                    int insert = payLogMapper.insert(payLog);
                }
                return new CommonResult(2000,"支付成功",null);

            }else if(map.get("trade_state").equals("NOTPAY")){
                return new CommonResult(3000,"订单未支付",null);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return new CommonResult(5000,"支付失败",null);
    }
}

mapper:

package com.wzh.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wzh.entity.Order;

public interface OrderMapper extends BaseMapper<Order> {
}

entity:

package com.wzh.entity;

import com.baomidou.mybatisplus.annotation.*;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * <p>
 * 订单
 * </p>
 *
 * @author 王振华
 * @since 2022-08-12
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("t_order")
@ApiModel(value = "Order对象", description = "订单")
public class Order implements Serializable {

    private static final long serialVersionUID = 1L;
    @TableId(type = IdType.ASSIGN_ID)
    private String id;

    @ApiModelProperty("订单号")
    private String orderNo;

    @ApiModelProperty("课程id")
    private String courseId;

    @ApiModelProperty("课程名称")
    private String courseTitle;

    @ApiModelProperty("课程封面")
    private String courseCover;

    @ApiModelProperty("讲师名称")
    private String teacherName;

    @ApiModelProperty("会员id")
    private String memberId;

    @ApiModelProperty("会员昵称")
    private String nickname;

    @ApiModelProperty("会员手机")
    private String mobile;

    @ApiModelProperty("订单金额(分)")
    private Double totalFee;

    @ApiModelProperty("支付类型(0:微信 1:支付宝)")
    private Integer payType;

    @ApiModelProperty("订单状态(0:未支付 1:已支付)")
    @TableField(fill = FieldFill.UPDATE,value = "status")
    private Integer status;

    @ApiModelProperty("逻辑删除 1(true)已删除, 0(false)未删除")
    @TableLogic
    private Integer isDeleted;

    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @ApiModelProperty("创建时间")
    private LocalDateTime gmtCreate;

    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @TableField(fill = FieldFill.UPDATE,value = "gmt_modified")
    @ApiModelProperty("更新时间")
    private LocalDateTime gmtModified;


}
package com.wzh.entity;

import com.baomidou.mybatisplus.annotation.*;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * <p>
 * 支付日志表
 * </p>
 *
 * @author 王振华
 * @since 2022-08-12
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("t_pay_log")
@ApiModel(value = "PayLog对象", description = "支付日志表")
public class PayLog implements Serializable {

    private static final long serialVersionUID = 1L;
    @TableId(type = IdType.ASSIGN_ID)
    private String id;

    @ApiModelProperty("订单号")
    private String orderNo;

    @TableField(fill = FieldFill.INSERT,value = "pay_time")
    @ApiModelProperty("支付完成时间")
    private LocalDateTime payTime;

    @ApiModelProperty("支付金额(分)")
    private Double totalFee;

    @ApiModelProperty("交易流水号")
    private String transactionId;

    @ApiModelProperty("交易状态")
    private String tradeState;

    @ApiModelProperty("支付类型(0:微信 1:支付宝)")
    private Integer payType;

    @ApiModelProperty("其他属性")
    private String attr;

    @TableLogic
    @TableField(fill = FieldFill.INSERT,value = "is_deleted")
    @ApiModelProperty("逻辑删除 1(true)已删除, 0(false)未删除")
    private Integer isDeleted;

    @TableField(fill = FieldFill.INSERT,value = "gmt_create")
    @ApiModelProperty("创建时间")
    private LocalDateTime gmtCreate;

    @TableField(fill = FieldFill.INSERT_UPDATE,value = "gmt_modified")
    @ApiModelProperty("更新时间")
    private LocalDateTime gmtModified;


}

vo:

package com.wzh.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @ProjectName: maven-jenkins
 * @Package: com.wzh.vo
 * @ClassName: CommonResult
 * @Author: 王振华
 * @Description:
 * @Date: 2022/8/12 22:23
 * @Version: 1.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResult {
    private Integer code;

    private String msg;

    private Object result;
}

6.前端

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

 

<template>
    <div id="app">
        <el-button type="primary" @click="pay">支付</el-button>

        <el-dialog
                title="收银台"
                :visible.sync="dialogVisible"
                width="30%"
        >
            <div style="text-align: center">
                <p>微信支付 {{payResult.price}} 元</p>
                <div style="border: 1px solid red;width: 220px;padding: 10px;margin: 0px auto">
                    <vue-qr
                            :text="payResult.codeUrl"
                            :margin="0"
                            colorDark="green"
                            :logoSrc="require('@/assets/logo.png')"
                            colorLight="#fff"
                            :size="200"
                    >

                    </vue-qr>
                </div>
            </div>
            <el-divider></el-divider>
            <div style="font-size: 13px">
                提示:<br>
                支付成功前请勿手动关闭页面<br>
                二维码两小时内有效,请及时扫码支付<br>
            </div>
        </el-dialog>
    </div>
</template>

<script>
    import vueQr from 'vue-qr'

    export default {
        name: 'app',
        components: {
            vueQr
        },
        data() {
            return {
                //得到响应的结果
                orderNo: "e334ce2a6b1d4b8686",
                payResult: {
                    price: 0,//支付金额
                    //借助vue-qr 可以把二维码地址转换为二维码图片
                    codeUrl: "",//二维码的地址

                },
                timer1:"",
                dialogVisible: false,//弹出款


            }
        },

        methods: {
            //创建二维码
            pay() {
                this.dialogVisible = true
                this.$http.post("/order/createNavite/" + this.orderNo).then(result => {
                    this.payResult = result.data.result;
                    this.timer1 = setInterval(() => {
                        this.queryPayStatus();
                    }, 3000)
                })
            },
            //根据订单号查询支付状态
            queryPayStatus(){
                this.$http.post("/order/queryPayStatus/"+this.orderNo).then(result=>{
                    if(result.data.code===2000){
                        this.dialogVisible=false;
                        //清除定时器
                        clearInterval(this.time1);
                        this.time1=null;
                        this.$message.success("支付成功")
                    }
                })
            }
        }
    }
</script>

<style>

</style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值