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";
}
}
注:以上内容仅提供参考和交流,请勿用于商业用途,如有侵权联系本人删除!