From ab9b84ee42c872cd2277d2e3a863718355bcc6aa Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期一, 15 十二月 2025 16:20:27 +0800
Subject: [PATCH] feat:开发

---
 ApiTools.Core/Models/ChannelWallets/Commands/TestNongYePayCommand.cs        |   17 +
 ApiTools.Core/Utils/StringUtils/StringUtils.cs                              |    1 
 ApiTools.Application/ApiTools.Application.xml                               |    8 
 ApiTools.Core/Utils/NongYePayUtils/NongYePayOptions.cs                      |   26 +
 ApiTools.Web.Entry/Startup.cs                                               |    3 
 ApiTools.Web.Entry/appsettings.json                                         |    5 
 ApiTools.Core/Utils/NongYePayUtils/NongYePayUtils.cs                        |  181 ++++++++++++
 ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs |   27 +
 ApiTools.Core/ApiTools.Core.xml                                             |  266 +++++++++++++++++
 ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayGetBalanceRequest.cs     |  137 +++++++++
 ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayBaseRequest.cs           |  180 ++++++++++++
 11 files changed, 848 insertions(+), 3 deletions(-)

diff --git a/ApiTools.Application/ApiTools.Application.xml b/ApiTools.Application/ApiTools.Application.xml
index 1663257..8f06091 100644
--- a/ApiTools.Application/ApiTools.Application.xml
+++ b/ApiTools.Application/ApiTools.Application.xml
@@ -165,6 +165,14 @@
             <param name="cancellationToken"></param>
             <returns></returns>
         </member>
+        <member name="M:ApiTools.Application.ChannelWalletCommandHandler.Handle(ApiTools.Core.TestNongYePayCommand,System.Threading.CancellationToken)">
+            <summary>
+            娴嬭瘯鍐滀笟閾惰鎺ュ彛
+            </summary>
+            <param name="request"></param>
+            <param name="cancellationToken"></param>
+            <returns></returns>
+        </member>
         <member name="T:ApiTools.Application.ChannelWalletQueryHandler">
             <summary>
             鏌ヨ娓犻亾閽卞寘浜ゆ槗璇︽儏
diff --git a/ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs b/ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
index 137684a..51d567d 100644
--- a/ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
+++ b/ApiTools.Application/ChannelWallets/Commands/ChannelWalletCommandHandler.cs
@@ -19,15 +19,18 @@
             IDistributedLockProvider distributedLockProvider,
             ChannelWalletRepository channelWalletRepository,
             ChannelWalletTransactionRepository channelWalletTransactionRepository,
-            ChannelWalletService channelWalletService
+            ChannelWalletService channelWalletService,
+            NongYePayUtils nongYePayUtils
         ) :
         IRequestHandler<SaveChannelPingAnPayWalletCommand, SaveChannelPingAnPayWalletCommandResult>,
-        IRequestHandler<SubmitChannelWalletTransferCommand, SubmitChannelWalletTransferCommandResult>
+        IRequestHandler<SubmitChannelWalletTransferCommand, SubmitChannelWalletTransferCommandResult>,
+        IRequestHandler<TestNongYePayCommand, bool>
     {
         private readonly IDistributedLockProvider distributedLockProvider = distributedLockProvider;
         private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository;
         private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository;
         private readonly ChannelWalletService channelWalletService = channelWalletService;
+        private readonly NongYePayUtils nongYePayUtils = nongYePayUtils;
 
         /// <summary>
         /// 淇濆瓨娓犻亾骞冲畨閾惰閽卞寘
@@ -171,5 +174,25 @@
                 FailReason = transaction.FailReason,
             };
         }
+
+        /// <summary>
+        /// 娴嬭瘯鍐滀笟閾惰鎺ュ彛
+        /// </summary>
+        /// <param name="request"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        public async Task<bool> Handle(TestNongYePayCommand request, CancellationToken cancellationToken)
+        {
+            var res = await nongYePayUtils.GetBalance(new Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceRequest
+            {
+                Cmp = new Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceRequestCmp
+                {
+                    AccountNo = "314101046433493",
+                    CurrencyCode = "01",
+                    ProvinceCode = "14"
+                }
+            });
+            return true;
+        }
     }
 }
diff --git a/ApiTools.Core/ApiTools.Core.xml b/ApiTools.Core/ApiTools.Core.xml
index ce92f10..1ee1549 100644
--- a/ApiTools.Core/ApiTools.Core.xml
+++ b/ApiTools.Core/ApiTools.Core.xml
@@ -2473,6 +2473,11 @@
             鏌ヨ鍒扮殑璁㈠崟鐘舵�佷负FAIL澶辫触鎴朢EFUND閫�绁ㄦ椂锛岃繑鍥炲叿浣撶殑鍘熷洜銆�
             </summary>
         </member>
+        <member name="T:ApiTools.Core.TestNongYePayCommand">
+            <summary>
+            娴嬭瘯鍐滀笟閾惰鎺ュ彛
+            </summary>
+        </member>
         <member name="T:ApiTools.Core.GetChannelPingAnPayWalletQuery">
             <summary>
             鏌ヨ娓犻亾骞冲畨閾惰閽卞寘
@@ -4937,6 +4942,231 @@
             </summary>
             <returns></returns>
         </member>
+        <member name="T:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest">
+            <summary>
+            鍐滀笟閾惰鏀粯鍩虹璇锋眰
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.TransCode">
+            <summary>
+            浜ゆ槗鐮�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.CorpNo">
+            <summary>
+            瀹㈡埛鍙�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.OpNo">
+            <summary>
+            鎿嶄綔鍛業D锛堢┖鑺傜偣锛孖CT鑷姩琛ュ厖锛�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.AuthNo">
+            <summary>
+            璁よ瘉鐮侊紙绌鸿妭鐐癸紝ICT鑷姩琛ュ厖锛�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.ChannelType">
+            <summary>
+            娓犻亾鏍囪瘑
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.ProductID">
+            <summary>
+            浜у搧鏍囪瘑
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.ReqDate">
+            <summary>
+            璇锋眰鏃ユ湡锛圷YYYMMDD锛�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.ReqTime">
+            <summary>
+            璇锋眰鏃堕棿锛圚HMMSS锛�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.ReqSeqNo">
+            <summary>
+            璇锋眰娴佹按鍙凤紙鍏ㄥ眬鍞竴锛�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseRequest.Sign">
+            <summary>
+            鏁板瓧绛惧悕锛堢┖鑺傜偣锛孖CT鑷姩琛ュ厖锛�
+            </summary>
+        </member>
+        <member name="T:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse">
+            <summary>
+            鍐滀笟閾惰鏀粯鍩虹鍥炶皟
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.TransCode">
+            <summary>
+            浜ゆ槗鐮�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.RespSource">
+            <summary>
+            杩斿洖鏉ユ簮锛�0=鎴愬姛锛�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.RespSeqNo">
+            <summary>
+            搴旂瓟娴佹按鍙�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.RespCode">
+            <summary>
+            杩斿洖鐮侊紙0000=鍙楃悊鎴愬姛锛�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.RespInfo">
+            <summary>
+            杩斿洖淇℃伅
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.RxtInfo">
+            <summary>
+            鎵╁睍淇℃伅
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.RespDate">
+            <summary>
+            搴旂瓟鏃ユ湡
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.RespTime">
+            <summary>
+            搴旂瓟鏃堕棿
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.FileFlag">
+            <summary>
+            鏂囦欢鏍囪瘑
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.Cmp">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponse.Cme">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="T:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponseCme">
+            <summary>
+            鍐滀笟閾惰鏀粯鍩虹鍥炶皟
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponseCme.RecordNum">
+            <summary>
+            璁板綍鏁帮紙琛岋級
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponseCme.FieldNum">
+            <summary>
+            瀛楁鏁帮紙鍒楋級
+            </summary>
+        </member>
+        <member name="T:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponseCmp">
+            <summary>
+            鍐滀笟閾惰鏀粯鍩虹鍥炶皟
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponseCmp.BatFileName">
+            <summary>
+            鏂囦欢鍚�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayBaseResponseCmp.RespPrvData">
+            <summary>
+            绉佹湁鏁版嵁鍖�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceRequest.Cmp">
+            <summary>
+            涓氬姟鏁版嵁
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceRequestCmp.ProvinceCode">
+            <summary>
+            鐪佸競浠g爜
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceRequestCmp.AccountNo">
+            <summary>
+            鏌ヨ璐﹀彿
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceRequestCmp.CurrencyCode">
+            <summary>
+            璐у竵鐮�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseCorp.DbAccName">
+            <summary>
+            鍊熸柟鎴峰悕
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.Bal">
+            <summary>
+            璐︽埛浣欓
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.AvailBal">
+            <summary>
+            璐︽埛鍙敤浣欓
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.FrzAmt">
+            <summary>
+            鍐荤粨閲戦
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.FrzBal">
+            <summary>
+            鍐荤粨浣欓
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.ValUDLmt">
+            <summary>
+            涓嶅畾鏈熷彲鐢ㄩ檺棰�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.ValMonthLmt">
+            <summary>
+            鏈堝彲鐢ㄩ檺棰�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.ValDayLmt">
+            <summary>
+            鏃ュ彲鐢ㄩ檺棰�
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.LastAvailBal">
+            <summary>
+            鏄ㄦ棩鍙敤浣欓
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.LastBal">
+            <summary>
+            鏄ㄦ棩浣欓
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.AccType">
+            <summary>
+            璐︽埛绫诲瀷
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceResponseAcc.AccSts">
+            <summary>
+            璐︽埛鐘舵��
+            </summary>
+        </member>
         <member name="T:ApiTools.Core.Utils.WxmpUtils.WxmpGetAccessTokenRequest">
             <summary>
             寰俊灏忕▼搴忚幏鍙栨帴鍙h皟鐢ㄥ嚟鎹�
@@ -5057,6 +5287,42 @@
             </summary>
             <returns></returns>
         </member>
+        <member name="P:ApiTools.Core.NongYePayOptions.Ip">
+            <summary>
+            ICT IP鍦板潃
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.NongYePayOptions.Port">
+            <summary>
+            ICP 绔彛
+            </summary>
+        </member>
+        <member name="P:ApiTools.Core.NongYePayOptions.CorpNo">
+            <summary>
+            瀹㈡埛鍙�
+            </summary>
+        </member>
+        <member name="M:ApiTools.Core.NongYePayUtils.GetBalance(ApiTools.Core.Utils.NongYePayUtils.Models.NongYePayGetBalanceRequest)">
+            <summary>
+            鏌ヨ璐︽埛浣欓
+            </summary>
+            <returns>浣欓淇℃伅</returns>
+        </member>
+        <member name="M:ApiTools.Core.NongYePayUtils.SerializeRequest``1(``0)">
+            <summary>
+            娉涘瀷璇锋眰绫昏浆XML
+            </summary>
+        </member>
+        <member name="M:ApiTools.Core.NongYePayUtils.DeserializeResponse``1(System.String)">
+            <summary>
+            XML杞硾鍨嬪簲绛旂被
+            </summary>
+        </member>
+        <member name="M:ApiTools.Core.NongYePayUtils.SendRequest(System.String)">
+            <summary>
+            鍙戦�佽姹傚苟鎺ユ敹搴旂瓟
+            </summary>
+        </member>
         <member name="T:ApiTools.Core.PasswordUtils">
             <summary>
             瀵嗙爜宸ュ叿
diff --git a/ApiTools.Core/Models/ChannelWallets/Commands/TestNongYePayCommand.cs b/ApiTools.Core/Models/ChannelWallets/Commands/TestNongYePayCommand.cs
new file mode 100644
index 0000000..d08f348
--- /dev/null
+++ b/ApiTools.Core/Models/ChannelWallets/Commands/TestNongYePayCommand.cs
@@ -0,0 +1,17 @@
+锘縰sing MediatR;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ApiTools.Core
+{
+    /// <summary>
+    /// 娴嬭瘯鍐滀笟閾惰鎺ュ彛
+    /// </summary>
+    [Resource([EnumResourceController.UserServerChannelWallet])]
+    public class TestNongYePayCommand : IRequest<bool>
+    {
+    }
+}
diff --git a/ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayBaseRequest.cs b/ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayBaseRequest.cs
new file mode 100644
index 0000000..496ea97
--- /dev/null
+++ b/ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayBaseRequest.cs
@@ -0,0 +1,180 @@
+锘縰sing Org.BouncyCastle.Ocsp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+
+namespace ApiTools.Core.Utils.NongYePayUtils.Models
+{
+    /// <summary>
+    /// 鍐滀笟閾惰鏀粯鍩虹璇锋眰
+    /// </summary>
+    [XmlRoot("ap")]
+    public abstract class NongYePayBaseRequest
+    {
+        /// <summary>
+        /// 浜ゆ槗鐮�
+        /// </summary>
+        [XmlElement("CCTransCode")]
+        public string TransCode { get; set; }
+
+        /// <summary>
+        /// 瀹㈡埛鍙�
+        /// </summary>
+        [XmlElement("CorpNo")]
+        public string CorpNo { get; set; }
+
+        /// <summary>
+        /// 鎿嶄綔鍛業D锛堢┖鑺傜偣锛孖CT鑷姩琛ュ厖锛�
+        /// </summary>
+        [XmlElement("OpNo")]
+        public string OpNo { get; set; }
+
+        /// <summary>
+        /// 璁よ瘉鐮侊紙绌鸿妭鐐癸紝ICT鑷姩琛ュ厖锛�
+        /// </summary>
+        [XmlElement("AuthNo")]
+        public string AuthNo { get; set; }
+
+        /// <summary>
+        /// 娓犻亾鏍囪瘑
+        /// </summary>
+        [XmlElement("ChannelType")]
+        public string ChannelType { get; set; }
+
+        /// <summary>
+        /// 浜у搧鏍囪瘑
+        /// </summary>
+        [XmlElement("ProductID")]
+        public string ProductID { get; set; }
+
+        /// <summary>
+        /// 璇锋眰鏃ユ湡锛圷YYYMMDD锛�
+        /// </summary>
+        [XmlElement("ReqDate")]
+        public string ReqDate { get; set; }
+
+        /// <summary>
+        /// 璇锋眰鏃堕棿锛圚HMMSS锛�
+        /// </summary>
+        [XmlElement("ReqTime")]
+        public string ReqTime { get; set; }
+
+        /// <summary>
+        /// 璇锋眰娴佹按鍙凤紙鍏ㄥ眬鍞竴锛�
+        /// </summary>
+        [XmlElement("ReqSeqNo")]
+        public string ReqSeqNo { get; set; }
+
+        /// <summary>
+        /// 鏁板瓧绛惧悕锛堢┖鑺傜偣锛孖CT鑷姩琛ュ厖锛�
+        /// </summary>
+        [XmlElement("Sign")]
+        public string Sign { get; set; }
+    }
+
+    /// <summary>
+    /// 鍐滀笟閾惰鏀粯鍩虹鍥炶皟
+    /// </summary>
+    [XmlRoot("ap")]
+    public abstract class NongYePayBaseResponse
+    {
+        /// <summary>
+        /// 浜ゆ槗鐮�
+        /// </summary>
+        [XmlElement("CCTransCode")]
+        public string TransCode { get; set; }
+
+        /// <summary>
+        /// 杩斿洖鏉ユ簮锛�0=鎴愬姛锛�
+        /// </summary>
+        [XmlElement("RespSource")]
+        public string RespSource { get; set; }
+
+        /// <summary>
+        /// 搴旂瓟娴佹按鍙�
+        /// </summary>
+        [XmlElement("RespSeqNo")]
+        public string RespSeqNo { get; set; }
+
+        /// <summary>
+        /// 杩斿洖鐮侊紙0000=鍙楃悊鎴愬姛锛�
+        /// </summary>
+        [XmlElement("RespCode")]
+        public string RespCode { get; set; }
+
+        /// <summary>
+        /// 杩斿洖淇℃伅
+        /// </summary>
+        [XmlElement("RespInfo")]
+        public string RespInfo { get; set; }
+
+        /// <summary>
+        /// 鎵╁睍淇℃伅
+        /// </summary>
+        [XmlElement("RxtInfo")]
+        public string RxtInfo { get; set; }
+
+        /// <summary>
+        /// 搴旂瓟鏃ユ湡
+        /// </summary>
+        [XmlElement("RespDate")]
+        public string RespDate { get; set; }
+
+        /// <summary>
+        /// 搴旂瓟鏃堕棿
+        /// </summary>
+        [XmlElement("RespTime")]
+        public string RespTime { get; set; }
+
+        /// <summary>
+        /// 鏂囦欢鏍囪瘑
+        /// </summary>
+        [XmlElement("FileFlag")]
+        public string FileFlag { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public NongYePayBaseResponseCmp Cmp { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        public NongYePayBaseResponseCme Cme { get; set; }
+    }
+
+    /// <summary>
+    /// 鍐滀笟閾惰鏀粯鍩虹鍥炶皟
+    /// </summary>
+    public class NongYePayBaseResponseCme
+    {
+        /// <summary>
+        /// 璁板綍鏁帮紙琛岋級
+        /// </summary>
+        public string RecordNum { get; set; }
+
+        /// <summary>
+        /// 瀛楁鏁帮紙鍒楋級
+        /// </summary>
+        public string FieldNum { get; set; }
+    }
+
+    /// <summary>
+    /// 鍐滀笟閾惰鏀粯鍩虹鍥炶皟
+    /// </summary>
+    public class NongYePayBaseResponseCmp
+    {
+        /// <summary>
+        /// 鏂囦欢鍚�
+        /// </summary>
+        public string BatFileName { get; set; }
+
+        /// <summary>
+        /// 绉佹湁鏁版嵁鍖�
+        /// </summary>
+        public string RespPrvData { get; set; }
+    }
+}
diff --git a/ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayGetBalanceRequest.cs b/ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayGetBalanceRequest.cs
new file mode 100644
index 0000000..7852d9d
--- /dev/null
+++ b/ApiTools.Core/Utils/NongYePayUtils/Models/NongYePayGetBalanceRequest.cs
@@ -0,0 +1,137 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+
+namespace ApiTools.Core.Utils.NongYePayUtils.Models
+{
+    [XmlRoot("ap")]
+    public class NongYePayGetBalanceRequest : NongYePayBaseRequest
+    {
+        public NongYePayGetBalanceRequest()
+        {
+            TransCode = "CQRA06";
+        }
+
+        /// <summary>
+        /// 涓氬姟鏁版嵁
+        /// </summary>
+        [XmlElement("Cmp")]
+        public NongYePayGetBalanceRequestCmp Cmp { get; set; }
+    }
+
+    public class NongYePayGetBalanceRequestCmp
+    {
+        /// <summary>
+        /// 鐪佸競浠g爜
+        /// </summary>
+        [XmlElement("DbProv")]
+        public string ProvinceCode { get; set; }
+
+        /// <summary>
+        /// 鏌ヨ璐﹀彿
+        /// </summary>
+        [XmlElement("DbAccNo")]
+        public string AccountNo { get; set; }
+
+        /// <summary>
+        /// 璐у竵鐮�
+        /// </summary>
+        [XmlElement("DbCur")]
+        public string CurrencyCode { get; set; }
+    }
+
+    [XmlRoot("ap")]
+    public class NongYePayGetBalanceResponse : NongYePayBaseResponse
+    {
+        [XmlElement("Acc")]
+        public NongYePayGetBalanceResponseAcc Acc { get; set; }
+
+        [XmlElement("Corp")]
+        public NongYePayGetBalanceResponseCorp Corp { get; set; }
+    }
+
+    public class NongYePayGetBalanceResponseCorp
+    {
+        /// <summary>
+        /// 鍊熸柟鎴峰悕
+        /// </summary>
+        [XmlElement("DbAccName")]
+        public string DbAccName { get; set; }
+
+        [XmlElement("UseState")]
+        public string UseState { get; set; }
+    }
+
+    public class NongYePayGetBalanceResponseAcc
+    {
+        /// <summary>
+        /// 璐︽埛浣欓
+        /// </summary>
+        [XmlElement("Bal")]
+        public string Bal { get; set; }
+
+        /// <summary>
+        /// 璐︽埛鍙敤浣欓
+        /// </summary>
+        [XmlElement("AvailBal")]
+        public string AvailBal { get; set; }
+
+        /// <summary>
+        /// 鍐荤粨閲戦
+        /// </summary>
+        [XmlElement("FrzAmt")]
+        public string FrzAmt { get; set; }
+
+        /// <summary>
+        /// 鍐荤粨浣欓
+        /// </summary>
+        [XmlElement("FrzBal")]
+        public string FrzBal { get; set; }
+
+        /// <summary>
+        /// 涓嶅畾鏈熷彲鐢ㄩ檺棰�
+        /// </summary>
+        [XmlElement("ValUDLmt")]
+        public string ValUDLmt { get; set; }
+
+        /// <summary>
+        /// 鏈堝彲鐢ㄩ檺棰�
+        /// </summary>
+        [XmlElement("ValMonthLmt")]
+        public string ValMonthLmt { get; set; }
+
+        /// <summary>
+        /// 鏃ュ彲鐢ㄩ檺棰�
+        /// </summary>
+        [XmlElement("ValDayLmt")]
+        public string ValDayLmt { get; set; }
+
+        /// <summary>
+        /// 鏄ㄦ棩鍙敤浣欓
+        /// </summary>
+        [XmlElement("LastAvailBal")]
+        public string LastAvailBal { get; set; }
+
+        /// <summary>
+        /// 鏄ㄦ棩浣欓
+        /// </summary>
+        [XmlElement("LastBal")]
+        public string LastBal { get; set; }
+
+        /// <summary>
+        /// 璐︽埛绫诲瀷
+        /// </summary>
+        [XmlElement("AccType")]
+        public string AccType { get; set; }
+
+        /// <summary>
+        /// 璐︽埛鐘舵��
+        /// </summary>
+        [XmlElement("AccSts")]
+        public string AccSts { get; set; }
+
+    }
+}
diff --git a/ApiTools.Core/Utils/NongYePayUtils/NongYePayOptions.cs b/ApiTools.Core/Utils/NongYePayUtils/NongYePayOptions.cs
new file mode 100644
index 0000000..2273dc0
--- /dev/null
+++ b/ApiTools.Core/Utils/NongYePayUtils/NongYePayOptions.cs
@@ -0,0 +1,26 @@
+锘縰sing Furion.ConfigurableOptions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ApiTools.Core
+{
+    public class NongYePayOptions : IConfigurableOptions
+    {
+        /// <summary>
+        /// ICT IP鍦板潃
+        /// </summary>
+        public string Ip { get; set; }
+        /// <summary>
+        /// ICP 绔彛
+        /// </summary>
+        public int Port { get; set; }
+
+        /// <summary>
+        /// 瀹㈡埛鍙�
+        /// </summary>
+        public string CorpNo { get; set; }
+    }
+}
diff --git a/ApiTools.Core/Utils/NongYePayUtils/NongYePayUtils.cs b/ApiTools.Core/Utils/NongYePayUtils/NongYePayUtils.cs
new file mode 100644
index 0000000..42650ad
--- /dev/null
+++ b/ApiTools.Core/Utils/NongYePayUtils/NongYePayUtils.cs
@@ -0,0 +1,181 @@
+锘縰sing Aop.Api.Domain;
+using ApiTools.Core.Utils.NongYePayUtils.Models;
+using Furion;
+using Furion.DatabaseAccessor;
+using Furion.DependencyInjection;
+using Furion.DistributedIDGenerator;
+using Furion.FriendlyException;
+using Microsoft.Extensions.Options;
+using NetTopologySuite.Algorithm;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace ApiTools.Core
+{
+    public class NongYePayUtils(
+            IOptions<NongYePayOptions> options,
+            IRepository<ThreeResourceLog, LogDbContextLocator> repThreeResourceLog
+        ) : ITransient
+    {
+        private readonly IOptions<NongYePayOptions> options = options;
+        private readonly IRepository<ThreeResourceLog, LogDbContextLocator> repThreeResourceLog = repThreeResourceLog;
+
+        /// <summary>
+        /// 鏌ヨ璐︽埛浣欓
+        /// </summary>
+        /// <returns>浣欓淇℃伅</returns>
+        public Task<NongYePayGetBalanceResponse> GetBalance(NongYePayGetBalanceRequest request)
+        {
+            return Send<NongYePayGetBalanceRequest, NongYePayGetBalanceResponse>(request);
+        }
+
+        private async Task<TResponse> Send<TRequest, TResponse>(TRequest request)
+            where TRequest : NongYePayBaseRequest
+            where TResponse : NongYePayBaseResponse
+        {
+            var logier = JwtUtils.GetCurrentLogier();
+            var now = DateTime.Now;
+            var random = StringUtils.GenerateRandomString(6);
+            request.CorpNo = options.Value.CorpNo;
+            request.ReqDate = now.ToString("yyyyMMdd");
+            request.ReqTime = now.ToString("HHmmss");
+            request.ReqSeqNo = $"{now:yyyyMMddHHmmssfff}{random}";
+            request.ChannelType = "ERP";
+            request.ProductID = "ICC";
+
+            string requestXml = SerializeRequest(request);
+            var log = new ThreeResourceLog
+            {
+                CreatedTime = DateTimeOffset.Now,
+                Id = IDGen.NextID(),
+                TraceId = App.GetTraceId(),
+                Method = EnumResourceMethod.Post,
+                Domain = $"{options.Value.Ip}:{options.Value.Port}",
+                Path = request.TransCode,
+                CreatedUserId = logier?.Id,
+                CreatedChannelId = logier?.ChannelId,
+                Request = request.ToJson(),
+            };
+            await repThreeResourceLog.InsertNowAsync(log);
+            var stopwatch = Stopwatch.StartNew();
+            var responseXml = await SendRequest(requestXml);
+            stopwatch.Stop();
+            var response = DeserializeResponse<TResponse>(responseXml);
+            log.UpdatedTime = DateTimeOffset.Now;
+            log.Response = responseXml;
+            log.IsSuccess = response.RespSource == "0";
+            log.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
+            await repThreeResourceLog.UpdateNowAsync(log);
+
+            if (!log.IsSuccess) throw Oops.Oh(EnumErrorCodeType.s510, $"鍐滆鎺ュ彛寮傚父锛歿response.RespInfo}");
+
+            return response;
+        }
+
+        /// <summary>
+        /// 娉涘瀷璇锋眰绫昏浆XML
+        /// </summary>
+        private string SerializeRequest<T>(T request)
+        {
+            var serializer = new XmlSerializer(typeof(T));
+            var ns = new XmlSerializerNamespaces();
+            ns.Add("", "");
+
+            var settings = new XmlWriterSettings
+            {
+                OmitXmlDeclaration = true,
+                Indent = false,
+                Encoding = Encoding.UTF8
+            };
+
+            using var stream = new MemoryStream();
+            using var writer = XmlWriter.Create(stream, settings);
+            serializer.Serialize(writer, request, ns);
+
+            // 杞崲涓篏BK缂栫爜
+            stream.Position = 0;
+            using var reader = new StreamReader(stream, Encoding.UTF8);
+            string utf8Xml = reader.ReadToEnd();
+            return Encoding.GetEncoding("GBK").GetString(Encoding.GetEncoding("GBK").GetBytes(utf8Xml));
+        }
+
+        /// <summary>
+        /// XML杞硾鍨嬪簲绛旂被
+        /// </summary>
+        private T DeserializeResponse<T>(string gbkXml)
+        {
+            var serializer = new XmlSerializer(typeof(T));
+            using var stream = new MemoryStream(Encoding.UTF8.GetBytes(gbkXml));
+            return (T)serializer.Deserialize(stream);
+        }
+
+        /// <summary>
+        /// 鍙戦�佽姹傚苟鎺ユ敹搴旂瓟
+        /// </summary>
+        private async Task<string> SendRequest(string requestXml)
+        {
+            byte[] requestBytes = Encoding.GetEncoding("GBK").GetBytes(requestXml);
+
+            // 2. 鏋勫缓7瀛楄妭鍖呭ご锛堝姞瀵嗘爣蹇�0 + 鏁版嵁闀垮害锛屽彸琛ョ┖鏍硷級
+            byte[] header = new byte[7];
+            header[0] = 0x30; // 鍔犲瘑鏍囧織锛�0锛圓SCII鐮侊級
+            string requestLengthStr = requestBytes.Length.ToString().PadRight(6, ' '); // 鍚�6瀛楄妭锛氶暱搴﹀彸琛ョ┖鏍�
+            Buffer.BlockCopy(Encoding.ASCII.GetBytes(requestLengthStr), 0, header, 1, 6);
+
+            // 3. 鍚堝苟鍖呭ご+鏁版嵁鍖�
+            byte[] sendData = new byte[header.Length + requestBytes.Length];
+            Buffer.BlockCopy(header, 0, sendData, 0, header.Length);
+            Buffer.BlockCopy(requestBytes, 0, sendData, header.Length, requestBytes.Length);
+
+            // 4. Socket鍙戦�侊紙甯﹁秴鏃讹級
+            using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+            socket.SendTimeout = (int)TimeSpan.FromMinutes(5).TotalMilliseconds;
+            socket.ReceiveTimeout = (int)TimeSpan.FromMinutes(5).TotalMilliseconds;
+
+            try
+            {
+                await socket.ConnectAsync(options.Value.Ip, options.Value.Port);
+                await socket.SendAsync(sendData);
+
+                // 鎺ユ敹鍖呭ご
+                byte[] responseHeader = new byte[7];
+                int headerLen = socket.Receive(responseHeader);
+                if (headerLen != 7) throw Oops.Oh(EnumErrorCodeType.s510, "鎺ユ敹鍖呭ご澶辫触");
+
+                // 瑙f瀽鏁版嵁闀垮害
+                string lengthStr = Encoding.ASCII.GetString(responseHeader, 1, 6).Trim();
+                if (!int.TryParse(lengthStr, out int dataLength))
+                    throw Oops.Oh(EnumErrorCodeType.s510, $"瑙f瀽鏁版嵁闀垮害澶辫触锛歿lengthStr}");
+
+                // 鎺ユ敹鏁版嵁鍖�
+                byte[] responseBytes = new byte[dataLength];
+                int receivedLen = 0;
+                while (receivedLen < dataLength)
+                {
+                    int len = socket.Receive(responseBytes, receivedLen, dataLength - receivedLen, SocketFlags.None);
+                    receivedLen += len;
+                }
+
+                // 杞崲涓篏BK XML
+                var responseXml = Encoding.GetEncoding("GBK").GetString(responseBytes);
+                if (responseXml.IsNull())
+                {
+                    throw Oops.Oh(EnumErrorCodeType.s510, "鏈敹鍒板簲绛�");
+                }
+                return responseXml;
+            }
+            finally
+            {
+                socket.Dispose();
+            }
+        }
+    }
+}
diff --git a/ApiTools.Core/Utils/StringUtils/StringUtils.cs b/ApiTools.Core/Utils/StringUtils/StringUtils.cs
index 76fbf93..7304d08 100644
--- a/ApiTools.Core/Utils/StringUtils/StringUtils.cs
+++ b/ApiTools.Core/Utils/StringUtils/StringUtils.cs
@@ -166,5 +166,6 @@
             }
             return result.ToString();
         }
+
     }
 }
diff --git a/ApiTools.Web.Entry/Startup.cs b/ApiTools.Web.Entry/Startup.cs
index 0a4ec9c..01d69a4 100644
--- a/ApiTools.Web.Entry/Startup.cs
+++ b/ApiTools.Web.Entry/Startup.cs
@@ -27,7 +27,8 @@
             services.AddConfigurableOptions<WxmpOptions>();
             services.AddConfigurableOptions<WeChatPayOptions>();
             services.AddConfigurableOptions<AlipayOptions>();
-            services.AddConfigurableOptions<PingAnPayOptions>(); 
+            services.AddConfigurableOptions<PingAnPayOptions>();
+            services.AddConfigurableOptions<NongYePayOptions>();
             services.AddConfigurableOptions<ChengLiYeSmsOptions>();
             services.AddConfigurableOptions<AliyunOptions>();
             services.AddConfigurableOptions<BaiduOptions>();
diff --git a/ApiTools.Web.Entry/appsettings.json b/ApiTools.Web.Entry/appsettings.json
index d837641..9ee8c41 100644
--- a/ApiTools.Web.Entry/appsettings.json
+++ b/ApiTools.Web.Entry/appsettings.json
@@ -96,6 +96,11 @@
   "PingAnPay": {
     "MrChCode": "0040107980000NBCS000"
   },
+  "NongYePay": {
+    "Ip": "183.242.60.51",
+    "Port": 14028,
+    "CorpNo": "14314153600000025"
+  },
   "ChengLiYeSms": {
     "UserName": "nbcsxx",
     "Password": "8af9s7",

--
Gitblit v1.9.1