SpringBoot + 微信公众号JSAPI支付功能的实现

 更新时间:2021年03月26日 09:28:40   作者:开心的小马甲  
这篇文章主要介绍了SpringBoot + 微信公众号JSAPI支付功能的实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

1、pom.xml依赖配置

<!-- 微信支付 -->
<dependency>
  <groupId>com.egzosn</groupId>
  <artifactId>pay-java-wx</artifactId>
  <version>2.12.4</version>
</dependency>

2、application.yml文件配置微信公众号的基础信息

#微信公众号支付配置
wechatpay:
 mchId: # 商户Id
 appId: #应用id
 storePassword: #秘钥支付密码
 secretKey: # 密钥
 notifyUrl: #微信支付回调
 keyStore:  # 证书所在位置

3、设置配置文件 WechatPayConfig.java

package com.example.emoticon.wechat;
 
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
/**
 * @ClassName WechatPayConfig
 * @Description 微信支付配置
 * @Author WangJing
 * @Date 2021/3/23 4:38 下午
 * @Version V1.1.0
 */
 
@Data
@Component
@ConfigurationProperties(prefix = "wechatpay")
public class WechatPayConfig {
 
  private String mchId;//合作者id(商户号
 
  private String appId;//应用id
 
  private String secretKey;//密钥
 
  private String notifyUrl;
  private String keyStore;// 支付密钥存放位置 文件是以.p12为后缀名字
  private String storePassword;
 
}

4、controller 逻辑代码

package com.example.emoticon.controller;
 
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.bean.RefundOrder;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.wx.api.WxPayConfigStorage;
import com.egzosn.pay.wx.api.WxPayService;
import com.egzosn.pay.wx.bean.WxTransactionType;
import com.example.emoticon.wechat.WechatPayConfig;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
 
/**
 * @ClassName WechatPayController
 * @Description 微信支付Controller
 * @Author WangJing
 * @Date 2021/3/23 4:35 下午
 * @Version V1.1.0
 */
@RestController
@RequestMapping("/wechatPay")
@Slf4j
public class WechatPayController {
 
 
  @Autowired
  WechatPayConfig wechatPayConfig;
 
  private PayService service = null;
 
  @PostConstruct
  public void init() {
    WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
    wxPayConfigStorage.setMchId(wechatPayConfig.getMchId()); // 合作者id(商户号
    wxPayConfigStorage.setAppid(wechatPayConfig.getAppId()); // 应用id
    wxPayConfigStorage.setSecretKey(wechatPayConfig.getSecretKey()); // 密钥
    wxPayConfigStorage.setNotifyUrl(wechatPayConfig.getNotifyUrl()); // 异步回调地址 http://域名:端口号/项目名/回调接口名称
    wxPayConfigStorage.setSignType(SignUtils.MD5.name());
    wxPayConfigStorage.setInputCharset("utf-8");
    // 支付api证书设置,退款必须 方式一
    HttpConfigStorage httpConfigStorage = new HttpConfigStorage();
    httpConfigStorage.setKeystore(wechatPayConfig.getKeyStore());// 支付密钥存放位置 文件是以.p12为后缀名字
    httpConfigStorage.setStorePassword(wechatPayConfig.getStorePassword());
    // 是否为证书地址
    httpConfigStorage.setPath(true);
    service = new WxPayService(wxPayConfigStorage, httpConfigStorage);
    // 请求连接池配置
    // 最大连接数
    httpConfigStorage.setMaxTotal(20);
    // 默认的每个路由的最大连接数
    httpConfigStorage.setDefaultMaxPerRoute(10);
    service.setRequestTemplateConfigStorage(httpConfigStorage);
  }
 
  @ApiOperation("返回订单信息")
  @RequestMapping(value = "weixinpay", method = RequestMethod.POST)
  public Map<String, Object> weixinpay(HttpServletRequest request) {
    //备注:这个可以获取预支付的订单,根据需要调用这个接口,可有前台向后台传递参数。然后后台根据需要进行处理。
    init();
    // 在这一步,可以传入一个订单Id,自行去搜索订单信息,并填写以下内容
    PayOrder payOrder = new PayOrder();// 这个就是支付成功后,在微信支付里面返回的信息(支付订单信息)
    // 一下内容需要分情况而定,自行填写。
    payOrder.setSubject("商品名称");
    payOrder.setBody("商品描述");
    payOrder.setAddition("附加信息");
    payOrder.setPrice(new BigDecimal(0.2));// 价格
    payOrder.setOutTradeNo("商户订单号");
    payOrder.setBankType("银行卡类型");
    payOrder.setDeviceInfo("设备信息");
    payOrder.setSpbillCreateIp("支付创建ip");// 可用IPUtils.getIpAddr(request)
    payOrder.setOpenid("用户微信openid");
    payOrder.setTransactionType(WxTransactionType.JSAPI);// 支付方式
    Map orderInfo = service.orderInfo(payOrder);// 返回创建的订单信息
    log.debug("获取预支付订单信息回参" + orderInfo.toString());
    // 可自行选择 ,是否将支付的流水插入到数据库中。返回的信息由:signType appId timeStamp nonceStr package sign
    return orderInfo;
  }
 
  /**
   * 这就是支付回调地址
   *
   * @param request
   * @return
   * @throws IOException
   */
  @ApiOperation("回调地址")
  @RequestMapping(value = "weixinpayBack")
  public String payBack(HttpServletRequest request) throws IOException {
    init();
    // 获取支付方返回的对应参数
    Map<String, Object> params = service.getParameter2Map(request.getParameterMap(), request.getInputStream());
    if (null == params) {
      log.debug("通知失败");
      return service.getPayOutMessage("failed", "通知失败").toMessage();
    }
    log.debug("微信公众号支付结果通知:" + params.toString());
    // 校验
    if (service.verify(params)) {
      // 这里处理业务逻辑 支付成功后的代码逻辑块
      // ......业务逻辑处理块........
      log.debug("通知支付成功");
      return service.getPayOutMessage("success", "支付成功").toMessage();
    }
    log.debug("通知支付失败");
    return service.getPayOutMessage("fail", "支付失败").toMessage();
  }
 
 
  @ApiOperation("微信公众号退款")
  @RequestMapping(value = "weixinAccRefund")
  public String weixinRefund() {
    init();
    RefundOrder refundOrder = new RefundOrder();//退款订单信息
    refundOrder.setRefundNo("退款单号,每次进行退款的单号,此处唯一");
    refundOrder.setTradeNo("支付平台订单号,交易号");
    refundOrder.setOutTradeNo("商户单号");
    refundOrder.setRefundAmount(new BigDecimal(0.2));//退款金额
    refundOrder.setTotalAmount(new BigDecimal(0.5));//订单总金额
    refundOrder.setOrderDate(new Date());//退款交易日期
    refundOrder.setDescription("退款说明");
    Map<String, Object> refund = service.refund(refundOrder);//微信退款
    //退款成功后,写其他的逻辑
    log.debug("微信公众号退款结果:=" + refund.toString());
 
    return "Success";
 
  }
}

到此这篇关于SpringBoot + 微信公众号JSAPI支付功能的实现的文章就介绍到这了,更多相关SpringBoot 微信公众号JSAPI支付内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 新手初学Java常见排序算法

    新手初学Java常见排序算法

    排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列
    2021-07-07
  • 基于sharding-jdbc的使用限制

    基于sharding-jdbc的使用限制

    这篇文章主要介绍了sharding-jdbc的使用限制,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • SpringBoot全局配置long转String丢失精度问题解决方案

    SpringBoot全局配置long转String丢失精度问题解决方案

    这篇文章主要介绍了SpringBoot全局配置long转String丢失精度问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • SpringCloud之Zuul服务网关详解

    SpringCloud之Zuul服务网关详解

    这篇文章主要介绍了SpringCloud之Zuul服务网关详解,服务网关是微服务架构中一个不可或缺的部分,通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制(鉴权)等功能,需要的朋友可以参考下
    2023-08-08
  • Java求解两个非负整数最大公约数算法【循环法与递归法】

    Java求解两个非负整数最大公约数算法【循环法与递归法】

    这篇文章主要介绍了Java求解两个非负整数最大公约数算法,结合实例形式分析了java求解最大公约数的实现方法,并附带了循环法与递归法算法思路,需要的朋友可以参考下
    2018-03-03
  • 一文探索Apache HttpClient如何设定超时时间

    一文探索Apache HttpClient如何设定超时时间

    Apache HttpClient是一个流行的Java库,用于发送HTTP请求,这篇文章主要为大家介绍了Apache HttpClient如何设定超时时间,感兴趣的小伙伴可以学习一下
    2023-10-10
  • 详解Java如何关闭线程以及线程池

    详解Java如何关闭线程以及线程池

    java如何正确关闭线程以及线程池是一个高频的面试题,本文将为大家详细介绍实现的方法与代码,感兴趣的小伙伴快跟随小编一起学习一下
    2022-04-04
  • 谈谈为JAXB和response设置编码,解决wechat4j中文乱码的问题

    谈谈为JAXB和response设置编码,解决wechat4j中文乱码的问题

    中文乱码是每个程序员都会遇到的问题,本篇文章主要介绍了谈谈为JAXB和response设置编码,解决wechat4j中文乱码的问题,具有一定的参考价值,有兴趣的可以了解一下。
    2016-12-12
  • Spring Boot最经典的20道面试题你都会了吗

    Spring Boot最经典的20道面试题你都会了吗

    Spring Boot是现代化的Java应用程序开发框架,具有高度的灵活性和可扩展性,下面这篇文章主要给大家介绍了关于Spring Boot最经典的20道面试题,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-06-06
  • SpringBoot开发实战系列之定时器

    SpringBoot开发实战系列之定时器

    定时任务我想诸位童鞋都不陌生,简而言之名为“设定定时闹钟做某件事情”,下面这篇文章主要给大家介绍了关于SpringBoot定时器的相关资料,需要的朋友可以参考下
    2021-08-08

最新评论