LifePayment/LifePayment.Application/LifePay/LifePayService.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayEnum.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
LifePayment/LifePayment.Domain.Shared/LifePaymentConstant.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
LifePayment/LifePayment.Domain.Shared/WeChat/WxPayPostBaseModel.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
LifePayment/LifePayment.Domain/WeChat/IWxPayApi.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
LifePayment/LifePayment.Domain/WeChat/WxClient.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
LifePayment/LifePayment.Domain/WeChat/WxPayApi.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
LifePayment/LifePayment.Application/LifePay/LifePayService.cs
@@ -993,6 +993,9 @@ throw new UserFriendlyException("当前订单状态无法退款"); } /// TODO 退款请求完成后如何操作 /// var refundResult = await WxPayDomesticRefunds(order.OrderNo, order.RefundApplyRemark, Convert.ToInt32(order.PayAmount * 100), Convert.ToInt32(order.PayAmount * 100)); order.PayStatus = LifePayStatusEnum.已退款; order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; order.RefundCredentialsImgUrl = input.RefundCredentialsImgUrl; @@ -1043,6 +1046,26 @@ await _lifePayOrderRepository.UpdateAsync(order); } public async Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(string outTradeNo, string reason, int refund, int total, string currency = "CNY") { WxPayDomesticRefundsRequest req = new WxPayDomesticRefundsRequest { OutTradeNo = outTradeNo, OutRefundNo = CreateRefundOrderNo(), Reason = reason, Amount = new Model_WxPayDomesticRefunds_Amount { Refund = refund, Total = total, Currency = "CNY" }, NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxPayDomesticRefundsNotifySectionUrl}", }; var res = await _wxPayApi.WxPayDomesticRefunds(req); return res; } public async Task<int> AddUpdateUserAccount(AddUpdateUserAccountInput input) { if (input.Id.HasValue) @@ -1064,7 +1087,6 @@ } else { var repeatAccountContent = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.LifePayType == input.LifePayType && x.Content == input.Content) .FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(repeatAccountContent != null, "户号已存在"); @@ -1240,6 +1262,11 @@ return "JF" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + GlobalRandom.GetRandomNum(4); } private string CreateRefundOrderNo() { return "JFTK" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + GlobalRandom.GetRandomNum(4); } private (decimal PayAmont, decimal DiscountAmount, decimal RechargeAmount) CalculateAmount(decimal amount, decimal rate) { /// 正常支付 LifePayment/LifePayment.Domain.Shared/Enum/LifePay/LifePayEnum.cs
@@ -59,6 +59,25 @@ 退款失败 = 60, } public enum LifePayRefundStatusEnum { [Description("无需退款")] 无需退款 = 0, [Description("待退款")] 待退款 = 10, [Description("退款中")] 退款中 = 20, [Description("已退款")] 已退款 = 30, [Description("退款驳回")] 退款驳回 = 40, } public enum LifePayRateTypeEnum { 默认话费折扣=10, LifePayment/LifePayment.Domain.Shared/LifePaymentConstant.cs
@@ -53,7 +53,11 @@ public const string PayTransactionsH5 = "/v3/pay/transactions/h5"; public const string WxPayDomesticRefunds = "/v3/refund/domestic/refunds"; public const string WxRechargeNotifySectionUrl = "/api/WxPayNotify/WxRechargeNotify"; public const string WxPayDomesticRefundsNotifySectionUrl = "/api/WxPayNotify/WxPayDomesticRefundsNotify"; public const string AliRechargeNotifySectionUrl = "/api/AliPayNotify/AliRechargeNotify"; @@ -423,6 +427,18 @@ public const string 支付成功 = "SUCCESS"; } public static class WxPayRefundStatus { public const string 退款成功 = "SUCCESS"; public const string 退款关闭 = "CLOSED"; public const string 退款处理中 = "PROCESSING"; public const string 退款异常 = "ABNORMAL"; } public static class ThumbsUpStatus { public const int 取消 = 0; LifePayment/LifePayment.Domain.Shared/WeChat/WxPayPostBaseModel.cs
@@ -594,4 +594,182 @@ public string Attach { get; set; } } /// <summary> /// 申请退款 /// </summary> public class WxPayDomesticRefundsRequest { /// <summary> /// 微信支付订单号 和out_trade_no必须二选一进行传参 /// </summary> [JsonProperty("transaction_id")] public string TransactionId { get; set; } /// <summary> /// 商户订单号 和out_trade_no必须二选一进行传参 /// </summary> [JsonProperty("out_trade_no")] public string OutTradeNo { get; set; } /// <summary> /// 商户退款单号 必填 /// </summary> [JsonProperty("out_refund_no")] public string OutRefundNo { get; set; } /// <summary> /// 退款原因 /// </summary> [JsonProperty("reason")] public string Reason { get; set; } /// <summary> /// 退款结果回调url /// </summary> [JsonProperty("notify_url")] public string NotifyUrl { get; set; } /// <summary> /// 退款资金来源 /// </summary> [JsonProperty("funds_account")] public string FundsAccount { get; set; } /// <summary> /// 金额信息 必填 /// </summary> [JsonProperty("amount")] public Model_WxPayDomesticRefunds_Amount Amount { get; set; } } public class Model_WxPayDomesticRefunds_Amount { /// <summary> /// 退款金额,单位为分,只能为整数 /// </summary> [JsonProperty("refund")] public int Refund { get; set; } /// <summary> /// 原订单金额 /// </summary> [JsonProperty("total")] public int Total { get; set; } /// <summary> /// 退款币种 /// </summary> [JsonProperty("currency")] public string Currency { get; set; } = "CNY"; } public class WxPayDomesticRefundsReponse { /// <summary> /// 微信支付退款单号 /// </summary> [JsonProperty("refund_id")] public string RefundId { get; set; } /// <summary> /// 商户退款单号 /// </summary> [JsonProperty("out_refund_no")] public string OutRefundNo { get; set; } /// <summary> /// 微信支付订单号 /// </summary> [JsonProperty("transaction_id")] public string TransactionId { get; set; } /// <summary> /// 商户订单号 /// </summary> [JsonProperty("out_trade_no")] public string OutTradeNo { get; set; } /// <summary> /// 退款渠道 ORIGINAL: 原路退款 BALANCE: 退回到余额 OTHER_BALANCE: 原账户异常退到其他余额账户 OTHER_BANKCARD: 原银行卡异常退到其他银行卡(发起异常退款成功后返回) /// </summary> [JsonProperty("channel")] public string Channel { get; set; } /// <summary> /// 退款入账账户 /// </summary> [JsonProperty("user_received_account")] public string UserReceivedAccount { get; set; } /// <summary> /// 退款成功时间 /// </summary> [JsonProperty("success_time")] public string SuccessTime { get; set; } /// <summary> /// 退款创建时间 /// </summary> [JsonProperty("create_time")] public string CreateTime { get; set; } /// <summary> /// 退款状态 /// </summary> [JsonProperty("status")] public string Status { get; set; } /// <summary> /// 资金账户 /// </summary> [JsonProperty("funds_account")] public string FundsAccount { get; set; } /// <summary> /// 金额信息 /// </summary> [JsonProperty("amount")] public Model_WxPayRetuenDomesticRefunds_Amount Amount { get; set; } } public class Model_WxPayRetuenDomesticRefunds_Amount: Model_WxPayDomesticRefunds_Amount { /// <summary> /// 用户实际支付金额 /// </summary> [JsonProperty("payer_total")] public int PayerTotal { get; set; } /// <summary> /// 用户退款金额 /// </summary> [JsonProperty("payer_refund")] public int PayerRefund { get; set; } /// <summary> /// 应结退款金额 /// </summary> [JsonProperty("settlement_refund")] public int SettlementRefund { get; set; } /// <summary> /// 应结订单金额 /// </summary> [JsonProperty("settlement_total")] public int SettlementTotal { get; set; } /// <summary> /// 优惠退款金额 /// </summary> [JsonProperty("discount_refund")] public int DiscountRefund { get; set; } /// <summary> /// 手续费退款金额 /// </summary> [JsonProperty("refund_fee")] public int RefundFee { get; set; } } } LifePayment/LifePayment.Domain/WeChat/IWxPayApi.cs
@@ -21,6 +21,7 @@ Task<ModelPayPrePayId> PayTransactionsJsAPI(ModelMiniPayRequest input); string GeneratePaySignByKey(string message); Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(WxPayDomesticRefundsRequest input); } } LifePayment/LifePayment.Domain/WeChat/WxClient.cs
@@ -35,7 +35,18 @@ AddAuthHeader(client, BuildAuth(body, function)); var data = new StringContent(body, Encoding.UTF8, "application/json"); var responseMessage = await client.PostAsync($"{Options.Url}{function}", data); var str = await responseMessage.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject<TResult>(str); return result; } public async Task<TResult> RefundsPostAsync<TInput, TResult>(TInput input, string function) { var client = HttpClientFactory.CreateClient(LifePaymentConstant.WxPayHttpClientName); var body = JsonConvert.SerializeObject(input); AddAuthHeader(client, BuildAuth(body, function)); var data = new StringContent(body, Encoding.UTF8, "application/json"); var responseMessage = await client.PostAsync($"{Options.Url}{function}", data); var str = await responseMessage.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject<TResult>(str); return result; @@ -129,9 +140,9 @@ gcmBlockCipher.DoFinal(plaintext, length); return Encoding.UTF8.GetString(plaintext); } public string GeneratePaySignByKey(string message) { return WxPayRsaHelper.Sign(message); } @@ -148,8 +159,5 @@ string signature = WxPayRsaHelper.Sign(message); return $"mchid=\"{Options.Mchid}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{Options.SerialNo}\",signature=\"{signature}\""; } } } LifePayment/LifePayment.Domain/WeChat/WxPayApi.cs
@@ -29,6 +29,10 @@ return result; } public async Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(WxPayDomesticRefundsRequest input) { var result = await RefundsPostAsync<WxPayDomesticRefundsRequest, WxPayDomesticRefundsReponse>(input, LifePaymentConstant.WxPayDomesticRefunds); return result; } } }