1.准备工作
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
2.统一下单以及退款单
2.1统一下单
private Map<String, String> wxPay(String openId, BigDecimal consume, Orders orders, String notifyUrl) throws IOException, NoSuchAlgorithmException, SignatureException, InvalidKeyException {
//WxPayConfig.certPath 为证书存放路径,绝对路径。eg:/root/xx/xx/xx.pem
PrivateKey privateKey = WxUtils.create().getPrivateKey(WxPayConfig.certPath);
CloseableHttpClient client = WxUtils.create().client();
String param = ModelOrder.WxCreateOrder.create()
.setAmount(new ModelOrder.WxCreateOrder.Amount(consume.intValue(), "CNY"))
.setMchid(WxPayConfig.mchId)
.setDescription(orders.getContent())
.setNotify_url(WxPayConfig.notifyUrl + notifyUrl)
.setPayer(new ModelOrder.WxCreateOrder.Payer(openId))
.setOut_trade_no(orders.getCode())
.setAppid(WxPayConfig.appId).build();
logger.debug(param);
Map<String, String> headers = new HashMap<>(3);
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
//参考另一篇文章中的HttpUtils
String ret = HttpUtils.create().headers(headers).client(client).post(WxUtils.CREATE_ORDER, param);
ModelOrder.WxCreateOrderResult result = new Gson().fromJson(ret, new TypeToken<ModelOrder.WxCreateOrderResult>() {
}.getType());
String nonceStr = WxUtils.create().nonceStr(32).toUpperCase();
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
String packAge = "prepay_id=" + result.getPrepay_id();
String signType = "RSA";
String message = WxPayConfig.appId + "
" + timeStamp + "
" + nonceStr + "
" + packAge + "
";
logger.debug(message);
String sign = WxUtils.create().paySign(message, privateKey);
Map<String, String> data = new HashMap<>(6);
data.put("appId", WxPayConfig.appId);
data.put("timeStamp", timeStamp);
data.put("nonceStr", nonceStr);
data.put("package", packAge);
data.put("signType", signType);
data.put("paySign", sign);
return data;
}
2.2退款单
4.支付回调
/**
* 余额充值支付回调
*/
public NotifyResult invest(@RequestBody NotifyBody body) throws IOException, GeneralSecurityException {
logger.info("余额充值支付回调:" + body.toString());
if (StringUtils.equals("TRANSACTION.SUCCESS", body.getEvent_type())) {
NotifyBody.Resource resource = body.getResource();
String ret = new AesUtil(WxPayConfig.v3Secret.getBytes(StandardCharsets.UTF_8)).decryptToString(resource.getAssociated_data().getBytes(StandardCharsets.UTF_8), resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
NotifyResource result = new Gson().fromJson(ret, NotifyResource.class);
if (StringUtils.equals(result.getTrade_state(), "SUCCESS")) {
//支付回调 数据解析成功后,相关处理
}
logger.debug(ret);
}
return NotifyResult.create().success();
}
/**
* 退款回调
*/
@PostMapping("/refund")
public NotifyResult refund(@RequestBody NotifyBody body) throws IOException, GeneralSecurityException {
logger.info("退款回调:" + body.toString());
if (StringUtils.equals("REFUND.SUCCESS", body.getEvent_type())) {
NotifyBody.Resource resource = body.getResource();
String ret = new AesUtil(WxPayConfig.v3Secret.getBytes(StandardCharsets.UTF_8)).decryptToString(resource.getAssociated_data().getBytes(StandardCharsets.UTF_8), resource.getNonce().getBytes(StandardCharsets.UTF_8), resource.getCiphertext());
RefundResource result = new Gson().fromJson(ret, RefundResource.class);
if (StringUtils.equals(result.getRefund_status(), "SUCCESS")) {
//退款回调 数据解析成功后,相关处理
}
logger.debug(ret);
}
return NotifyResult.create().success();
}
5.接收回调参数类以及解析结果类 NotifyBody.java,RefundResource.java
public class NotifyResult {
private String code;
private String message;
public NotifyResult() {
}
public static NotifyResult create(){
return new NotifyResult();
}
public NotifyResult success(){
this.code = "SUCCESS";
this.message = "成功";
return this;
}
public NotifyResult fail(){
this.code = "FAIL";
this.message = "失败";
return this;
}
public NotifyResult fail(String message){
this.code = "FAIL";
this.message = message;
return this;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
8.文中缺少的一些类文件如下: