|
@@ -14,6 +14,7 @@ using Com.Alipay;
|
|
|
using Com.Alipay.Business;
|
|
|
using Com.Alipay.Domain;
|
|
|
using Com.Alipay.Model;
|
|
|
+using F2FPayDll.Domain;
|
|
|
using Newtonsoft.Json;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
@@ -459,7 +460,108 @@ namespace Central.Control.WebApi.Service
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
- /// 支付回写(雏形,需要根据实际需要接入支付宝或微信)
|
|
|
+ /// 申请退款
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public ApiResult OrderRefund(string orderId)
|
|
|
+ {
|
|
|
+ var order = _dbContent.Set<YW_Order>().FirstOrDefault(p => p.IsDelete == 0 && p.Id == orderId);
|
|
|
+
|
|
|
+ if (order.PayStatus != PayStatusEnum.RefundApply)
|
|
|
+ {
|
|
|
+ // 订单状态不可退款
|
|
|
+ return new ApiResult(ApiStatusCode.InvalidParameter, "当前订单状态不可退款");
|
|
|
+ }
|
|
|
+ ApiResult result = null;
|
|
|
+ switch (order.PayWay)
|
|
|
+ {
|
|
|
+ case PayWayEnum.WeChatPay:
|
|
|
+ result = new ApiResult(ApiStatusCode.Forbidden, "微信支付暂未接入,无法发起退款");
|
|
|
+ break;
|
|
|
+ case PayWayEnum.AliPay:
|
|
|
+ // 支付宝退款
|
|
|
+ result = AliPayRefund(order.Id, order.PaySerialId, order.Price, "客户发起退款");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ result = new ApiResult(ApiStatusCode.Forbidden, "未知支付方式,无法在线自动退款");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result.IsSuccess)
|
|
|
+ {
|
|
|
+ // 修改订单状态
|
|
|
+ order.PayStatus = PayStatusEnum.Refunding;
|
|
|
+ order.OrderStatus = OrderStatusEnum.Cancel;
|
|
|
+ order.ModifyDT = DateTime.Now;
|
|
|
+ order.ModifyBY = "用户申请";
|
|
|
+ _dbContent.SaveChanges();
|
|
|
+ // 写入订单流程记录
|
|
|
+ _ywLogService.WriteOrderProcess(order.Id, order.DeviceId, OrderStatusEnum.Cancel, "申请退款", "用户申请");
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 轮询查询退款信息,并更新订单的退款记录
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public ApiResult OrderRefundLoop()
|
|
|
+ {
|
|
|
+ // 1、查询出所有退款中的订单
|
|
|
+ // 2、请求支付宝退款接口查询是否已退款成功
|
|
|
+ // 3、退款成功或失败时,回写到订单中
|
|
|
+ var modifyDt = DateTime.Now.AddMinutes(-2);// 查询2分钟以前的订单,因为退款需要一定时间,马上查询会返回失败
|
|
|
+ var order = _dbContent.Set<YW_Order>().Where(p => p.IsDelete == 0 && p.PayStatus == PayStatusEnum.RefundApply && p.ModifyDT < modifyDt).OrderBy(p => p.ModifyDT).FirstOrDefault();
|
|
|
+ if (order == null)
|
|
|
+ {
|
|
|
+ return new ApiResult(ApiStatusCode.InvalidParameter, "无退款中订单");
|
|
|
+ }
|
|
|
+ // 更新modifydt以便下次捞取别的订单
|
|
|
+ order.ModifyDT = DateTime.Now;
|
|
|
+
|
|
|
+ ApiResult result = null;
|
|
|
+ switch (order.PayWay)
|
|
|
+ {
|
|
|
+ case PayWayEnum.WeChatPay:
|
|
|
+ result = new ApiResult(ApiStatusCode.Forbidden, "微信支付暂未接入,无法进行查询");
|
|
|
+ break;
|
|
|
+ case PayWayEnum.AliPay:
|
|
|
+ // 查询支付宝退款
|
|
|
+ result = AliPayRefundQuery(order.Id, order.PaySerialId, order.DeviceId);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ result = new ApiResult(ApiStatusCode.Forbidden, "未知支付方式,无法进行查询");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result.IsSuccess)
|
|
|
+ {
|
|
|
+ // 修改订单状态
|
|
|
+ order.PayStatus = PayStatusEnum.Refunded;
|
|
|
+ order.OrderStatus = OrderStatusEnum.Cancel;
|
|
|
+ order.ModifyDT = DateTime.Now;
|
|
|
+ order.ModifyBY = "用户申请";
|
|
|
+ // 写入订单流程记录
|
|
|
+ _ywLogService.WriteOrderProcess(order.Id, order.DeviceId, OrderStatusEnum.Cancel, "退款成功", "用户申请");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 退款失败,将订单更新成错误,并记录订单日志
|
|
|
+ order.PayStatus = PayStatusEnum.Fail;
|
|
|
+ order.OrderStatus = OrderStatusEnum.Cancel;
|
|
|
+ order.ModifyDT = DateTime.Now;
|
|
|
+ order.ModifyBY = "用户申请";
|
|
|
+ // 写入订单日志
|
|
|
+ _ywLogService.WriteOrderLog(order.Id, "订单退款失败", result.Message, "用户申请");
|
|
|
+ }
|
|
|
+ _dbContent.SaveChanges();
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ #region privatemethods
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 支付回写(回写到实际表中)
|
|
|
/// </summary>
|
|
|
/// <param name="req"></param>
|
|
|
/// <returns></returns>
|
|
@@ -524,6 +626,99 @@ namespace Central.Control.WebApi.Service
|
|
|
return new ApiResult();
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 支付宝退款
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="orderId"></param>
|
|
|
+ /// <param name="paySerialId"></param>
|
|
|
+ /// <param name="refundAmount"></param>
|
|
|
+ /// <param name="refundReason"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private ApiResult AliPayRefund(string orderId,string paySerialId,decimal refundAmount, string refundReason)
|
|
|
+ {
|
|
|
+ AlipayTradeRefundContentBuilder builder = new AlipayTradeRefundContentBuilder()
|
|
|
+ {
|
|
|
+ trade_no = paySerialId,
|
|
|
+ out_trade_no = orderId,
|
|
|
+ refund_amount = refundAmount.ToString(),
|
|
|
+ out_request_no = string.Empty,
|
|
|
+ refund_reason = refundReason,
|
|
|
+ };
|
|
|
+ ApiResult result = null;
|
|
|
+ // 支付宝退款
|
|
|
+ _log4NetHelper.Error($"[AliPayRefund]-tradeRefund-start:request:{JsonConvert.SerializeObject(builder)}");
|
|
|
+ AlipayF2FRefundResult refundResult = serviceClient.tradeRefund(builder);
|
|
|
+ _log4NetHelper.Error($"[AliPayRefund]-tradeRefund-end:request:{JsonConvert.SerializeObject(refundResult)}");
|
|
|
+
|
|
|
+ switch (refundResult.Status)
|
|
|
+ {
|
|
|
+ case ResultEnum.SUCCESS:
|
|
|
+ // 退款成功-记录日志
|
|
|
+ _ywLogService.WriteOrderLog(orderId, "申请退款", $"申请退款成功:退款金额{refundResult.response?.SendBackFee}", "用户申请");
|
|
|
+ result = new ApiResult();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ result = new ApiResult(ApiStatusCode.InternalServerError, "请求支付宝退款失败" + refundResult.response?.SubMsg);
|
|
|
+ // 退款失败-记录订单日志
|
|
|
+ _ywLogService.WriteOrderLog(orderId, "申请退款", $"申请退款失败:{refundResult.response?.SubMsg}", "用户申请");
|
|
|
+ // 请求失败,记录log4net日志
|
|
|
+ _log4NetHelper.Error($"[AliPayRefund]-tradeRefund失败:request:{JsonConvert.SerializeObject(builder)};response:{JsonConvert.SerializeObject(refundResult)}");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 支付宝退款查询
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="orderId"></param>
|
|
|
+ /// <param name="paySerialId"></param>
|
|
|
+ /// <param name="deviceId"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private ApiResult AliPayRefundQuery(string orderId, string paySerialId, string deviceId)
|
|
|
+ {
|
|
|
+ var builder = new AlipayTradeFastpayRefundQueryContentBuilder()
|
|
|
+ {
|
|
|
+ trade_no = paySerialId,
|
|
|
+ out_trade_no = orderId,
|
|
|
+ out_request_no = deviceId
|
|
|
+ };
|
|
|
+ ApiResult result = null;
|
|
|
+ // 支付宝退款
|
|
|
+ _log4NetHelper.Error($"[AliPayRefund]-AliPayRefundQuery-start:request:{JsonConvert.SerializeObject(builder)}");
|
|
|
+ var refundQueryResult = serviceClient.tradeFastpayRefundQuery(builder);
|
|
|
+ _log4NetHelper.Error($"[AliPayRefund]-AliPayRefundQuery-end:request:{JsonConvert.SerializeObject(refundQueryResult)}");
|
|
|
+
|
|
|
+ switch (refundQueryResult.Status)
|
|
|
+ {
|
|
|
+ case ResultEnum.SUCCESS:
|
|
|
+ string content = "成功";
|
|
|
+ if (refundQueryResult.response.RefundStatus == "REFUND_SUCCESS")
|
|
|
+ {
|
|
|
+ // 退款成功
|
|
|
+ result = new ApiResult();
|
|
|
+ content = $"退款成功:退款金额{refundQueryResult.response?.RefundAmount}";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 退款失败
|
|
|
+ result = new ApiResult(ApiStatusCode.InternalServerError, "请求支付宝退款失败" + refundQueryResult.response?.SubMsg);
|
|
|
+ content = $"退款失败:{refundQueryResult.response?.SubMsg}";
|
|
|
+ }
|
|
|
+ // 记录订单日志
|
|
|
+ _ywLogService.WriteOrderLog(orderId, "退款查询", content, "用户申请");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ result = new ApiResult(ApiStatusCode.InternalServerError, "请求支付宝退款失败" + refundQueryResult.response?.SubMsg);
|
|
|
+ // 退款失败-记录订单日志
|
|
|
+ _ywLogService.WriteOrderLog(orderId, "退款查询", $"退款失败:{refundQueryResult.response?.SubMsg}", "用户申请");
|
|
|
+ // 请求失败,记录log4net日志
|
|
|
+ _log4NetHelper.Error($"[AliPayRefund]-AliPayRefundQuery失败:request:{JsonConvert.SerializeObject(builder)};response:{JsonConvert.SerializeObject(refundQueryResult)}");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 支付测试
|
|
|
/// </summary>
|
|
@@ -684,5 +879,7 @@ namespace Central.Control.WebApi.Service
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ #endregion
|
|
|
+
|
|
|
}
|
|
|
}
|