源码资料在第六章最后(本文最后有链接)
一 商户定时查询本地订单
1.1、后端定义商户查单接口
支付成功后,商户则查询本地数据库,订单是否支付成功
OrderInfoController.java
/**
* 查询本地订单状态
*/
@ApiOperation("查询本地订单状态")
@GetMapping("/query-order-status/{orderNo}")
public R queryOrderStatus(@PathVariable String orderNo) {
String orderStatus = orderInfoService.getOrderStatus(orderNo);
if (OrderStatus.SUCCESS.getType().equals(orderStatus)) {//支付成功
return R.ok();
}
return R.ok().setCode(101).setMessage("支付中...");
}
1.2、前端定时轮询查单
在二维码展示页面,前端定时轮询查询订单是否已支付,如果支付成功则跳转到订单页面
(1)定义定时器(前端vue)
//启动定时器
this.timer = setInterval(() => {
//查询订单是否支付成功
this.queryOrderStatus()
}, 3000)
(2)查询订单
// 查询订单状态
queryOrderStatus() {
orderInfoApi.queryOrderStatus(this.orderNo).then(response => {
console.log('查询订单状态:' + response.code)
// 支付成功后的页面跳转
if (response.code === 0) {
console.log('清除定时器')
clearInterval(this.timer)
// 三秒后跳转到订单列表
setTimeout(() => {
this.$router.push({ path: '/success' })
}, 3000)
}
})
}
二 用户取消订单API
实现用户主动取消订单的功能
2.1、定义取消订单接口
WxPayController中添加接口方法
/**
* 用户取消订单
* @param orderNo
* @return
* @throws Exception
*/
@ApiOperation("用户取消订单")
@PostMapping("/cancel/{orderNo}")
public R cancel(@PathVariable String orderNo) throws Exception {
log.info("取消订单");
wxPayService.cancelOrder(orderNo);
return R.ok().setMessage("订单已取消");
}
2.2 WxPayService
接口:
void cancelOrder(String orderNo) throws Exception;
实现:
/**
* 用户取消订单
* @param orderNo
*/
@Override
public void cancelOrder(String orderNo) throws Exception {
//调用微信支付的关单接口
this.closeOrder(orderNo);
//更新商户端的订单状态
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.CANCEL);
}
关单方法
/**
* 关单接口的调用
* @param orderNo
*/
private void closeOrder(String orderNo) throws Exception {
log.info("关单接口的调用,订单号 ===> {}", orderNo);
//创建远程请求对象
String url = String.format(WxApiType.CLOSE_ORDER_BY_NO.getType(), orderNo);
url = wxPayConfig.getDomain().concat(url);
HttpPost httpPost = new HttpPost(url);
//组装json请求体
Gson gson = new Gson();
Map<String, String> paramsMap = new HashMap<>();
paramsMap.put("mchid", wxPayConfig.getMchId());
String jsonParams = gson.toJson(paramsMap);
log.info("请求参数 ===> {}", jsonParams);
//将请求参数设置到请求对象中
StringEntity entity = new StringEntity(jsonParams,"utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = wxPayClient.execute(httpPost);
try {
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
if (statusCode == 200) { //处理成功
log.info("成功200");
} else if (statusCode == 204) { //处理成功,无返回Body
log.info("成功204");
} else {
log.info("Native下单失败,响应码 = " + statusCode);
throw new IOException("request failed");
}
} finally {
response.close();
}
}
三 微信支付查单API
3.1 查单接口的调用
商户后台未收到异步支付结果通知时,商户应该主动调用《微信支付查单接口》,同步订单状态。
(1)WxPayController
/**
* 查询订单
* @param orderNo
* @return
* @throws Exception
*/
@ApiOperation("查询订单:测试订单状态用")
@GetMapping("/query/{orderNo}")
public R queryOrder(@PathVariable String orderNo) throws Exception {
log.info("查询订单");
String result = wxPayService.queryOrder(orderNo);
return R.ok().setMessage("查询成功").data("result", result);
}
(2)WxPayService
接口:
String queryOrder(String orderNo) throws Exception;
实现:
@Override
public String queryOrder(String orderNo) throws Exception {
log.info("查单接口调用 ===> {}", orderNo);
String url = String.format(WxApiType.ORDER_QUERY_BY_NO.getType(), orderNo);
url = wxPayConfig.getDomain().concat(url).concat("?mchid=").concat(wxPayConfig.getMchId());
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = wxPayClient.execute(httpGet);
try {
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
if (statusCode == 200) { //处理成功
log.info("成功, 返回结果 = " + bodyAsString);
} else if (statusCode == 204) { //处理成功,无返回Body
log.info("成功");
} else {
log.info("查单接口调用,响应码 = " + statusCode+ ",返回结果 = " + bodyAsString);
throw new IOException("request failed");
}
return bodyAsString;
} finally {
response.close();
}
}
3.2 集成Spring Task
Spring 3.0后提供Spring Task实现任务调度
(1)启动类添加注解
statistics启动类添加注解
@EnableScheduling
(2)测试定时任务
创建 task 包,创建 WxPayTask.java
package com.atguigu.paymentdemo.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class WxPayTask {
/**
* 测试
* (cron="秒 分 时 日 月 周")
* *:每隔一秒执行
* 0/3:从第0秒开始,每隔3秒执行一次
* 1-3: 从第1秒开始执行,到第3秒结束执行
* 1,2,3:第1、2、3秒执行
* ?:不指定,若指定日期,则不指定周,反之同理
*/
@Scheduled(cron="0/3 * * * * ?")
public void task1() {
log.info("task1 执行");
}
}
3.3 定时查找超时订单
(1)WxPayTask
@Resource
private OrderInfoService orderInfoService;
@Resource
private WxPayService wxPayService;
/**
* 从第0秒开始每隔30秒执行1次,查询创建超过5分钟,并且未支付的订单
*/
@Scheduled(cron = "0/30 * * * * ?")
public void orderConfirm() throws Exception {
log.info("orderConfirm 被执行......");
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(1);
for (OrderInfo orderInfo : orderInfoList) {
String orderNo = orderInfo.getOrderNo();
log.warn("超时订单 ===> {}", orderNo);
//核实订单状态:调用微信支付查单接口
wxPayService.checkOrderStatus(orderNo);
}
}
(2)OrderInfoService
接口
List<OrderInfo> getNoPayOrderByDuration(int minutes);
实现
/**
* 查询创建超过minutes分钟并且未支付的订单
* @param minutes
* @return
*/
@Override
public List<OrderInfo> getNoPayOrderByDuration(int minutes) {
Instant instant = Instant.now().minus(Duration.ofMinutes(minutes));
QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
queryWrapper.le("create_time", instant);
List<OrderInfo> orderInfoList = baseMapper.selectList(queryWrapper);
return orderInfoList;
}
3.4 处理超时订单
WxPayService
核实订单状态
接口:
void checkOrderStatus(String orderNo) throws Exception;
实现
/**
* 根据订单号查询微信支付查单接口,核实订单状态
* 如果订单已支付,则更新商户端订单状态,并记录支付日志
* 如果订单未支付,则调用关单接口关闭订单,并更新商户端订单状态
* @param orderNo
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void checkOrderStatus(String orderNo) throws Exception {
log.warn("根据订单号核实订单状态 ===> {}", orderNo);
//调用微信支付查单接口
String result = this.queryOrder(orderNo);
Gson gson = new Gson();
Map<String, String> resultMap = gson.fromJson(result, HashMap.class);
//获取微信支付端的订单状态
String tradeState = resultMap.get("trade_state");
//判断订单状态
if(WxTradeState.SUCCESS.getType().equals(tradeState)){
log.warn("核实订单已支付 ===> {}", orderNo);
//如果确认订单已支付则更新本地订单状态
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.SUCCESS);
//记录支付日志
paymentInfoService.createPaymentInfo(result);
}
if(WxTradeState.NOTPAY.getType().equals(tradeState)){
log.warn("核实订单未支付 ===> {}", orderNo);
//如果订单未支付,则调用关单接口
this.closeOrder(orderNo);
//更新本地订单状态
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.CLOSED);
}
}
四 申请退款API
4.1 创建退款单
文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_9.shtml
(1)根据订单号查询订单
OrderInfoService
接口:
OrderInfo getOrderByOrderNo(String orderNo);
实现:
/**
* 根据订单号获取订单
* @param orderNo
* @return
*/
@Override
public OrderInfo getOrderByOrderNo(String orderNo) {
QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_no", orderNo);
OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
return orderInfo;
}
(2)创建退款单记录
RefundsInfoService
接口:
RefundInfo createRefundByOrderNo(String orderNo, String reason);
实现
/**
* 根据订单号创建退款订单
* @param orderNo
* @return
*/
@Override
public RefundInfo createRefundByOrderNo(String orderNo, String reason) {
//根据订单号获取订单信息
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
//根据订单号生成退款订单
RefundInfo refundInfo = new RefundInfo();
refundInfo.setOrderNo(orderNo);//订单编号
refundInfo.setRefundNo(OrderNoUtils.getRefundNo());//退款单编号
refundInfo.setTotalFee(orderInfo.getTotalFee());//原订单金额(分)
refundInfo.setRefund(orderInfo.getTotalFee());//退款金额(分)
refundInfo.setReason(reason);//退款原因
//保存退款订单
baseMapper.insert(refundInfo);
return refundInfo;
}
4.2 更新退款单
RefundInfoService
接口:
void updateRefund(String content);
实现:
/**
* 记录退款记录
* @param content
*/
@Override
public void updateRefund(String content) {
//将json字符串转换成Map
Gson gson = new Gson();
Map<String, String> resultMap = gson.fromJson(content, HashMap.class);
//根据退款单编号修改退款单
QueryWrapper<RefundInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("refund_no", resultMap.get("out_refund_no"));
//设置要修改的字段
RefundInfo refundInfo = new RefundInfo();
refundInfo.setRefundId(resultMap.get("refund_id"));//微信支付退款单号
//查询退款和申请退款中的返回参数
if(resultMap.get("status") != null){
refundInfo.setRefundStatus(resultMap.get("status"));//退款状态
refundInfo.setContentReturn(content);//将全部响应结果存入数据库的content字段
}
//退款回调中的回调参数
if(resultMap.get("refund_status") != null){
refundInfo.setRefundStatus(resultMap.get("refund_status"));//退款状态
refundInfo.setContentNotify(content);//将全部响应结果存入数据库的content字段
}
//更新退款单
baseMapper.update(refundInfo, queryWrapper);
}
4.3 申请退款
(1)WxPayController
@ApiOperation("申请退款")
@PostMapping("/refunds/{orderNo}/{reason}")
public R refunds(@PathVariable String orderNo, @PathVariable String reason) throws Exception {
log.info("申请退款");
wxPayService.refund(orderNo, reason);
return R.ok();
}
(2)WxPayService
接口
void refund(String orderNo, String reason) throws Exception;
实现
/**
* 退款
* @param orderNo
* @param reason
* @throws IOException
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void refund(String orderNo, String reason) throws Exception {
log.info("创建退款单记录");
//根据订单编号创建退款单
RefundInfo refundsInfo = refundsInfoService.createRefundByOrderNo(orderNo, reason);
log.info("调用退款API");
//调用统一下单API
String url = wxPayConfig.getDomain().concat(WxApiType.DOMESTIC_REFUNDS.getType());
HttpPost httpPost = new HttpPost(url);
// 请求body参数
Gson gson = new Gson();
Map paramsMap = new HashMap();
paramsMap.put("out_trade_no", orderNo);//订单编号
paramsMap.put("out_refund_no", refundsInfo.getRefundNo());//退款单编号
paramsMap.put("reason",reason);//退款原因
paramsMap.put("notify_url", wxPayConfig.getNotifyDomain().concat(WxNotifyType.REFUND_NOTIFY.getType()));//退款通知地址
Map amountMap = new HashMap();
amountMap.put("refund", refundsInfo.getRefund());//退款金额
amountMap.put("total", refundsInfo.getTotalFee());//原订单金额
amountMap.put("currency", "CNY");//退款币种
paramsMap.put("amount", amountMap);
//将参数转换成json字符串
String jsonParams = gson.toJson(paramsMap);
log.info("请求参数 ===> {}" + jsonParams);
StringEntity entity = new StringEntity(jsonParams,"utf-8");
entity.setContentType("application/json");//设置请求报文格式
httpPost.setEntity(entity);//将请求报文放入请求对象
httpPost.setHeader("Accept", "application/json");//设置响应报文格式
//完成签名并执行请求,并完成验签
CloseableHttpResponse response = wxPayClient.execute(httpPost);
try {
//解析响应结果
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 退款返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("退款异常, 响应码 = " + statusCode+ ", 退款返回结果 = " + bodyAsString);
}
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_PROCESSING);
//更新退款单
refundsInfoService.updateRefund(bodyAsString);
} finally {
response.close();
}
}
五 查询退款API
文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_10.shtml
5.1 查单接口的调用
(1)WxPayController
/**
* 查询退款
* @param refundNo
* @return
* @throws Exception
*/
@ApiOperation("查询退款:测试用")
@GetMapping("/query-refund/{refundNo}")
public R queryRefund(@PathVariable String refundNo) throws Exception {
log.info("查询退款");
String result = wxPayService.queryRefund(refundNo);
return R.ok().setMessage("查询成功").data("result", result);
}
(2)WxPayService
接口
String queryRefund(String orderNo) throws Exception;
实现
/**
* 查询退款接口调用
* @param refundNo
* @return
*/
@Override
public String queryRefund(String refundNo) throws Exception {
log.info("查询退款接口调用 ===> {}", refundNo);
String url = String.format(WxApiType.DOMESTIC_REFUNDS_QUERY.getType(), refundNo);
url = wxPayConfig.getDomain().concat(url);
//创建远程Get 请求对象
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
//完成签名并执行请求
CloseableHttpResponse response = wxPayClient.execute(httpGet);
try {
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 查询退款返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("查询退款异常, 响应码 = " + statusCode+ ", 查询退款返回结果 = " + bodyAsString);
}
return bodyAsString;
} finally {
response.close();
}
}
5.2 定时查找退款中的订单
(1)WxPayTask
/**
* 从第0秒开始每隔30秒执行1次,查询创建超过5分钟,并且未成功的退款单
*/
@Scheduled(cron = "0/30 * * * * ?")
public void refundConfirm() throws Exception {
log.info("refundConfirm 被执行......");
//找出申请退款超过5分钟并且未成功的退款单
List<RefundInfo> refundInfoList = refundInfoService.getNoRefundOrderByDuration(1);
for (RefundInfo refundInfo : refundInfoList) {
String refundNo = refundInfo.getRefundNo();
log.warn("超时未退款的退款单号 ===> {}", refundNo);
//核实订单状态:调用微信支付查询退款接口
wxPayService.checkRefundStatus(refundNo);
}
}
(2)RefundInfoService
接口
List<RefundInfo> getNoRefundOrderByDuration(int minutes);
实现
/**
* 找出申请退款超过minutes分钟并且未成功的退款单
* @param minutes
* @return
*/
@Override
public List<RefundInfo> getNoRefundOrderByDuration(int minutes) {
//minutes分钟之前的时间
Instant instant = Instant.now().minus(Duration.ofMinutes(minutes));
QueryWrapper<RefundInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("refund_status", WxRefundStatus.PROCESSING.getType());
queryWrapper.le("create_time", instant);
List<RefundInfo> refundInfoList = baseMapper.selectList(queryWrapper);
return refundInfoList;
}
5.3 处理超时未退款订单
WxPayService
核实订单状态
接口:
void checkRefundStatus(String refundNo);
实现
/**
* 根据退款单号核实退款单状态
* @param refundNo
* @return
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void checkRefundStatus(String refundNo) throws Exception {
log.warn("根据退款单号核实退款单状态 ===> {}", refundNo);
//调用查询退款单接口
String result = this.queryRefund(refundNo);
//组装json请求体字符串
Gson gson = new Gson();
Map<String, String> resultMap = gson.fromJson(result, HashMap.class);
//获取微信支付端退款状态
String status = resultMap.get("status");
String orderNo = resultMap.get("out_trade_no");
if (WxRefundStatus.SUCCESS.getType().equals(status)) {
log.warn("核实订单已退款成功 ===> {}", refundNo);
//如果确认退款成功,则更新订单状态
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_SUCCESS);
//更新退款单
refundsInfoService.updateRefund(result);
}
if (WxRefundStatus.ABNORMAL.getType().equals(status)) {
log.warn("核实订单退款异常 ===> {}", refundNo);
//如果确认退款成功,则更新订单状态
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_ABNORMAL);
//更新退款单
refundsInfoService.updateRefund(result);
}
}
六 退款结果通知API
文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_11.shtml
6.1 接收退款通知
WxPayController
/**
* 退款结果通知
* 退款状态改变后,微信会把相关退款结果发送给商户。
*/
@ApiOperation("退款结果通知")
@PostMapping("/refunds/notify")
public String refundsNotify(HttpServletRequest request, HttpServletResponse response){
log.info("退款通知执行");
Gson gson = new Gson();
Map<String, String> map = new HashMap<>();//应答对象
try {
//处理通知参数
String body = HttpUtils.readData(request);
Map<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
String requestId = (String)bodyMap.get("id");
log.info("支付通知的id ===> {}", requestId);
//签名的验证
WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest
= new WechatPay2ValidatorForRequest(verifier, requestId, body);
if(!wechatPay2ValidatorForRequest.validate(request)){
log.error("通知验签失败");
//失败应答
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "通知验签失败");
return gson.toJson(map);
}
log.info("通知验签成功");
//处理退款单
wxPayService.processRefund(bodyMap);
//成功应答
response.setStatus(200);
map.put("code", "SUCCESS");
map.put("message", "成功");
return gson.toJson(map);
} catch (Exception e) {
e.printStackTrace();
//失败应答
response.setStatus(500);
map.put("code", "ERROR");
map.put("message", "失败");
return gson.toJson(map);
}
}
6.2 处理订单和退款单
WxPayService
接口:
void processRefund(Map<String, Object> bodyMap) throws Exception;
实现:
/**
* 处理退款单
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void processRefund(Map<String, Object> bodyMap) throws Exception {
log.info("退款单");
//解密报文
String plainText = decryptFromResource(bodyMap);
//将明文转换成map
Gson gson = new Gson();
HashMap plainTextMap = gson.fromJson(plainText, HashMap.class);
String orderNo = (String)plainTextMap.get("out_trade_no");
if(lock.tryLock()){
try {
String orderStatus = orderInfoService.getOrderStatus(orderNo);
if (!OrderStatus.REFUND_PROCESSING.getType().equals(orderStatus)) {
return;
}
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.REFUND_SUCCESS);
//更新退款单
refundsInfoService.updateRefund(plainText);
} finally {
//要主动释放锁
lock.unlock();
}
}
}
七 账单
7.1 申请交易账单和资金账单
(1)WxPayController
@ApiOperation("获取账单url:测试用")
@GetMapping("/querybill/{billDate}/{type}")
public R queryTradeBill(
@PathVariable String billDate,
@PathVariable String type) throws Exception {
log.info("获取账单url");
String downloadUrl = wxPayService.queryBill(billDate, type);
return R.ok().setMessage("获取账单url成功").data("downloadUrl", downloadUrl);
}
(2)WxPayService
接口
String queryBill(String billDate, String type) throws Exception;
实现
/**
* 申请账单
* @param billDate
* @param type
* @return
* @throws Exception
*/
@Override
public String queryBill(String billDate, String type) throws Exception {
log.warn("申请账单接口调用 {}", billDate);
String url = "";
if("tradebill".equals(type)){
url = WxApiType.TRADE_BILLS.getType();
}else if("fundflowbill".equals(type)){
url = WxApiType.FUND_FLOW_BILLS.getType();
}else{
throw new RuntimeException("不支持的账单类型");
}
url = wxPayConfig.getDomain().concat(url).concat("?bill_date=").concat(billDate);
//创建远程Get 请求对象
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Accept", "application/json");
//使用wxPayClient发送请求得到响应
CloseableHttpResponse response = wxPayClient.execute(httpGet);
try {
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 申请账单返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("申请账单异常, 响应码 = " + statusCode+ ", 申请账单返回结果 = " + bodyAsString);
}
//获取账单下载地址
Gson gson = new Gson();
Map<String, String> resultMap = gson.fromJson(bodyAsString, HashMap.class);
return resultMap.get("download_url");
} finally {
response.close();
}
}
7.2 下载账单
(1)WxPayController
@ApiOperation("下载账单")
@GetMapping("/downloadbill/{billDate}/{type}")
public R downloadBill(
@PathVariable String billDate,
@PathVariable String type) throws Exception {
log.info("下载账单");
String result = wxPayService.downloadBill(billDate, type);
return R.ok().data("result", result);
}
(2)WxPayService
接口:
String downloadBill(String billDate, String type) throws Exception;
实现:
/**
* 下载账单
* @param billDate
* @param type
* @return
* @throws Exception
*/
@Override
public String downloadBill(String billDate, String type) throws Exception {
log.warn("下载账单接口调用 {}, {}", billDate, type);
//获取账单url地址
String downloadUrl = this.queryBill(billDate, type);
//创建远程Get 请求对象
HttpGet httpGet = new HttpGet(downloadUrl);
httpGet.addHeader("Accept", "application/json");
//使用wxPayClient发送请求得到响应
CloseableHttpResponse response = wxPayNoSignClient.execute(httpGet);
try {
String bodyAsString = EntityUtils.toString(response.getEntity());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
log.info("成功, 下载账单返回结果 = " + bodyAsString);
} else if (statusCode == 204) {
log.info("成功");
} else {
throw new RuntimeException("下载账单异常, 响应码 = " + statusCode+ ", 下载账单返回结果 = " + bodyAsString);
}
return bodyAsString;
} finally {
response.close();
}
}
第六章:微信基础支付API V2