主要依赖
implementation 'com.github.wechatpay-apiv3:wechatpay-java:0.2.10'
微信支付证书自动更新配置
@Configuration
public class WxPayAutoCertificateConfig {
@Resource
private WxPayConfig wxPayConfig;
@Bean
public RSAAutoCertificateConfig rsaAutoCertificateConfig() {
RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
.merchantId(wxPayConfig.getMerchantId())
.privateKeyFromPath(WxPayAutoCertificateConfig.class.getClassLoader().getResource(wxPayConfig.getPrivateKey()).getPath()) //apiclient_key.pem文件地址
.merchantSerialNumber(wxPayConfig.getMerchantSerialNumber())
.apiV3Key(wxPayConfig.getApiV3Key())
.build();
return config;
}
}
java获取预支付参数
@RestController
@RequestMapping("/wx/pay")
public class WxPayController {
@Autowired
private WxPayAutoCertificateConfig wxPayAutoCertificateConfig;
@Autowired
private WxPayConfig wxPayConfig;
@PostMapping("/prepay")
public R wxPrepay(@RequestBody Order order) {
//请求微信支付相关配置
JsapiServiceExtension service =
new JsapiServiceExtension.Builder()
.config(wxPayAutoCertificateConfig.rsaAutoCertificateConfig())
.signType("RSA") // 默认为RSA
.build();
PrepayWithRequestPaymentResponse response = new PrepayWithRequestPaymentResponse();
try {
PrepayRequest request = new PrepayRequest();
request.setAppid(wxPayConfig.getAppId());
request.setMchid(wxPayConfig.getMerchantId());
request.setDescription(order.getDescription());
request.setOutTradeNo(order.getOrderNo());
request.setNotifyUrl(wxPayConfig.getPayNotifyUrl());
Amount amount = new Amount();
//微信支付金额单位是分
amount.setTotal(order.getAmount().multiply(new BigDecimal(100)).intValue());
request.setAmount(amount);
Payer payer = new Payer();
payer.setOpenid(wxPayConfig.getOpenid());
request.setPayer(payer);
logger.info("请求预支付下单,请求参数:{}", JSONObject.toJSONString(request));
// 调用预下单接口
response = service.prepayWithRequestPayment(request);
logger.info("订单【{}】发起预支付成功,返回信息:{}", order.getOrderNo(), response);
} catch (HttpException e) { // 发送HTTP请求失败
logger.error("微信下单发送HTTP请求失败,错误信息:{}", e.getHttpRequest());
return R.error("下单失败");
} catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
logger.error("微信下单服务状态错误,错误信息:{}", e.getErrorMessage());
return R.error("下单失败");
} catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
logger.error("服务返回成功,返回体类型不合法,或者解析返回体失败,错误信息:{}", e.getMessage());
return R.error("下单失败");
}
return R.data(response);
}
}
小程序通过requestPayment方法调用支付
const { appId, timeStamp, nonceStr, packageVal, paySign, signType } = response.data;
Taro.requestPayment({
timeStamp,
nonceStr,
package: packageVal,
signType,
paySign,
success(res) {
console.log('支付成功', res);
},
fail(res) {
console.error('支付失败', res);
}
});
最后还需要有回调接口接收支付结果
public synchronized R payNotify(HttpServletRequest request) throws IOException {
logger.info("------收到支付通知------");
// 构造 RequestParam
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(request.getHeader("Wechatpay-Serial"))
.nonce(request.getHeader("Wechatpay-Nonce"))
.signature(request.getHeader("Wechatpay-Signature"))
.timestamp(request.getHeader("Wechatpay-Timestamp"))
.signType(request.getHeader("Wechatpay-Signature-Type"))
.body(HttpServletUtils.getRequestBody(request))
.build();
NotificationParser parser = new NotificationParser(wxPayAutoCertificateConfig.rsaAutoCertificateConfig());
logger.info("验签参数:{}", requestParam);
Transaction transaction = parser.parse(requestParam, Transaction.class);
logger.info("验签成功!-支付回调结果:{}", transaction.toString());
return R.data(transaction);
}