Browse Source

支付记录调整

warr.qian 2 years ago
parent
commit
5db0c3acf1
4 changed files with 100 additions and 53 deletions
  1. 16 12
      Common/AlipayCommon.cs
  2. 9 7
      Common/WeChat/WxPayNativePay.cs
  3. 4 4
      Common/WeChatCommon.cs
  4. 71 30
      Service/PaymentService.cs

+ 16 - 12
Common/AlipayCommon.cs

@@ -1,3 +1,4 @@
+using System.Net.Cache;
 using System.Security.Cryptography.X509Certificates;
 using System;
 using Aop.Api;
@@ -34,7 +35,7 @@ namespace WingPaymentService.Common
         /// <param name="totalAmount"></param>
         /// <param name="orderCode"></param>
         /// <returns></returns>
-        public string AlipayPagePay(string subject, double totalAmount, string orderCode)
+        public (string, string) AlipayPagePay(string subject, double totalAmount, string orderCode, string recordCode)
         {
             try
             {
@@ -45,7 +46,8 @@ namespace WingPaymentService.Common
                     Subject = subject,
                     TotalAmount = totalAmount.ToString("0.00"),
                     OutTradeNo = orderCode,
-                    ProductCode = "QUICK_WAP_WAY"
+                    ProductCode = "QUICK_WAP_WAY",
+                    StoreId = recordCode
                 };
                 // 1. 创建IAopClient实例
                 IAopClient client = new DefaultAopClient
@@ -70,18 +72,18 @@ namespace WingPaymentService.Common
                 {
                     var url = $"{serverUrl}?{response.Body}";
                     Logger.WriteLineInfo($"AlipayPagePay success pay url:{url}");
-                    return url;
+                    return (url, JsonConvert.SerializeObject(request));
                 }
                 else
                 {
                     Logger.WriteLineError($"AlipayPagePay error:{response.Msg},{response.SubMsg}");
-                    return string.Empty;
+                    return (string.Empty, JsonConvert.SerializeObject(request));
                 }
             }
             catch (Exception ex)
             {
                 Logger.WriteLineError($"AlipayPagePay error:{ex}");
-                return string.Empty;
+                return (string.Empty, $"AlipayPagePay error:{ex}");
             }
         }
 
@@ -92,17 +94,19 @@ namespace WingPaymentService.Common
         /// <param name="totalAmount"></param>
         /// <param name="orderCode"></param>
         /// <returns></returns>
-        public string AlipayWapPay(string subject, double totalAmount, string orderCode)
+        public (string, string) AlipayWapPay(string subject, double totalAmount, string orderCode, string recordCode)
         {
             try
             {
+                var serverUrl = $"{_protocol}://{_gatewayHost}/gateway.do";
                 // 组装业务参数model
                 AlipayTradeWapPayModel model = new AlipayTradeWapPayModel
                 {
                     Subject = subject,
                     TotalAmount = totalAmount.ToString("0.00"),
                     OutTradeNo = orderCode,
-                    ProductCode = "QUICK_WAP_WAY"
+                    ProductCode = "QUICK_WAP_WAY",
+                    StoreId = recordCode
                 };
                 // 1. 创建IAopClient实例
                 IAopClient client = new DefaultAopClient
@@ -118,27 +122,27 @@ namespace WingPaymentService.Common
                 );
                 Aop.Api.Request.AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
                 // 设置异步通知接收地址
-                request.SetNotifyUrl($"/PaymentApi/UnityPay/AlipayNotify");
+                request.SetNotifyUrl(_notifyUrl);
                 request.SetProdCode("QUICK_WAP_WAY");
                 request.SetBizModel(model);
                 // 3. 发起请求并处理响应
                 Aop.Api.Response.AlipayTradeWapPayResponse response = client.SdkExecute(request);
                 if (!response.IsError)
                 {
-                    var url = $"{_gatewayHost}?{response.Body}";
+                    var url = $"{serverUrl}?{response.Body}";
                     Logger.WriteLineInfo($"AlipayWapPay success pay url:{url}");
-                    return url;
+                    return (url, JsonConvert.SerializeObject(request));
                 }
                 else
                 {
                     Logger.WriteLineError($"AlipayWapPay error:{response.Msg},{response.SubMsg}");
-                    return string.Empty;
+                    return (string.Empty, JsonConvert.SerializeObject(request));
                 }
             }
             catch (Exception ex)
             {
                 Logger.WriteLineError($"AlipayWapPay error:{ex}");
-                return string.Empty;
+                return (string.Empty, $"AlipayWapPay error:{ex}");
             }
         }
     }

+ 9 - 7
Common/WeChat/WxPayNativePay.cs

@@ -1,4 +1,6 @@
-using System.Linq;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Data.Common;
+using System.Linq;
 using System;
 using System.Collections.Generic;
 using System.Threading.Tasks;
@@ -18,7 +20,7 @@ namespace WingPaymentService.Common.WeChat
         /// <param name="attach">附加数据</param>
         /// <param name="deviceInfo">设备信息</param>
         /// <returns></returns>
-        public async Task<string> GetWebPayUrl(string body, int totalAmount, string outTradeNo, string attach, string deviceInfo)
+        public async Task<(string,string)> GetWebPayUrl(string body, int totalAmount, string outTradeNo, string recordCode, string attach, string deviceInfo)
         {
             WxPayData data = new WxPayData();
             data.SetValue("body", body);//商品描述
@@ -32,7 +34,7 @@ namespace WingPaymentService.Common.WeChat
             //data.SetValue("goods_tag", "jjj");//商品标记
             data.SetValue("trade_type", "NATIVE");//交易类型
             data.SetValue("device_info", deviceInfo);
-
+            data.SetValue("pay_record_code", recordCode);
             WxPayData result = await _wxPayApi.UnifiedOrder(data);//调用统一下单接口
             var errorCode = result.GetValue("err_code_des")?.ToString();
             if (!string.IsNullOrWhiteSpace(errorCode))
@@ -40,7 +42,7 @@ namespace WingPaymentService.Common.WeChat
                 throw new Exception(errorCode);
             }
             string url = result.GetValue("code_url")?.ToString();//获取二维码链接
-            return url;
+            return (url, data.ToJson());
         }
 
         /// <summary>
@@ -52,7 +54,7 @@ namespace WingPaymentService.Common.WeChat
         /// <param name="attach">附加数据</param>
         /// <param name="deviceInfo">设备信息</param>
         /// <returns></returns>
-        public async Task<string> GetWapPayUrl(string body, int totalAmount, string outTradeNo, string attach, string deviceInfo)
+        public async Task<(string,string)> GetWapPayUrl(string body, int totalAmount, string outTradeNo, string recordCode, string attach, string deviceInfo)
         {
             WxPayData data = new WxPayData();
             data.SetValue("body", body);//商品描述
@@ -66,7 +68,7 @@ namespace WingPaymentService.Common.WeChat
             //data.SetValue("goods_tag", "jjj");//商品标记
             data.SetValue("trade_type", "MWEB");//交易类型
             data.SetValue("device_info", deviceInfo);
-
+            data.SetValue("pay_record_code", recordCode);
             WxPayData result = await _wxPayApi.UnifiedOrder(data);//调用统一下单接口
             var errorCode = result.GetValue("err_code_des")?.ToString();
             if (!string.IsNullOrWhiteSpace(errorCode))
@@ -74,7 +76,7 @@ namespace WingPaymentService.Common.WeChat
                 throw new Exception(errorCode);
             }
             string url = result.GetValue("mweb_url")?.ToString();//wap支付链接
-            return url;
+            return (url, data.ToJson());
         }
 
         /// <summary>

+ 4 - 4
Common/WeChatCommon.cs

@@ -19,10 +19,10 @@ namespace WingPaymentService.Common
         /// <param name="attach">附加数据</param>
         /// <param name="deviceInfo">设备信息</param>
         /// <returns></returns>
-        public async Task<string> GetWebPayUrlAsync(string body, double totalAmount, string outTradeNo, string attach, string deviceInfo)
+        public async Task<(string, string)> GetWebPayUrlAsync(string body, double totalAmount, string outTradeNo, string recordCode, string attach, string deviceInfo)
         {
             int totalNumber = Convert.ToInt32(totalAmount * 100);
-            return await _nativePay.GetWebPayUrl(body, totalNumber, outTradeNo, attach, deviceInfo);
+            return await _nativePay.GetWebPayUrl(body, totalNumber, outTradeNo, recordCode, attach, deviceInfo);
         }
 
         /// <summary>
@@ -34,10 +34,10 @@ namespace WingPaymentService.Common
         /// <param name="attach">附加数据</param>
         /// <param name="deviceInfo">设备信息</param>
         /// <returns></returns>
-        public async Task<string> GetWapPayUrlAsync(string body, double totalAmount, string outTradeNo, string attach, string deviceInfo)
+        public async Task<(string, string)> GetWapPayUrlAsync(string body, double totalAmount, string outTradeNo, string recordCode, string attach, string deviceInfo)
         {
             int totalNumber = Convert.ToInt32(totalAmount * 100);
-            return await _nativePay.GetWapPayUrl(body, totalNumber, outTradeNo, attach, deviceInfo);
+            return await _nativePay.GetWapPayUrl(body, totalNumber, outTradeNo, recordCode, attach, deviceInfo);
         }
     }
 }

+ 71 - 30
Service/PaymentService.cs

@@ -98,28 +98,30 @@ namespace WingPaymentService.Service
                 var orderInfo = await _paymentDBService.GetOrderDetailAsync(new GetOrderDetailDBRequest { OrderCode = request.OrderCode });
                 if (orderInfo != null && orderInfo.OrderAmount > 0)
                 {
-                    string payUrl = string.Empty;
+                    string recordCode = Guid.NewGuid().ToString("N");
+                    (string payUrl, string recordContent) payContent = (string.Empty,string.Empty);
                     switch (request.PayType)
                     {
                         case PayTypeEnum.Alipay_PAGE:
-                            payUrl = _alipayCommon.AlipayPagePay(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code);
+                            payContent = _alipayCommon.AlipayPagePay(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode);
                             break;
                         case PayTypeEnum.Alipay_WAP:
-                            payUrl = _alipayCommon.AlipayWapPay(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code);
+                            payContent = _alipayCommon.AlipayWapPay(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode);
                             break;
                         case PayTypeEnum.WeChat_PAGE:
-                            payUrl = await _weChatCommon.GetWebPayUrlAsync(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, string.Empty, string.Empty);
+                            payContent = await _weChatCommon.GetWebPayUrlAsync(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode, string.Empty, string.Empty);
                             break;
                         case PayTypeEnum.WeChat_WAP:
-                            payUrl = await _weChatCommon.GetWapPayUrlAsync(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, string.Empty, string.Empty);
+                            payContent = await _weChatCommon.GetWapPayUrlAsync(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode, string.Empty, string.Empty);
                             break;
                     }
-                    if (!string.IsNullOrWhiteSpace(payUrl))
+                    await CreatePayStatusReq(recordCode, payContent.recordContent);
+                    if (!string.IsNullOrWhiteSpace(payContent.payUrl))
                     {
                         return new PayInfoDTO
                         {
                             IsSuccess = true,
-                            PayUrl = payUrl
+                            PayUrl = payContent.payUrl
                         };
                     }
                 }
@@ -139,19 +141,20 @@ namespace WingPaymentService.Service
         /// <returns></returns>
         public async Task<PayCallbackDTO> PayCallbackAsync(string src, string request)
         {
+            bool isSuccess = false;
             try
             {
                 switch (src)
                 {
-                    case "Alipay":
-                        await AlipayCallback(request);
+                    case "alipay":
+                        isSuccess = await AlipayCallback(request);
                         break;
-                    case "WeChat":
-                        await WeChatCallback(request);
+                    case "wechat":
+                        isSuccess = await WeChatCallback(request);
                         break;
                 }
 
-                return new PayCallbackDTO { IsSuccess = true };
+                return new PayCallbackDTO { IsSuccess = isSuccess };
             }
             catch (Exception ex)
             {
@@ -160,6 +163,11 @@ namespace WingPaymentService.Service
             }
         }
 
+        /// <summary>
+        /// 支付宝回调
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
         private async Task<bool> AlipayCallback(string request)
         {
             Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
@@ -177,49 +185,75 @@ namespace WingPaymentService.Service
             }
             var payOutTradeNo = keyValuePairs.GetValueOrDefault("out_trade_no");
             var totalAmount = keyValuePairs.GetValueOrDefault("total_amount");
-            var paymentRecordCode = keyValuePairs.GetValueOrDefault("pay_record_code");
+            var payRecordCode = keyValuePairs.GetValueOrDefault("pay_record_code");
             var payStatus = keyValuePairs.GetValueOrDefault("trade_status") == "TRADE_SUCCESS" ? WingInterfaceLibrary.Enum.PayStatusEnum.Paid : WingInterfaceLibrary.Enum.PayStatusEnum.NoPay;
             var payTime = DateTime.UtcNow;
-            await UpdatePayStatus(paymentRecordCode, payStatus, uriParams, payTime);
-            if(payStatus == PayStatusEnum.Paid)
-            {
-                return await UpdateOrderStatus(payOutTradeNo, payStatus, totalAmount, payTime);
-            }
-            return false;
+            return await PayRecordWriteRes(payOutTradeNo, payRecordCode, totalAmount, payStatus, payTime, request);
         }
 
+        /// <summary>
+        /// 微信回调
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
         private async Task<bool> WeChatCallback(string request)
         {
             //转换数据格式, 取消签名校验,签名调用方自己调用,兼容支付和退款
             WxPayData data = new WxPayData();
-            var paramValues = data.FromXml(request,false);//回调不用签名校验
+            var paramValues = data.FromXml(request, false);//回调不用签名校验
             var payOutTradeNo = paramValues.GetValueOrDefault("out_trade_no")?.ToString();
-            var totalAmount = (double.Parse(paramValues.GetValueOrDefault("total_fee")?.ToString())/100).ToString("0.00");
+            var totalAmount = (double.Parse(paramValues.GetValueOrDefault("total_fee")?.ToString()) / 100).ToString("0.00");
             var payRecordCode = paramValues.GetValueOrDefault("pay_record_code")?.ToString();
             var payStatus = paramValues.GetValueOrDefault("result_code")?.ToString() == "SUCCESS" ? PayStatusEnum.Paid : PayStatusEnum.NoPay;
             var payTime = DateTime.UtcNow;
-            await UpdatePayStatus(payRecordCode, payStatus, request, payTime);
-            if(payStatus == PayStatusEnum.Paid)
+            return await PayRecordWriteRes(payOutTradeNo, payRecordCode, totalAmount, payStatus, payTime, request);
+        }
+
+        /// <summary>
+        /// 支付记录
+        /// </summary>
+        /// <param name="orderCode">订单编码</param>
+        /// <param name="payRecordCode">支付记录编码</param>
+        /// <param name="totalAmount">支付金额</param>
+        /// <param name="payStatus">支付状态</param>
+        /// <param name="payTime">支付时间</param>
+        /// <param name="request">支付原始请求</param>
+        /// <returns></returns>
+        private async Task<bool> PayRecordWriteRes(string orderCode, string payRecordCode, string totalAmount, PayStatusEnum payStatus, DateTime payTime, string res)
+        {
+            if (string.IsNullOrWhiteSpace(payRecordCode))
+            {
+                Logger.WriteLineError("Pay record code is empty");
+                return false;
+            }
+            await UpdatePayStatusRes(payRecordCode, payStatus, res, payTime);
+            if (string.IsNullOrWhiteSpace(orderCode))
+            {
+                Logger.WriteLineError("Order code is empty");
+                return false;
+            }
+            if (payStatus == PayStatusEnum.Paid)
             {
-                var result = await UpdateOrderStatus(payOutTradeNo, payStatus, totalAmount, payTime);
-                return result;
+                return await UpdateOrderStatus(orderCode, payStatus, totalAmount, payTime);
             }
             return false;
         }
 
         private async Task<bool> UpdateOrderStatus(string orderCode, PayStatusEnum payStatus, string totalAmount, DateTime payTime)
         {
-            var orderInfo = await _paymentDBService.GetOrderDetailAsync(new GetOrderDetailDBRequest{ OrderCode = orderCode});
-            if(orderInfo.OrderAmount.ToString("0.00") != totalAmount)
+            var orderInfo = await _paymentDBService.GetOrderDetailAsync(new GetOrderDetailDBRequest { OrderCode = orderCode });
+            if (orderInfo.OrderAmount.ToString("0.00") != totalAmount)
             {
                 Logger.WriteLineError($"OrderCode:{orderInfo.Code} pay status {payStatus}, total amount error, order amount {orderInfo.OrderAmount.ToString("0.00")} paid amount {totalAmount}");
                 return false;
             }
-            var result = await _paymentDBService.UpdateOrderAsync(new UpdateOrderDBRequest{
+            var result = await _paymentDBService.UpdateOrderAsync(new UpdateOrderDBRequest
+            {
                 OrderCode = orderCode,
                 PayStatus = payStatus
             });
-            await _educationService.PaymentCallbackAsync(new PaymentCallbackRequest{
+            await _educationService.PaymentCallbackAsync(new PaymentCallbackRequest
+            {
                 PaymentOrderCode = orderCode,
                 PayStatus = payStatus,
                 PayTime = payTime
@@ -227,7 +261,14 @@ namespace WingPaymentService.Service
             return result.IsSuccess;
         }
 
-        private async Task<UpdatePaymentRecordResultDTO> UpdatePayStatus(string paymentRecordCode, PayStatusEnum payStatus, string payResContent, DateTime payTime)
+        private async Task<CreatePaymentRecordResultDTO> CreatePayStatusReq(string paymentRecordCode, string payReqContent)
+        {
+            var createRecordInfo = new CreatePaymentRecordDBRequest();
+            createRecordInfo.PayReqContent = payReqContent;
+            return await _paymentDBService.CreatePaymentRecordAsync(createRecordInfo);
+        }
+
+        private async Task<UpdatePaymentRecordResultDTO> UpdatePayStatusRes(string paymentRecordCode, PayStatusEnum payStatus, string payResContent, DateTime payTime)
         {
             var updateRecordInfo = new UpdatePaymentRecordDBRequest();
             updateRecordInfo.Code = paymentRecordCode;