瀏覽代碼

提交支付

DOVER-GLOBAL\11047086 8 月之前
父節點
當前提交
75bf42f686

+ 26 - 0
FuelCloud/Fuel.Application/EntityHelper.cs

@@ -83,5 +83,31 @@ namespace Fuel.Application
             // 查询插入后的数据
             return await _fsql.Select<T>().Where(lambda).FirstAsync();
         }
+        /// <summary>
+        /// 更新
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="entity"></param>
+        /// <returns></returns>
+        public async Task<bool> UpdateAsync<T>(T entity) where T : class
+        {
+            try
+            {
+                // 更新数据,显式指定类型参数 T
+                int affectedRows = _fsql.Update<T>(entity).ExecuteAffrows();
+
+                // 返回是否成功更新
+                return affectedRows > 0;
+            }
+            catch (Exception ex)
+            {
+                // 可以在这里处理异常,例如日志记录
+                // Console.WriteLine(ex.Message);
+            }
+
+            return false;
+        }
+
+
     }
 }

+ 4 - 2
FuelCloud/Fuel.Application/Service/ITransactionsService.cs

@@ -5,13 +5,15 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using Fuel.Core.Models;
 
 namespace Fuel.Application.Service
 {
     public interface ITransactionsService
     {
-         Task<transactions> CreateTransactions(UploadTransactions uploadTransactions);
+         Task<ServiceResponse> CreateTransactions(UploadTransactions uploadTransactions);
 
-        Task<List<transactions>> GetTransactionsAsync(TransactionsInput input);
+        Task<ServiceResponse> GetTransactionsAsync(TransactionsInput input);
+        Task<ServiceResponse> CommitPayment(int trxId, string AuthCode);
     }
 }

+ 51 - 9
FuelCloud/Fuel.Application/Service/TransactionsService.cs

@@ -13,6 +13,11 @@ using FuelServer.Core.Entity;
 using Fuel.Core.Nozzle.Dto;
 using Org.BouncyCastle.Asn1.X509;
 using System.Linq.Expressions;
+using Fuel.Core.Models;
+using DFS.Core.Abstractions.View;
+using System.Net;
+using Fuel.Payment.Service.Pay;
+
 
 namespace Fuel.Application.Service
 {
@@ -20,15 +25,22 @@ namespace Fuel.Application.Service
     {
         private readonly EntityHelper _entityHelper;
         private readonly IHttpContextAccessor _httpContextAccessor;
-        public TransactionsService(EntityHelper entityHelper, IHttpContextAccessor httpContextAccessor)
+        private readonly IPayService _payService;
+        public TransactionsService(EntityHelper entityHelper, IHttpContextAccessor httpContextAccessor, IPayService payService)
         {
             _entityHelper = entityHelper;
             _httpContextAccessor = httpContextAccessor;
+            _payService = payService;
         }
 
-        public async Task<transactions> CreateTransactions(UploadTransactions uploadTransactions)
+        /// <summary>
+        /// 创建订单
+        /// </summary>
+        /// <param name="uploadTransactions"></param>
+        /// <returns></returns>
+        public async Task<ServiceResponse> CreateTransactions(UploadTransactions uploadTransactions)
         {
-            string Buid  = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
+            string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
             Guid guid = Guid.Parse(Buid);
             string key = string.Empty;
             if (uploadTransactions.Type == 1)//预支付
@@ -52,7 +64,7 @@ namespace Fuel.Application.Service
             transactions output = await GetRedisTransactions(uploadTransactions, key);
             if (output != null)
             {
-                return output;
+                return ServiceResponse.Ok(output);
             }
             var _product = await _entityHelper.GetEntitiesAsync<product>(_ => _.Buid == guid && _.ProductName == uploadTransactions.Product);
             var _nozzle = await _entityHelper.GetEntitiesAsync<nozzle>(_ => _.Buid == guid && _.ExternalGunNumber == uploadTransactions.NozzleId);
@@ -61,9 +73,9 @@ namespace Fuel.Application.Service
             string jsonString = JsonConvert.SerializeObject(respond);
 
             RedisHelper.SetAsync(key, jsonString, 3600);
-            return respond;
+            return ServiceResponse.Ok(respond);
         }
-        public async Task<List<transactions>> GetTransactionsAsync(TransactionsInput input)
+        public async Task<ServiceResponse> GetTransactionsAsync(TransactionsInput input)
         {
             string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
             Guid guid = Guid.Parse(Buid);
@@ -93,14 +105,44 @@ namespace Fuel.Application.Service
             {
                 where = CombineExpressions(where, p => p.ProductName == input.Product);
             }
-
-            return await _entityHelper.GetEntitiesAsync<transactions>(where);
+            var result = await _entityHelper.GetEntitiesAsync<transactions>(where);
+            return ServiceResponse.Ok(result);
+        }
+        /// <summary>
+        /// 提交支付
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<ServiceResponse> CommitPayment(int trxId, string AuthCode)
+        {
+            bool paymentOK = false;
+            var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Id == trxId).Result.FirstOrDefault();
+            if (trx == null)
+            {
+                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
+            }
+            var paytype = _entityHelper.GetEntitiesAsync<paytype>(_ => _.Id == trx.PaymentMethod).Result.FirstOrDefault();
+            string billNumber = SequenceNumber.Next();//订单编号
+            trx.TransactionNumber = billNumber;
+            decimal payDueAmount = (decimal)trx.OriginalAmount;
+            string Channel = paytype.Channel;
+            var serviceResult = await _payService.PerformElectronicProcess(AuthCode, payDueAmount, billNumber);
+            Payment.Core.Models.ElectronicOrderProcessResultModel payResult = (Payment.Core.Models.ElectronicOrderProcessResultModel)serviceResult.Data;
+            if (!serviceResult.IsSuccessful() || payResult.ResultCode == "PAY_ERROR")
+            {
+                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "支付失败");
+            }
+            trx.ActualPaymentAmount = payDueAmount;//实际支付金额
+            trx.ResultCode = payResult?.ResultCode;//支付成功应该为0
+            trx.ErrorDetail = payResult?.ErrorDetail;
+            _entityHelper.UpdateAsync(trx);
+            return ServiceResponse.Ok(trx);
         }
         /// <summary>
         /// 查询redis订单缓存
         /// </summary>
         /// <returns></returns>
-        public async Task<transactions> GetRedisTransactions(UploadTransactions uploadTransactions,string key)
+        public async Task<transactions> GetRedisTransactions(UploadTransactions uploadTransactions, string key)
         {
             string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
             var respond = RedisHelper.GetAsync(key).Result;

+ 1 - 0
FuelCloud/src/Fuel.Payment.Core/GenericProcessResponse.cs

@@ -17,5 +17,6 @@ namespace Fuel.Payment.Core
         public Dictionary<string, string> AllInPayResponse { get; set; }
         public TongLianResponseV2 AllInPayResponseV2 { get; set; }
         public ElectronicOrderModel electronicOrderModel { get; set; }
+        public  List<ElectronicOrderProcessResultModel> ProcessResults { get; set; }
     }
 }

+ 19 - 4
FuelCloud/src/Fuel.Payment.Server/Controllers/TransactionsController.cs

@@ -23,9 +23,10 @@ namespace Fuel.PaymentServer.Controllers
         /// <returns></returns>
         [Route("CreateTransactions")]
         [HttpPost]
-        public async Task<transactions> CreateTransactionsAsync(UploadTransactions uploadTransactions)
+        public async Task<IActionResult> CreateTransactionsAsync(UploadTransactions uploadTransactions)
         {
-            return await _transactionsService.CreateTransactions(uploadTransactions);
+            var serviceResult = await _transactionsService.CreateTransactions(uploadTransactions);
+            return Ok(serviceResult);
         }
         /// <summary>
         /// 查询订单
@@ -34,9 +35,23 @@ namespace Fuel.PaymentServer.Controllers
         /// <returns></returns>
         [Route("GetTransactions")]
         [HttpPost]
-        public async Task<List<transactions>> GetTransactionsAsync(TransactionsInput input)
+        public async Task<IActionResult> GetTransactionsAsync(TransactionsInput input)
         {
-            return await _transactionsService.GetTransactionsAsync(input);
+            var serviceResult = await _transactionsService.GetTransactionsAsync(input);
+            return Ok(serviceResult);
+        }
+        /// <summary>
+        /// 提交支付
+        /// </summary>
+        /// <param name="trxId"></param>
+        /// <param name="AuthCode"></param>
+        /// <returns></returns>
+        [Route("Payment")]
+        [HttpPost]
+        public async Task<IActionResult> CommitPayment(int trxId,string AuthCode)
+        {
+            var serviceResult = await _transactionsService.CommitPayment(trxId, AuthCode);
+            return Ok(serviceResult);
         }
     }
 }

+ 1 - 1
FuelCloud/src/Fuel.Payment.Server/Controllers/WeatherForecastController.cs

@@ -47,7 +47,7 @@ namespace Fuel.PaymentServer.Controllers
         [HttpPost(Name = "Payment")]
         public async Task<IActionResult> Payment(string AuthCode)
         {
-            await _payService.PerformElectronicProcess(AuthCode);
+            await _payService.PerformElectronicProcess(AuthCode,0.01M);
             return Ok(0);
         }
 

+ 4 - 1
FuelCloud/src/Fuel.Payment.Service/AllInPayProcessor/AllInPay/AllInPayProcessor.cs

@@ -138,10 +138,13 @@ namespace Fuel.Payment.Service.AllInPayProcessor.AllInPay
                     }
                 }
             }
-            return new GenericProcessResponse()
+            var Generic = new GenericProcessResponse()
             {
                 AllInPayResponse = response
             };
+            var ProcessResults = await PaymentResult(Generic, order);
+            Generic.ProcessResults = ProcessResults.ProcessResults;
+            return Generic;
         }
 
         private async Task<Dictionary<string, string>> QueryTrxResult(ElectronicOrderModel order, int interval = 3, int dueTime = 60)

+ 1 - 1
FuelCloud/src/Fuel.Payment.Service/Pay/IPayService.cs

@@ -10,7 +10,7 @@ namespace Fuel.Payment.Service.Pay
 {
     public interface IPayService
     {
-        Task<ServiceResponse> PerformElectronicProcess(string AuthCode);
+        Task<ServiceResponse> PerformElectronicProcess(string AuthCode, decimal payDueAmount, string Channel = "ALL_IN_SCAN", string preCreatedBillNumber = "");
             
     }
 }

+ 12 - 7
FuelCloud/src/Fuel.Payment.Service/Pay/PayService.cs

@@ -22,16 +22,22 @@ namespace Fuel.Payment.Service.Pay
         /// </summary>
         /// <param name="AuthCode"></param>
         /// <returns></returns>
-        public async Task<ServiceResponse> PerformElectronicProcess(string AuthCode)
+        public async Task<ServiceResponse> PerformElectronicProcess(string AuthCode,
+            decimal payDueAmount,
+            string Channel = "ALL_IN_SCAN",
+            string preCreatedBillNumber = "")
         {
-            string billNumber = SequenceNumber.Next();
+            if(string.IsNullOrEmpty(preCreatedBillNumber)) 
+            {
+                preCreatedBillNumber = SequenceNumber.Next();
+            }
             ElectronicOrderModel eOrder = new ElectronicOrderModel
             {
-                Channel = "ALL_IN_SCAN",
+                Channel = Channel,
                 IsRefund = false,
                 AuthCode = AuthCode,
-                BillNumber = billNumber,
-                NetAmount = 0.01M,
+                BillNumber = preCreatedBillNumber,
+                NetAmount = payDueAmount,
                 Title = "Wayne Payment",
                 FuelOrderDetails = new List<FuelOrderDetailModel>(),
                 OperatorId = "001",
@@ -42,9 +48,8 @@ namespace Fuel.Payment.Service.Pay
             //var payConfig = await eProcessor.Initialize(eOrder).ConfigureAwait(false);
             //eOrder.Config = payConfig.electronicOrderModel?.Config;
             var genericResponseAlipay = await eProcessor.Process(eOrder).ConfigureAwait(false);
-
             //var Result = await eProcessor.PaymentResult(genericResponseAlipay, eOrder).ConfigureAwait(false);
-            return new ServiceResponse { StatusCode = HttpStatusCode.OK, Data = genericResponseAlipay };
+            return new ServiceResponse { StatusCode = HttpStatusCode.OK, Data = genericResponseAlipay.ProcessResults.Last() };
         }
         private string GetPaymentChannelByPaymentId(PaymentID paymentID)
         {

+ 6 - 2
FuelCloud/src/FuelServer.Core/Entity/paytype.cs

@@ -24,7 +24,11 @@ namespace FuelServer.Core.Entity
 		/// </summary>
 		[JsonProperty, Column(StringLength = 100)]
 		public string Name { get; set; }
-
-	}
+        /// <summary>
+        ///
+        /// </summary>
+        [JsonProperty, Column(StringLength = 100)]
+        public string Channel { get; set; }
+    }
 
 }

+ 23 - 3
FuelCloud/src/FuelServer.Core/Entity/transactions.cs

@@ -97,8 +97,8 @@ namespace FuelServer.Core.Entity
 		/// <summary>
 		/// 支付方式
 		/// </summary>
-		[JsonProperty, Column(StringLength = 50)]
-		public string PaymentMethod { get; set; }
+		[JsonProperty]
+		public int PaymentMethod { get; set; }
 
 		/// <summary>
 		/// 油品名称
@@ -130,7 +130,27 @@ namespace FuelServer.Core.Entity
 		[JsonProperty, Column(DbType = "timestamp", InsertValueSql = "0000-00-00 00:00:00")]
 		public DateTime TransactionTime { get; set; }
 
-	}
+        /// <summary>
+        /// 加密字符串,用于验证金额是否篡改
+        /// </summary>
+        [JsonProperty, Column(StringLength = 255, IsNullable = false)]
+        public string secret { get; set; }
+        /// <summary>
+        /// 支付返回结果
+        /// </summary>
+        [JsonProperty, Column(StringLength = 500, IsNullable = false)]
+        public string RawResult { get; set; }
+        /// <summary>
+        /// 错误信息
+        /// </summary>
+        [JsonProperty, Column(StringLength = 500, IsNullable = false)]
+        public string ErrorDetail { get; set; }
+        /// <summary>
+        /// 支付结果代码
+        /// </summary>
+        [JsonProperty, Column(StringLength = 20, IsNullable = false)]
+        public string ResultCode { get; set; }
+    }
 
     public enum transactionsORDERSTATUS
     {

+ 55 - 0
FuelCloud/src/FuelServer.Core/Models/SequenceNumber.cs

@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Fuel.Core.Models
+{
+    public class SequenceNumber
+    {
+        private const int INIT_VALUE = 1;
+
+        private static readonly object obj = new object();
+        private static int counter = INIT_VALUE;
+        public static string Next()
+        {
+            lock (obj)
+            {
+                var now = DateTime.Now.ToString("yyyyMMddHHmmssfff");
+                var cnt = counter.ToString().PadLeft(11, '0');
+
+                if (counter >= int.MaxValue)
+                    counter = INIT_VALUE;
+                else
+                    counter++;
+
+                return now + cnt; // length of 28
+            }
+        }
+    }
+
+    public class SequenceNumber20
+    {
+        private const int INIT_VALUE = 1;
+        private const int MAX_VALUE = 999;
+
+        private static readonly object obj = new object();
+        private static int counter = INIT_VALUE;
+        public static string Next()
+        {
+            lock (obj)
+            {
+                var now = DateTime.Now.ToString("yyyyMMddHHmmssfff"); // length of 17
+                var cnt = counter.ToString().PadLeft(3, '0');
+
+                if (counter > MAX_VALUE)
+                    counter = INIT_VALUE;
+                else
+                    counter++;
+
+                return now + cnt; // length of 20
+            }
+        }
+    }
+}

+ 62 - 0
FuelCloud/src/FuelServer.Core/Models/ServiceResponse.cs

@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Fuel.Core.Models
+{
+    public class ServiceResponse
+    {
+        public HttpStatusCode StatusCode { get; set; }
+        public string Message { get; set; }
+        public object Data { get; set; }
+        public object Result { get; set; }
+        private bool Success { get; set; }
+        public bool IsSuccessful()
+        {
+            return StatusCode == HttpStatusCode.OK;
+        }
+        public ServiceResponse() { }
+        public ServiceResponse(HttpStatusCode statusCode, object data, string errorMsg = "")
+        {
+            StatusCode = statusCode;
+            Data = data;
+            Message = errorMsg;
+        }
+        public static ServiceResponse Ok(object data = null)
+        {
+            return new ServiceResponse(HttpStatusCode.OK, data);
+        }
+        public static ServiceResponse NotFound(string errorMsg = "")
+        {
+            return new ServiceResponse(HttpStatusCode.NotFound, null, errorMsg);
+        }
+        public static ServiceResponse Unauthorized(string errorMsg = "")
+        {
+            return new ServiceResponse(HttpStatusCode.Unauthorized, null, errorMsg);
+        }
+        public static ServiceResponse Forbidden(string errorMsg = "")
+        {
+            return new ServiceResponse(HttpStatusCode.Forbidden, null, errorMsg);
+        }
+        public static ServiceResponse BadRequest(string errorMsg = "")
+        {
+            return new ServiceResponse(HttpStatusCode.BadRequest, null, errorMsg);
+        }
+        public static ServiceResponse Error(string errorMsg = "")
+        {
+            return new ServiceResponse(HttpStatusCode.InternalServerError, null, errorMsg);
+        }
+        public static ServiceResponse Error(HttpStatusCode code, string errorMsg = "")
+        {
+            return new ServiceResponse(code, null, errorMsg);
+        }
+        public static ServiceResponse ValidateFailed(string errorMsg = "")
+        {
+            return new ServiceResponse(HttpStatusCode.NotAcceptable, null, errorMsg);
+        }
+    }
+
+}

+ 1 - 2
FuelCloud/src/FuelServer.Core/Transactions/Dto/UploadTransactions.cs

@@ -53,7 +53,7 @@ namespace Fuel.Core.Transactions.Dto
         /// <summary>
         /// 支付方式
         /// </summary>
-        public string PaymentMethod { get; set; }
+        public int PaymentMethod { get; set; }
 
         public transactions ToTransactions(UploadTransactions upload, Guid Buid, product product, nozzle nozzle)
         {
@@ -98,4 +98,3 @@ namespace Fuel.Core.Transactions.Dto
         }
     }
 }
-}