根据微信sdk中的WXPayConfig类生成自己的配置类
public class WXPayConfigUtil extends WXPayConfig { // 继承sdk中的WXPayConfig
Logger logger = Logger.getLogger(this.getClass());
private byte[] certData;
@Autowired
WXPayProp wxpayProp; // 微信支付配置信息appid,muchid,回调地址等
public WXPayConfigUtil() throws IOException { // 证书在退款的时候需要用到,这边在构造时读取证书
InputStream certStream = this.getClass().getResourceAsStream("/apiclient_cert.p12");//证书路径
this.certData = IOUtils.toByteArray(certStream);
certStream.close();
}
public String getAppID() {
return wxpayProp.getAppid();
};
public String getMchID() {
return wxpayProp.getMchid();
};
public String getKey() {
return wxpayProp.getKey();
};
protected InputStream getCertStream() {
return new ByteArrayInputStream(this.certData);
};
/**
* 获取WXPayDomain, 用于多域名容灾自动切换
* @return
*/
protected IWXPayDomain getWXPayDomain() {
IWXPayDomain WXPayDomain = new IWXPayDomain(){
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
public DomainInfo getDomain(WXPayConfig config) {
return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
}
};
return WXPayDomain;
};
/**
* HTTP(S) 连接超时时间,单位毫秒
*
* @return
*/
public int getHttpConnectTimeoutMs() {
return 6 * 1000;
}
/**
* HTTP(S) 读数据超时时间,单位毫秒
*
* @return
*/
public int getHttpReadTimeoutMs() {
return 8*1000;
}
}
注入自己的配置类
@Bean
public WXPayConfigUtil getWXPayConfigUtil() throws IOException {
WXPayConfigUtil config = new WXPayConfigUtil();
return config;
}
@Bean(name="WXPay") // 这里实例化用自己的配置类
public WXPay getWXPay() throws Exception {
WXPayConfigUtil config = getWXPayConfigUtil();
WXPay wxpay = new WXPay(config);
return wxpay;
}
微信统一下单
public class WXPayTask implements IWXPayTask {
Logger logger = Logger.getLogger(this.getClass());
@Autowired
WXPayProp wxpayProp; // 配置信息
@Autowired
WXPayConfigUtil config;
@Autowired
WXPay wxpay;
@Override
public Msg<Map<String, String>> dounifiedOrder(HttpServletRequest request) {
Msg<Map<String, String>> rmsg = new Msg<>();
try {
Map<String, String> data = new HashMap<>();
data.put("appid", config.getAppID()); // 微信的配置
data.put("mch_id", config.getMchID());
data.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串
data.put("body", "订单信息");
data.put("out_trade_no", "orderCode"); // 自己的订单code唯一
data.put("total_fee", String.valueOf(orderPrice.multiply(new BigDecimal(100)).intValue()));//单位 分
data.put("spbill_create_ip",‘0.0.0.0’); // 下单IP
data.put("notify_url", wxpayProp.getNotifyUrl()); // 回调地址
data.put("trade_type", wxpayProp.getTradeType()); // APP
String sign = WXPayUtil.generateSignature(data, config.getKey(), SignType.HMACSHA256); // 签名生成sign
data.put("sign", sign);
logger.info("微信支付请求参数request:" + data.toString());
Map<String, String> response = wxpay.unifiedOrder(data);
logger.info("微信支付响应response:" + response.toString());
String returnCode = response.get("return_code");
String returnMsg = response.get("return_msg");
if (WXPayConstants.SUCCESS.equals(returnCode)) {
String resultCode = response.get("result_code");
if (WXPayConstants.SUCCESS.equals(resultCode)) {//resultCode 为SUCCESS,才会返回prepay_id和trade_type
// 返回prepay_id后需要重新生成签名sign
Long timestamp = WXPayUtil.getCurrentTimestamp();
Map<String,String> resultMap = Maps.newHashMap();
resultMap.put("appid", response.get("appid"));
resultMap.put("partnerid", response.get("mch_id"));
resultMap.put("prepayid", response.get("prepay_id"));
resultMap.put("package", "Sign=WXPay"); // APP支付 固定
resultMap.put("noncestr", response.get("nonce_str")); // 需要用返回的随机字符串
resultMap.put("timestamp", String.valueOf(timestamp));
String resultSign = WXPayUtil.generateSignature(resultMap, config.getKey(), SignType.HMACSHA256);
resultMap.put("sign", resultSign); // 返回时没有signType 按自己原先的加密方式签名
rmsg.setValue(resultMap).setSuccess(true);
return rmsg;
} else {
//此时返回没有预付订单的数据
String errCode = response.get("err_code");
String errCodeDes = response.get("err_code_des");
logger.error("微信支付生成预支付订单失败,失败错误码 ==" + errCode + ",错误描述 ==" + errCodeDes);
rmsg.setError(ResultCode.TASK_FAILED.name());
return rmsg;
}
} else {
logger.error("调用接口失败:" + returnMsg);
rmsg.setError(ResultCode.INTERFACE_REQUEST_TIMEOUT.name());
return rmsg;
}
} catch (Exception e) {
logger.error("", e);
}
return rmsg;
}
}
回调处理
@Override
public String wxpayNotify(String notifyData) {
String resultXml = "";
Map<String, String> resultMap = Maps.newHashMap();
Map<String, String> notifyMap = null;
try {
notifyMap = WXPayUtil.xmlToMap(notifyData);
logger.info("微信支付异步回调参数======" + notifyMap.toString());
// 返回数据中没有signType,这里都采用的是 SHA256
notifyMap.put(WXPayConstants.FIELD_SIGN_TYPE, WXPayConstants.HMACSHA256);
if (wxpay.isPayResultNotifySignatureValid(notifyMap)) { // 验签
if (WXPayConstants.SUCCESS.equals(notifyMap.get("return_code"))
&& WXPayConstants.SUCCESS.equals(notifyMap.get("result_code"))) {
String outTradeNo = notifyMap.get("out_trade_no");//商户订单号
String totalFee = notifyMap.get("total_fee");//金额
String appId = notifyMap.get("appid");
String mchId = notifyMap.get("mch_id");
if (totalFee.equals(String.valueOf(orderPrice))
&& appId.equals(wxpayProp.getAppid()) && mchId.equals(wxpayProp.getMchid())) { // 验证订单和金额 if () { // 判断订单状态 保证幂等性,如果已经处理过直接跳出
// 执行业务数据,修改订单状态
} else {
logger.info("订单已经处理,不在待支付状态");
resultMap.put("return_code", WXPayConstants.SUCCESS);
resultMap.put("return_msg", "OK");
}
} else {
logger.error("订单号、金额等验证未通过");
resultMap.put("return_code", WXPayConstants.FAIL);
resultMap.put("return_msg", "订单号、金额等验证未通过");
}
} else {
logger.error("微信支付回调通知返回失败=return_msg:" + notifyMap.get("return_msg"));
resultMap.put("return_code", WXPayConstants.FAIL);
resultMap.put("return_msg", "微信支付回调通知返回失败");
}
} else {
logger.error("微信支付回调通知验签失败");
resultMap.put("return_code", WXPayConstants.FAIL);
resultMap.put("return_msg", "签名错误");
}
} catch (Exception e) {
logger.error("", e);
resultMap.put("return_code", WXPayConstants.FAIL);
resultMap.put("return_msg", "微信支付回调通知失败");
}
try {
resultXml = WXPayUtil.mapToXml(resultMap);
} catch (Exception e) {
logger.error("", e);
}
return resultXml;
}