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

2023-01-21 0 4,414

目录

1.准备工作

1.1 数据库

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

订单表

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

支付记录表

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

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整合微信支付的资料请关注其它相关文章!

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 SpringBoot实现整合微信支付方法详解 http://www.20zxx.cn/463109/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务