- 引入架包
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-WxPay</artifactId>
<version>${ijapy.version}</version>
</dependency>
配置类
package com.joolun.web.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* <p>微信配置 Bean</p>
*
* @author yuhaiguang
*/
@Component
@PropertySource("classpath:/wxpay.properties")
@ConfigurationProperties(prefix = "wxpay")
public class WxPayBean {
private String appId;
private String appSecret;
private String mchId;
private String partnerKey;
private String certPath;
private String domain;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getPartnerKey() {
return partnerKey;
}
public void setPartnerKey(String partnerKey) {
this.partnerKey = partnerKey;
}
public String getCertPath() {
return certPath;
}
public void setCertPath(String certPath) {
this.certPath = certPath;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "WxPayBean [appId=" + appId + ", appSecret=" + appSecret + ", mchId=" + mchId + ", partnerKey="
+ partnerKey + ", certPath=" + certPath + ", domain=" + domain + "]";
}
}
controller
AbstractWxPayApiController
package com.joolun.web.controller.weixin;
import com.ijpay.wxpay.WxPayApiConfig;
public abstract class AbstractWxPayApiController {
public abstract WxPayApiConfig getApiConfig();
}
接口:
package com.joolun.web.controller.weixin;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.api.R;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.joolun.common.core.domain.AjaxResult;
import com.joolun.web.config.WxPayBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@RestController
@RequestMapping("/wxPay")
public class WxPayController extends AbstractWxPayApiController{
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private WxPayBean wxPayBean;
private String notifyUrl;
private String refundNotifyUrl;
@Override
public WxPayApiConfig getApiConfig() {
WxPayApiConfig apiConfig;
try {
apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
} catch (Exception e) {
apiConfig = WxPayApiConfig.builder()
.appId(wxPayBean.getAppId())
.mchId(wxPayBean.getMchId())
.partnerKey(wxPayBean.getPartnerKey())
.certPath(wxPayBean.getCertPath())
.domain(wxPayBean.getDomain())
.build();
}
notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
return apiConfig;
}
@RequestMapping(value = "/webPay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public R webPay(HttpServletRequest request) {
// openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
String openId = (String) request.getSession().getAttribute("openId");
if (openId == null) {
openId = "oQe4A6_acTpnPFTuAaxKq0Ss-yMo";
}
if (StrUtil.isEmpty(openId)) {
return R.failed("openId is null");
}
String ip = IpKit.getRealIp(request);
if (StrUtil.isEmpty(ip)) {
ip = "127.0.0.1";
}
WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("微信网页内测试")
.attach("产品说名")
.out_trade_no(WxPayKit.generateStr())
.total_fee("1")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.JSAPI.getTradeType())
.openid(openId)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.pushOrder(false, params);
log.info(xmlResult);
Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
String returnCode = resultMap.get("return_code");
String returnMsg = resultMap.get("return_msg");
if (!WxPayKit.codeIsOk(returnCode)) {
return R.failed(returnMsg);
}
String resultCode = resultMap.get("result_code");
if (!WxPayKit.codeIsOk(resultCode)) {
return R.failed(returnMsg);
}
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
String prepayId = resultMap.get("prepay_id");
Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wxPayApiConfig.getAppId(),
wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String jsonStr = JSON.toJSONString(packageParams);
return R.failed(jsonStr);
}
}
配置初始化拦截器
package com.joolun.web.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.joolun.web.interceptor.WxPayInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class IJPayConfigurer extends WebMvcConfigurationSupport {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//registry.addInterceptor(new AliPayInterceptor()).addPathPatterns("/aliPay/**");
registry.addInterceptor(new WxPayInterceptor()).addPathPatterns("/wxPay/**");
super.addInterceptors(registry);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 将所有/static/** 访问都映射到classpath:/static/ 目录下
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(
SerializerFeature.WriteMapNullValue, // 保留map空的字段
SerializerFeature.WriteNullStringAsEmpty, // 将String类型的null转成""
SerializerFeature.WriteNullNumberAsZero, // 将Number类型的null转成0
SerializerFeature.WriteNullListAsEmpty, // 将List类型的null转成[]
SerializerFeature.WriteNullBooleanAsFalse, // 将Boolean类型的null转成false
SerializerFeature.DisableCircularReferenceDetect);// 避免循环引用
converter.setFastJsonConfig(config);
converter.setDefaultCharset(Charset.forName("UTF-8"));
List<MediaType> mediaTypeList = new ArrayList<>();
// 解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
mediaTypeList.add(MediaType.APPLICATION_JSON);
converter.setSupportedMediaTypes(mediaTypeList);
converters.add(converter);
converters.add(responseBodyConverter());
}
@Bean
public HttpMessageConverter<String> responseBodyConverter() {
return new StringHttpMessageConverter(Charset.forName("UTF-8"));
}
}
package com.joolun.web.interceptor;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.joolun.web.controller.weixin.AbstractWxPayApiController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <p>微信支付拦截器</p>
*
* @author yuhaiguang
*/
public class WxPayInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) {
if (HandlerMethod.class.equals(handler.getClass())) {
HandlerMethod method = (HandlerMethod) handler;
Object controller = method.getBean();
if (!(controller instanceof AbstractWxPayApiController)) {
throw new RuntimeException("控制器需要继承 AbstractWxPayApiController");
}
WxPayApiConfigKit.setThreadLocalWxPayApiConfig(((AbstractWxPayApiController) controller).getApiConfig());
return true;
}
return false;
}
}
源码:
https://gitee.com/champion-myth/wx-shop/tree/dev-wx-pay/