SpringBoot实现整合微信支付方法详解

目录
  • 1.准备工作
    • 1.1 数据库表
    • 1.2 实体类
    • 1.3 导入依赖
    • 1.4 配置文件
    • 1.5 创建读取微信支付相关信息的工具类
    • 1.6 其他工具类
  • 2.生成订单
    • 2.1 远程调用用户模块和课程模块
    • 2.2 远程调用方法的实现
    • 2.3 根据课程id和用户id生成订单
  • 3.查询订单信息
    • 3.1 controller层
    • 3.2 service层
  • 4.生成微信支付的二维码
    • 4.1 controller层
    • 4.2 service层
  • 5.查询订单支付状态
    • 5.1 controller层
    • 5.2 service层

1.准备工作

1.1 数据库表

这里涉及微信支付一共两个表:

订单表

支付记录表

1.2 实体类

数据库对应的实体类:

订单表

@Data
@ToString
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("t_order")
@ApiModel(value = "Order对象", description = "订单")
public class Order implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.ID_WORKER_STR)
    private String id;

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

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

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

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

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

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

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

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

    @ApiModelProperty(value = "订单金额(分)")
    private BigDecimal totalFee;

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

    @ApiModelProperty(value = "订单状态(0:未支付 1:已支付)")
    private Integer status;

    @ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
    private Boolean isDeleted;

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

    @ApiModelProperty(value = "更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date gmtModified;
}

支付日志表

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("t_pay_log")
@ApiModel(value = "PayLog对象", description = "支付日志表")
public class PayLog implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.ID_WORKER_STR)
    private String id;

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

    @ApiModelProperty(value = "支付完成时间")
    private Date payTime;

    @ApiModelProperty(value = "支付金额(分)")
    private BigDecimal totalFee;

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

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

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

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

    @ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
    private Boolean isDeleted;

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

    @ApiModelProperty(value = "更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date gmtModified;
}

1.3 导入依赖

在订单模块service_order导入微信支付需要的依赖:

<dependencies>
    <dependency>
        <groupId>com.github.wxpay</groupId>
        <artifactId>wxpay-sdk</artifactId>
        <version>0.0.3</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
    </dependency>
</dependencies>

1.4 配置文件

在配置文件application.properties配置相关的信息:

# 服务端口
server.port=8007
# 服务名
spring.application.name=service-order
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

spring.jackson.time-zone=GMT+8
#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/atguigu/eduorder/mapper/xml/*.xml
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#开启熔断机制
#feign.hystrix.enabled=true
# 设置hystrix超时时间,默认1000ms
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000

#关联的公众号appid
wx.pay.app_id=wx74862e0dfc69954
#商户号
wx.pay.partner=155895011
#商户key
wx.pay.partnerkey=T6m9iK73b0kn9g5v426MKHQH7X8rKwb
#回调地址
wx.pay.notifyurl=http://guli.shop/api/order/weixinPay/weixinNotify
#微信提供的固定地址
wx.pay.wxurl=https://api.mch.weixin.qq.com/pay/unifiedorder
#微信查询状态地址
wx.pay.queryUrl=https://api.mch.weixin.qq.com/pay/orderquery

1.5 创建读取微信支付相关信息的工具类

创建一个读取微信支付需要的信息的工具类ConstantWxPayUtils:

@Controller
public class ConstantWxPayUtils implements InitializingBean {
    @Value("${wx.pay.app_id}")
    private String appID;
    @Value("${wx.pay.partner}")
    private String partner;
    @Value("${wx.pay.partnerkey}")
    private String partnerKey;
    @Value("${wx.pay.notifyurl}")
    private String notifyUrl;
    @Value("${wx.pay.wxurl}")
    private String wxUrl;
    @Value("${wx.pay.queryUrl}")
    private String queryUrl;

    //定义公共静态常量
    public static String WX_PAY_APP_ID;
    public static String WX_PAY_PARTNER;
    public static String WX_PAY_PARTNER_KEY;
    public static String WX_PAY_NOTIFY_URL;
    public static String WX_PAY_WX_URL;
    public static String WX_PAY_QUERY_URL;

    @Override
    public void afterPropertiesSet() throws Exception {
        WX_PAY_APP_ID = appID;
        WX_PAY_PARTNER = partner;
        WX_PAY_PARTNER_KEY = partnerKey;
        WX_PAY_NOTIFY_URL = notifyUrl;
        WX_PAY_WX_URL = wxUrl;
        WX_PAY_QUERY_URL=queryUrl;
    }
}

1.6 其他工具类

用于随机生成订单号的工具类OrderNoUtil:

public class OrderNoUtil {
    /**
     * 获取订单号
     * @return
     */
    public static String getOrderNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String newDate = sdf.format(new Date());
        String result = "";
        Random random = new Random();
        for (int i = 0; i < 3; i++) {
            result += random.nextInt(10);
        }
        return newDate + result;
    }
}

HttpClient工具类:

/**
 * http请求客户端
 *
 * @author xppll
 *
 */
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;
    }

}

2.生成订单

这里一共涉及service_order订单模块、service_ucenter用户模块、service-edu课程模块。

service_order使用Fegin远程调用其他模块的方法。

详细的Fegin的使用可以参考:SpringCloud-Feign远程调用

2.1 远程调用用户模块和课程模块

在service_order订单模块创建:

@Component
@FeignClient("service-ucenter") //调用的服务名称
public interface UcenterClient {

    //根据用户id获取用户信息,用于生成订单使用
    @PostMapping("/educenter/member/getUserInfoOrder/{id}")
    public UcenterMemberOrder getUserInfoOrder(@PathVariable("id") String id);
}
@Component
@FeignClient("service-edu") //调用的服务名称
public interface CourseClient {

    //根据课程id查询课程信息
    @PostMapping("/eduservice/coursefront/getCourseInfoOrder/{id}")
    public CourseWebOrder getCourseInfoOrder(@PathVariable("id") String id);

}

2.2 远程调用方法的实现

在service-edu课程模块实现根据课程id查询课程信息的getCourseInfoOrder方法

controller层:

/**
 * 根据课程id查询课程信息
 * @param id 客场id
 * @return CourseWebOrder
 */
@PostMapping("getCourseInfoOrder/{id}")
public CourseWebOrder getCourseInfoOrder(@PathVariable("id") String id) {
    CourseWebVo courseInfo = courseService.getBaseCourseInfo(id);
    CourseWebOrder courseWebOrder = new CourseWebOrder();
    BeanUtils.copyProperties(courseInfo, courseWebOrder);
    return courseWebOrder;
}

service层:

/**
 * 根据课程id,编写sql语句查询课程信息
 * @param courseId 课程id
 * @return CourseWebVo
 */
@Override
public CourseWebVo getBaseCourseInfo(String courseId) {
    return baseMapper.getBaseCourseInfo(courseId);
}

mapper层:

<!--根据课程id查询课程基本信息-->
<select id="getBaseCourseInfo" resultType="com.atguigu.eduservice.entity.frontvo.CourseWebVo">
    SELECT ec.id,
    ec.`title`,
    ec.`price`,
    ec.lesson_num as lessonNum,
    ec.cover,
    ec.buy_count  as buyCount,
    ec.view_count as viewCount,
    ecd.description,
    et.id            teacherId,
    et.`name`     AS teacherName,
    et.intro,
    et.avatar,
    es1.id        as subjectLevelOneId,
    es1.`title`   AS subjectLevelOne,
    es2.id        as subjectLevelTwoId,
    es2.`title`   AS subjectLevelTwo
    FROM edu_course ec
    LEFT JOIN edu_course_description ecd ON ec.id = ecd.id
    LEFT JOIN edu_teacher et ON ec.`teacher_id` = et.`id`
    LEFT JOIN edu_subject es1 ON ec.`subject_parent_id` = es1.`id`
    LEFT JOIN edu_subject es2 ON ec.`subject_id` = es2.`id`
    WHERE ec.id = #{courseId}
</select>

在service_ucenter用户模块实现根据用户id获取用户信息的getUserInfoOrder方法

controller层:

/**
 * 根据用户id获取用户信息,用于生成订单使用
 *
 * @param id 用户id
 * @return UcenterMemberOrder
 */
@PostMapping("getUserInfoOrder/{id}")
public UcenterMemberOrder getUserInfoOrder(@PathVariable("id") String id) {
    UcenterMember member = memberService.getById(id);
    UcenterMemberOrder memberOrder = new UcenterMemberOrder();
    BeanUtils.copyProperties(member, memberOrder);
    return memberOrder;
}

2.3 根据课程id和用户id生成订单

controller层:

@CrossOrigin
@RestController
@RequestMapping("/eduorder/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * 生成订单的方法
     *
     * @param courseId 课程id
     * @param request  用于获取用户id
     * @return 返回订单号
     */
    @PostMapping("createOrder/{courseId}")
    public R saveOrder(@PathVariable("courseId") String courseId, HttpServletRequest request) {
        //通过JWT工具类获取用户id
        //创建订单,返回订单号
        String orderNo = orderService.createOrderById(courseId, JwtUtils.getMemberIdByJwtToken(request));
        return R.ok().data("orderId", orderNo);
    }
}

service层:

/**
 * 根据courseId和userId生成订单
 *
 * @param courseId 课程id
 * @param userId   用户id
 * @return 返回订单号
 */
@Override
public String createOrderById(String courseId, String userId) {
    //通过远程调佣根据用户id获取用户信息
    UcenterMemberOrder userInfoOrder = ucenterClient.getUserInfoOrder(userId);
    //通过远程调佣根据课程id获取课程信息
    CourseWebOrder courseInfoOrder = courseClient.getCourseInfoOrder(courseId);
    Order order = new Order();
    //订单号
    order.setOrderNo(OrderNoUtil.getOrderNo());
    order.setCourseId(courseId);
    order.setCourseTitle(courseInfoOrder.getTitle());
    order.setCourseCover(courseInfoOrder.getCover());

    order.setTeacherName(courseInfoOrder.getTeacherName());
    order.setTotalFee(courseInfoOrder.getPrice());
    order.setMemberId(userId);
    order.setMobile(userInfoOrder.getMobile());
    order.setNickname(userInfoOrder.getNickname());
    //支付状态  未支付:0  已支付:1
    order.setStatus(0);
    //支付类型  微信:1    支付宝:2
    order.setPayType(1);
    //保存到数据库
    baseMapper.insert(order);
    //返回订单号
    return order.getOrderNo();
}

3.查询订单信息

3.1 controller层

在OrderController里创建getOrderInfo用于生成订单:

/**
 * 根据订单id查询订单信息
 * @param orderId 订单id
 * @return 返回订单信息
 */
@GetMapping("getOrderInfo/{orderId}")
public R getOrderInfo(@PathVariable("orderId") String orderId) {
    Order order=orderService.getOrderByOrderId(orderId);
    return R.ok().data("item", order);
}

3.2 service层

/**
 * 根据订单id查询订单信息
 *
 * @param orderId 订单id
 * @return 返回订单信息
 */
@Override
public Order getOrderByOrderId(String orderId) {
    LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(Order::getOrderNo, orderId);
    return baseMapper.selectOne(queryWrapper);
}

4.生成微信支付的二维码

4.1 controller层

在PayLogController里创建createNative用于生成支付二维码:

@CrossOrigin
@RestController
@RequestMapping("/eduorder/paylog")
public class PayLogController {

    @Autowired
    private PayLogService payLogService;

    /**
     * 根据订单号生成微信支付二维码
     * @param orderNo 订单号
     * @return R
     */
    @GetMapping("createNative/{orderNo}")
    public R createNative(@PathVariable("orderNo") String orderNo){
        //返回信息,包含二维码地址,还有其他信息
        Map map=payLogService.createNative(orderNo);
        return R.ok().data(map);
    }
}

4.2 service层

  1. 生成微信支付二维码大概分为这几步:
  2. 根据订单号查询订单信息
  3. 使用map设置生成二维码需要的参数
  4. 发送httpclient请求,传递xml格式的参数,传入微信支付提供的固定地址
  5. 得到发送请求返回的结果
  6. 最终返回封装数据
/**
 * 根据订单号生成微信支付二维码
 * @param orderNo 订单号
 * @return map
 */
@Override
public Map createNative(String orderNo) {
    try {
        //1.根据订单号查询订单信息
        Order order = orderService.getOrderByOrderId(orderNo);
        //2.使用map设置生成二维码需要的参数
        Map m = new HashMap();
        //关联的公众号appid
        m.put("appid", ConstantWxPayUtils.WX_PAY_APP_ID);
        //商户号
        m.put("mch_id", ConstantWxPayUtils.WX_PAY_PARTNER);
        //随机字符串
        m.put("nonce_str", WXPayUtil.generateNonceStr());
        //课程标题
        m.put("body", order.getCourseTitle());
        //订单号
        m.put("out_trade_no", orderNo);
        //价格
        m.put("total_fee", order.getTotalFee().multiply(new BigDecimal("100")).longValue() + "");
        //支付的ip地址
        m.put("spbill_create_ip", "127.0.0.1");
        m.put("notify_url", ConstantWxPayUtils.WX_PAY_NOTIFY_URL);
        m.put("trade_type", "NATIVE");

        //3.发送httpclient请求,传递参数xml格式,传入微信支付提供的固定地址
        HttpClient client = new HttpClient(ConstantWxPayUtils.WX_PAY_WX_URL);
        //设置xml格式的参数,需要传入二维码参数m和商户key
        client.setXmlParam(WXPayUtil.generateSignedXml(m, ConstantWxPayUtils.WX_PAY_PARTNER_KEY));
        //默认不支持https,设置为true支持
        client.setHttps(true);
        //执行请求发送
        client.post();
        //4.得到发送请求返回的结果
        //返回的内容是xml格式
        String xml = client.getContent();
        //把xml格式转换为map集合
        Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);

        //5.最终返回封装数据
        Map map = new HashMap();
        //订单号
        map.put("out_trade_no", orderNo);
        //课程id
        map.put("course_id", order.getCourseId());
        //价格
        map.put("total_fee", order.getTotalFee());
        //返回二维码操作状态码
        map.put("result_code", resultMap.get("result_code"));
        //二维码地址
        map.put("code_url", resultMap.get("code_url"));
        return map;
    } catch (Exception e) {
        throw new GuliException(20001, "生成微信支付二维码失败");
    }
}

5.查询订单支付状态

5.1 controller层

在PayLogController里创建queryPayStatus用于获取支付状态:

/**
 * 获取支付状态
 * @param orderNo 订单号
 * @return R
 */
@GetMapping("queryPayStatus/{orderNo}")
public R queryPayStatus(@PathVariable("orderNo") String orderNo){
    Map<String, String> map=payLogService.queryPayStatus(orderNo);
    if(map==null){
        return R.error().message("支付出错!");
    }
    //如果map不为空,通过map获取订单状态
    if(map.get("trade_state").equals("SUCCESS")){
        //添加记录到支付表,更新订单表订单状态
        payLogService.updateOrdersStatus(map);
        return R.ok().message("支付成功!");
    }
    return R.ok().code(25000).message("正在支付中...");
}

5.2 service层

根据订单号查询订单支付状态大概分为一下几步:

  1. 封装参数
  2. 发送httpclient
  3. 得到请求返回的内容
/**
 * 根据订单号查询订单支付状态
 * @param orderNo
 * @return
 */
@Override
public Map<String, String> queryPayStatus(String orderNo) {
    try {
        //1.封装参数
        Map m=new HashMap();
        //关联的公众号appid
        m.put("appid",ConstantWxPayUtils.WX_PAY_APP_ID);
        //商户号
        m.put("mch_id",ConstantWxPayUtils.WX_PAY_PARTNER);
        //订单号
        m.put("out_trade_no",orderNo);
        //随机字符串
        m.put("nonce_str",WXPayUtil.generateNonceStr());
        //2.发送httpclient
        HttpClient client = new HttpClient(ConstantWxPayUtils.WX_PAY_QUERY_URL);
        client.setXmlParam(WXPayUtil.generateSignedXml(m,ConstantWxPayUtils.WX_PAY_PARTNER_KEY));
        client.setHttps(true);
        client.post();
        //3.得到请求返回的内容
        String xml = client.getContent();
        Map<String, String> resultMap=WXPayUtil.xmlToMap(xml);
        return resultMap;
    } catch (Exception e) {
        e.printStackTrace();
        throw  new GuliException(20001,"查询订单支付状态失败");
    }
}

如果支付成功,需要添加记录到支付表,更新订单表订单状态:

/**
 * 向支付表添加记录,更新订单表订单状态
 * @param map
 */
@Override
public void updateOrdersStatus(Map<String, String> map) {
    //从map获取订单号
    String orderNo = map.get("out_trade_no");
    Order order = orderService.getOrderByOrderId(orderNo);
    //更新订单表t_order的订单状态status
    if(order.getStatus().intValue()==1){
        return;
    }
    order.setStatus(1);
    orderService.updateById(order);

    //向支付表 t_pag_log 添加记录
    PayLog payLog=new PayLog();
    payLog.setOrderNo(orderNo);

    payLog.setPayTime(new Date());
    //支付类型
    payLog.setPayType(1);
    //支付金额
    payLog.setTotalFee(order.getTotalFee());
    //支付状态
    payLog.setTradeState(map.get("trade_state"));
    //交易流水号
    payLog.setTransactionId(map.get("transaction_id"));
    //其他属性,转为json字符串
    payLog.setAttr(JSONObject.toJSONString(map));
    baseMapper.insert(payLog);
} 

以上就是SpringBoot实现整合微信支付方法详解的详细内容,更多关于SpringBoot整合微信支付的资料请关注我们其它相关文章!

(0)

相关推荐

  • springboot对接微信支付的完整流程(附前后端代码)

    展示图: 对接的完整流程如下 首先是配置 gzh.appid=公众号appid wxPay.mchId=商户号 wxPay.key=支付密钥 wxPay.notifyUrl=域名回调地址 常量: /**微信支付统一下单接口*/ public static final String unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; public static String SUCCESSxml = &q

  • springboot整合微信支付sdk过程解析

    前言 之前做的几个微信小程序项目,大部分客户都有要在微信小程序前端提现的需求.提现功能的实现,自然使用企业付款接口,不过这个功能开通比较麻烦,要满足3个条件; 之前实现过几个微信支付的接口,不过都是自己码的代码,从网上找找拼凑,觉得看起来不舒服~_~ 于是乎找到了微信官方提供的支付sdk.这里用的是java版本,springboot整合java 下载sdk,引入项目 这里可以直接下载官方提供的sdk,然后将几个java类拷贝到你的项目,也可以直接引入maven依赖,这里是直接将Java类拷贝到我

  • 一篇文章带你入门Springboot整合微信登录与微信支付(附源码)

    0. 前期准备 在使用微信支付前,默认小伙伴已经具备以下技能: 熟练使用springboot(SSM) + Mybatis(plus)/JPA + HttpClient + mysql5.x 了解JWT 权限校验 阅读过微信开放平台微信支付与微信登录相关文档,可以简单看懂时序图 有微信开放平台开发者资质认证账户,具备开通微信支付(如果不具备的小伙伴可以找身边有的人借一下) 1. 微信扫码登录 1.1 微信授权一键登录功能介绍 简介:登录方式优缺点和微信授权一键登录功能介绍 # 1.手机号或者邮箱

  • springboot接入微信app支付的方法

    1.前戏 1.1请先完成微信APP支付接入商户服务中心 1.2详情请参考微信官方文档:https://open.weixin.qq.com/ 2.application.yml文件的配置如下 #微信支付配置 tenpayconfig: #商户APPID appId: asdfg12345 #商户号 mchId: 12345678 #商户的key(API密匙) key: qwertyuiop #API支付请求地址 payUrl: https://api.mch.weixin.qq.com/pay/

  • SpringBoot微信扫码支付的实现示例

    一.首先导入生成二维码和微信支付环境 <!-- 生成二维码工具 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>com.google.zx

  • Springboot集成第三方jar快速实现微信、支付宝等支付场景

    前言 最近有个小型的活动外包项目,要集成一下支付功能,因为项目较小,按照微信官方文档的配置开发又极容易出错,加上个人又比较懒. 于是在gitee上找到一个封装好的各种支付场景业务,只需要自己将支付参数修改一下就能成功调起支付业务,实现真正的快速开发. 一.项目地址 官方网站:https://javen205.gitee.io/ijpay/ Gitee仓库: https://gitee.com/javen205/IJPay 官方示例程序源码:https://gitee.com/javen205/I

  • SpringBoot实现整合微信支付方法详解

    目录 1.准备工作 1.1 数据库表 1.2 实体类 1.3 导入依赖 1.4 配置文件 1.5 创建读取微信支付相关信息的工具类 1.6 其他工具类 2.生成订单 2.1 远程调用用户模块和课程模块 2.2 远程调用方法的实现 2.3 根据课程id和用户id生成订单 3.查询订单信息 3.1 controller层 3.2 service层 4.生成微信支付的二维码 4.1 controller层 4.2 service层 5.查询订单支付状态 5.1 controller层 5.2 serv

  • springBoot整合rabbitMQ的方法详解

    引入pom <?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

  • SpringBoot整合Shiro的方法详解

    目录 1.Shito简介 1.1 什么是shiro 1.2 有哪些功能 2.QuickStart 3.SpringBoot中集成 1.导入shiro相关依赖 2.自定义UserRealm 3.定义shiroConfig 4.新建页面进行测试 1.Shito简介 1.1 什么是shiro Apache Shiro是一个java安全(权限)框架 Shiro可以非常容易的开发出足够好的应用,其不仅可以用在javase环境,也可以用在javaee环境 shiro可以完成,认证,授权,加密,会话管理,we

  • SpringBoot整合RocketMQ的方法详解

    目录 一:Ubuntu安装RocketMQ 二:添加RocketMQ依赖 三:在application中添加RocketMQ配置 四:编写消费者,消息生产者,消息实体类(自定义) 五:测试Controller 一:Ubuntu安装RocketMQ 1.下载(在下面地址选择自己需要的版本的rocketmq) http://rocketmq.apache.org/release_notes/ 2.解压,更改配置 将下载的zip文件解压到自己需要安装的位置 在unbuntu系统下需要修改安装跟目录下的

  • springboot命令行启动的方法详解

    springboot命令行启动 创建的springboot项目想看看效果,不想打开idea等开发工具,使用直接使用命令行启动. maven的命令启动 需要将 jdk的bin目录和maven的bin目录添加到环境变量path中,若是没有,mvn就要用在maven的bin环境中的全路径 若是没有添加环境变量 mvn就要是E:\software\apache-maven-3.3.9\bin\mvn(安装路径\bin\mvn) java就要是C:\software\jdk\bin\java.exe(安装

  • 2020版IDEA整合GitHub的方法详解

    1.前提电脑安装好Git需要有个已经注册的GitHub帐号2.在IDEA中设置Git2.1 确保IDEA安装Git GitHub插件 2.2 在IDEA中设置Git,在File–>Setting->Version Control–>Git–>Path to Git executable选择你的git安装后的git.exe文件,然后点击Test,测试是否设置成功 2.3 在IDEA中设置GitHub,File–>Setting->Version Control–>G

  • Mockito 结合 Springboot 进行应用测试的方法详解

    Spring Boot可以和大部分流行的测试框架协同工作:通过Spring JUnit创建单元测试:生成测试数据初始化数据库用于测试:Spring Boot可以跟BDD(Behavier Driven Development)工具.Cucumber和Spock协同工作,对应用程序进行测试. 在web应用程序中,我们主要是对Service层做单元测试,以前单元测试都是使用 junit4 ,对Controller层做集成测试或者接口测试,对Controller层的测试一般有两种方法:(1)发送htt

  • SpringBoot中获取profile的方法详解

    目录 spring boot与profile 静态获取方式 autowire ProfileConfig spring boot与profile spring boot 的项目中不再使用xml的方式进行配置,并且,它还遵循着约定大于配置. 静态获取方式 静态工具类获取当前项目的profile环境. import org.springframework.beans.BeansException; import org.springframework.context.ApplicationConte

  • SpringBoot进行参数校验的方法详解

    目录 介绍 1.SpringBoot中集成参数校验 1.1引入依赖 1.2定义参数实体类 1.3定义校验类进行测试 1.4打开接口文档模拟提交数据 2.参数异常加入全局异常处理器 3.自定义参数校验 3.1创建自定义注解 3.2自定义校验逻辑 3.3在字段上增加注解 3.4体验效果 4.分组校验 4.1定义分组接口 4.2在模型中给参数分配分组 4.3体现效果 介绍 在日常的接口开发中,为了防止非法参数对业务造成影响,经常需要对接口的参数进行校验,例如登录的时候需要校验用户名和密码是否为空,添加

  • SpringBoot设置动态定时任务的方法详解

    之前写过文章记录怎么在SpringBoot项目中简单使用定时任务,不过由于要借助cron表达式且都提前定义好放在配置文件里,不能在项目运行中动态修改任务执行时间,实在不太灵活. 经过网上搜索学习后,特此记录如何在SpringBoot项目中实现动态定时任务. 因为只是一个demo,所以只引入了需要的依赖: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <ar

随机推荐