目录
2.3调用微信支付 get请求 统一配置(如果是看了前几篇的友友 前面有一样的 可不看)
第四弹 退款定时任务
对于特殊的退款订单 我们要有一些特殊处理
(这些要根据直接项目的情况按需来安排)
成果展示:
1.设计思路
2.代码实现
2.1数据库查询订单
/**
*根据退款状态查询 退款列表=>退款订单号(系统生成)
* @param returnStatus 退款状态
* @return List<TicketOrderReturn>
* @author zhangjunrong
* @date 2022/5/19 13:32
*/
@Override
public List<TicketOrderReturn> queryRefundByStatus(Integer returnStatus) {
QueryWrapper<TicketOrderReturn> wrapper = new QueryWrapper<>();
wrapper.select("pk_id","order_refund_sn")
.eq("return_status",returnStatus);
return list(wrapper);
}
2.2定时任务 检查退款订单
/**
*定时任务查询退款 订单 退款处理中=>最终结果为止 5分钟一次
* @param
* @return void
* @author zhangjunrong
* @date 2022/5/19 11:19
*/
@Async
@Scheduled(cron = "0 0/5 * * * ?")
public void orderTimeRefundCheck() {
//1.查询出所有退款处理中的退款表订单
List<TicketOrderReturn> returnList = iTicketOrderReturnService.queryRefundByStatus(WxPayStatusEnum.REF_PROCESSING.getCode());
if (ObjectUtil.isNotEmpty(returnList)){
log.info("定时任务=====退款订单核对==========开始=====处理订单状态为退款处理中订单==========");
//2.查询微信退款订单状态
returnList.stream()
.forEach(ticketOrderReturn -> {
//微信查退款单
JsonNode jsonNode = iToolWxConfigService.queryRefundOrder(iToolWxConfigService.find(), ticketOrderReturn.getOrderRefundSn());
if(ObjectUtil.isNotEmpty(jsonNode.get(WXOrderConstant.STATUS).textValue())){
//获取订单状态
String status = jsonNode.get(WXOrderConstant.STATUS).textValue();
//微信退款id(微信生成)
String refundId = jsonNode.get(WXOrderConstant.REFUND_ID).textValue();
Integer statusCode = WxPayStatusEnum.getCode(status);
log.info("微信回调状态"+statusCode);
log.info("定时任务:退款订单核对====微信订单状态状态======退款id{}======状态{}======微信退款id===={}=====",ticketOrderReturn.getPkId(),status,refundId);
//3.更新退款表状态 退款成功1 退款关闭2 退款异常3 退款处理中 0 插入微信退款id(微信生成)
//只有订单状态为最终态 入退款数据库数据库
if (statusCode !=SystemConstant.NUM_ZERO){
Boolean flag = iTicketOrderReturnService.updateStatusById(ticketOrderReturn.getPkId(), statusCode,refundId);
log.info("定时任务:退款订单核对====退款表更新=={}=====",flag);
//4.退款成功更新母单退款状态
if (statusCode ==SystemConstant.NUM_ONE){
Boolean orderStatus = iTicketOrderService.updateOrderStatus(jsonNode.get(WXOrderConstant.TRANSACTION_ID).textValue(), SystemConstant.NUM_FOUR);
log.info("定时任务:退款订单核对====母单更新=={}=====",orderStatus);
}
}
}
});
}
}
2.3调用微信支付 get请求 统一配置(如果是看了前几篇的友友 前面有一样的 可不看)
/**
*构造HttpClient 实现 微信申请接口 调用功能
* @param wxConfig 微信支付数据库参数
* @param verifier 微信验签器
* @return CloseableHttpClient
* @author zhangjunrong
* @date 2022/5/16 8:54
*/
public static CloseableHttpClient getHttpClient(ToolWxConfig wxConfig, Verifier verifier) {
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(wxConfig.getPrivateKey().getBytes(StandardCharsets.UTF_8)));
//通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(wxConfig.getMchId(), wxConfig.getMchSerialNo(), merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier));
return builder.build();
}
/**
* 调用微信支付 get请求 统一配置
* 要微信签名认证
* @param url
* @return String
* @author zhangjunrong
* @date 2022/5/9 20:39
*/
private String getHttpGet(ToolWxConfig wxConfig, String url) throws URISyntaxException, IOException {
//1.构造httpGet请求
URIBuilder uriBuilder = null;
uriBuilder = new URIBuilder(url);
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader(WechatPayHttpHeaders.ACCEPT, WechatPayHttpHeaders.APPLICATION_JSON);
//2.调起微信查询订单接口
CloseableHttpResponse response = WxPayUtil.getHttpClient(wxConfig, WxPayUtil.getVerifier(wxConfig)).execute(httpGet);
//3.返回结果信息
return EntityUtils.toString(response.getEntity());
}
2.4 微信查询退款订单
/**
*微信退款查询
*注意:提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,建议在提交退款申请后1分钟发起查询退款状态,一般来说零钱支付的退款5分钟内到账,银行卡支付的退款1-3个工作日到账。
* @param wxConfig
* @param refundNo 退款订单号 系统生成
* @return String
* @author zhangjunrong
* @date 2022/4/21 15:15
*/
@Override
public JsonNode queryRefundOrder(ToolWxConfig wxConfig, String refundNo) {
try {
//1.查单 微信接口 拼接url
String url = StrFormatter.format(WxApiType.QUERY_REFUND_ORDER.getValue(), refundNo);
//2.调用微信接口
String bodyAsString = getHttpGet(wxConfig, url);
log.info("退单查询信息============{}========" + bodyAsString);
//返回查单结果信息
if (ObjectUtil.isNotEmpty(bodyAsString)){
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readTree(bodyAsString);
}
} catch (Exception e) {
log.error("退单查单失败" + refundNo);
}
return null;
}
第五弹 账单下载
微信提供了对当天订单的订单下载功能(仅支持三个月内的账单下载申请)
下载账单API为通用接口,交易/资金账单都可以通过该接口获取到对应的账单。
注意:
• 账单文件的下载地址的有效时间为30s。
• 强烈建议商户将实际账单文件的哈希值和之前从接口获取到的哈希值进行比对,以确认数据的完整性。
• 该接口响应的信息请求头中不包含微信接口响应的签名值,因此需要跳过验签的流程。
•微信在次日9点启动生成前一天的对账单,建议商户10点后再获取。
效果展示:
1.申请账单VO
/**
* @Description
* @Author 小乌龟
* @Date 2022/5/20 16:08
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="前端=>下载微信账单", description="")
public class ToDownloadBillVO {
@ApiModelProperty(value = "账单日期")
@NotBlank
String billDate;
@ApiModelProperty(value = "账单类型:资金账单=>fundflowbill 交易账单=>tradebill")
@NotBlank
String billType;
}
2.get请求配置 无验证签名
/**
* 调用微信支付 get请求 统一配置
* 不用微信签名认证
* @param url
* @return String
* @author zhangjunrong
* @date 2022/5/9 20:39
*/
private String getHttpGetNoSign(ToolWxConfig wxConfig, String url) throws URISyntaxException, IOException {
//1.构造httpGet请求
URIBuilder uriBuilder = null;
uriBuilder = new URIBuilder(url);
HttpGet httpGet = new HttpGet(uriBuilder.build());
httpGet.addHeader(WechatPayHttpHeaders.ACCEPT, WechatPayHttpHeaders.APPLICATION_JSON);
//2.调起微信查询订单接口
CloseableHttpResponse response = WxPayUtil.getHttpClientNoSign(wxConfig, WxPayUtil.getVerifier(wxConfig)).execute(httpGet);
//3.返回结果信息
return EntityUtils.toString(response.getEntity());
}
public static CloseableHttpClient getHttpClientNoSign(ToolWxConfig wxConfig, Verifier verifier) {
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(wxConfig.getPrivateKey().getBytes(StandardCharsets.UTF_8)));
//通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(wxConfig.getMchId(), wxConfig.getMchSerialNo(), merchantPrivateKey)
.withValidator(new WechatPay2Validator(verifier))
.withValidator(response -> true);
return builder.build();
}
3.service
/**
*下载微信订单
* @param wxConfig 微信参数
* @param toDownloadBillVO
* @return String
* @author zhangjunrong
* @date 2022/5/20 17:11
*/
@Override
public String downloadBill(ToolWxConfig wxConfig, ToDownloadBillVO toDownloadBillVO){
log.info("申请账单接口调用====下载时间==={}======",toDownloadBillVO.getBillDate());
String url;
//1.选择下载账单的类型
if (WXOrderConstant.TRADE_BILL.equals(toDownloadBillVO.getBillType())){
url=StrFormatter.format(WxApiType.TRADE_BILLS.getValue(), toDownloadBillVO.getBillDate());
}else if (WXOrderConstant.FUND_FLOW_BILL.equals(toDownloadBillVO.getBillType())){
url=StrFormatter.format(WxApiType.FUND_FLOW_BILLS.getValue(), toDownloadBillVO.getBillDate());
}else {
throw new YqsException(MessageEnum.EXPIRE_ERR.getCode(),"不支持该账单生成");
}
try {
//2.get请求 去微信获取下载账单地址
String bodyAsString = getHttpGet(wxConfig,url);
log.info("返回结果===申请微信账单下载地址={}===========",bodyAsString);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(bodyAsString);
//账单地址
String downloadUrl = jsonNode.get(WXOrderConstant.DOWNLOAD_URL).textValue();
log.info("微信下载账单地址===账单类型======={}=====地址===={}",toDownloadBillVO.getBillType(),downloadUrl);
//调微信接口下载微信账单 注意:这个不用签名认证
return getHttpGetNoSign(wxConfig,downloadUrl);
} catch (Exception e) {
log.warn("微信账单请求下载地址失败================={}===",e);
}
return null;
}
到此 微信支付 的APP端全部功能也就完结了 感谢阅读🤭