1.把在微信商户界面申请的配置信息绑定到实体类中
/**
* @ClassName WxPayProperties
* @Description TODO
* @Author Administrator
* @Data 上午 01:42
* @Version 1.0
**/
@Configuration
@ConfigurationProperties(prefix = "wxpay")
@PropertySource(value = "classpath:application.yml")
public class WxPayProperties {
public String appId;
public String mchId;
public String apiKey;
public String signtype;
public String payNotify;
public String refundNotify;
public String certName;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getSigntype() {
return signtype;
}
public void setSigntype(String signtype) {
this.signtype = signtype;
}
public String getPayNotify() {
return payNotify;
}
public void setPayNotify(String payNotify) {
this.payNotify = payNotify;
}
public String getRefundNotify() {
return refundNotify;
}
public void setRefundNotify(String refundNotify) {
this.refundNotify = refundNotify;
}
public String getCertName() {
return certName;
}
public void setCertName(String certName) {
this.certName = certName;
}
}
2.参照微信文档的案例,加载配置;注意点如下
a.文档中是实现WXPayConfig ,实际上是继承WXPayConfig 抽象类
b.WXPayConfig 改写其中的属性为public,否则无法重写
c.使用@PostConstruct注解来加载证书文件,不要用文档中在构造方法中加载;因为工程继承了spring,使用构造方法加载的时候,绑定配置信息的实体类还未加载(类加载顺序,先构造方法,再加载普通成员变量);
d.借鉴网上的方法,重写getWXPayDomain()方法,否则无法正确调用接口
/**
* @ClassName SteamCatWxPayConfig
* @Description TODO
* @Author Administrator
* @Data 上午 01:06
* @Version 1.0
**/
@Configuration
public class SteamCatWxPayConfig extends WXPayConfig {
private byte[] certData;
@Autowired
WxPayProperties wxPayProperties;
public SteamCatWxPayConfig() {
}
@PostConstruct
public void initCertData() throws Exception {
ApplicationHome applicationHome = new ApplicationHome(SteamCatWxPayConfig.class);
File file = applicationHome.getSource();
file = new File(file, wxPayProperties.getCertName());
InputStream certStream = FileUtils.openInputStream(file);
this.certData = new byte[(int) file.length()];
certStream.read(this.certData);
certStream.close();
}
@Override
public String getAppID() {
return wxPayProperties.getAppId();
}
@Override
public String getMchID() {
return wxPayProperties.getMchId();
}
@Override
public String getKey() {
return wxPayProperties.getApiKey();
}
@Override
public InputStream getCertStream() {
return new ByteArrayInputStream(this.certData);
}
@Override
public IWXPayDomain getWXPayDomain() {
IWXPayDomain iwxPayDomain = new IWXPayDomain() {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
}
};
return iwxPayDomain;
}
}
3.业务逻辑调用统一下单接口
/**
* @ClassName WxPayService
* @Description TODO
* @Author Administrator
* @Data 上午 02:07
* @Version 1.0
**/
@Service
public class WxPayServiceImpl implements IWxPayService {
@Autowired
SteamCatWxPayConfig steamCatWxPayConfig;
public String callWxPayApi() throws Exception {
WXPay wxPay = new WXPay(steamCatWxPayConfig);
Map<String, String> bodyMap = new HashMap<>();
bodyMap.put("body", "qq会员充值");
bodyMap.put("out_trade_no", "2020090910595900000019");
bodyMap.put("device_info", "");
bodyMap.put("fee_type", "CNY");
bodyMap.put("total_fee", "1");
bodyMap.put("spbill_create_ip", "81.70.31.60");
bodyMap.put("notify_url", "http://www.baidu.com"); // 此处回调接口
bodyMap.put("trade_type", "NATIVE"); // 此处指定为扫码支付
bodyMap.put("product_id", "12");
try {
Map<String, String> resp = wxPay.unifiedOrder(bodyMap);
System.out.println(resp);
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
}