From 7b47c91bcf89d667a5c99cfafe0d899280f7fbe3 Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期三, 19 十一月 2025 11:22:27 +0800
Subject: [PATCH] feat:平安转账开发

---
 ApiTools.Core/Services/ChannelPingAnPayWalletService.cs |  298 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 298 insertions(+), 0 deletions(-)

diff --git a/ApiTools.Core/Services/ChannelPingAnPayWalletService.cs b/ApiTools.Core/Services/ChannelPingAnPayWalletService.cs
new file mode 100644
index 0000000..628ecc6
--- /dev/null
+++ b/ApiTools.Core/Services/ChannelPingAnPayWalletService.cs
@@ -0,0 +1,298 @@
+锘縰sing Aop.Api.Domain;
+using Furion.DatabaseAccessor;
+using Furion.DependencyInjection;
+using Furion.DistributedIDGenerator;
+using Furion.FriendlyException;
+using Mapster;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Identity.Client;
+using NetTopologySuite.Index.HPRtree;
+using Org.BouncyCastle.Ocsp;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection.Metadata;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ApiTools.Core
+{
+    public class ChannelPingAnPayWalletService(
+            ChannelWalletRepository channelWalletRepository,
+            ChannelWalletTransactionRepository channelWalletTransactionRepository,
+            PingAnPayUtils utils
+        ) :
+        IChannelWalletService, ITransient
+    {
+        private readonly ChannelWalletRepository channelWalletRepository = channelWalletRepository;
+        private readonly ChannelWalletTransactionRepository channelWalletTransactionRepository = channelWalletTransactionRepository;
+        private readonly PingAnPayUtils utils = utils;
+
+        /// <summary>
+        /// 鏌ヨ浼佷笟閽卞寘浣欓
+        /// </summary>
+        /// <param name="wallet"></param>
+        /// <returns></returns>
+        public async Task<ChannelWallet> GetEnterpriseWalletBalance(ChannelWallet wallet)
+        {
+            if (wallet != null
+                && wallet.Identity.IsNotNull())
+            {
+                var response = await utils.CorAcctBalanceQuery(new CorAcctBalanceQueryRequest
+                {
+                    Account = wallet.Identity,
+                    CcyCode = "RMB",
+                });
+                if (response.Code.IsNotNull())
+                {
+                    wallet.Balance = 0;
+                    wallet.ErrorCode = response.Code;
+                    wallet.FailReason = response.Message;
+                }
+                else
+                {
+                    wallet.ErrorCode = null;
+                    wallet.FailReason = null;
+                    wallet.SignStatus = EnumWalletSignStatus.Normal;
+                    wallet.Balance = response.AcctBalance.ToDecimal().Value;
+                }
+            }
+            return wallet;
+        }
+
+        /// <summary>
+        /// 杞处
+        /// </summary>
+        /// <param name="wallet"></param>
+        /// <param name="transaction"></param>
+        /// <returns></returns>
+        public async Task Transfer(ChannelWallet wallet, ChannelWalletTransaction transaction)
+        {
+            transaction.PingAnPay = new ChannelWalletTransactionPingAnPay();
+            var responseStop = await utils.StopPaymentAndSettlementAccounts(new StopPaymentAndSettlementAccountsRequest
+            {
+                CnsmrSeqNo = transaction.Code,
+                AccountNo = transaction.PayerAccount,
+                OpType = "A",
+                CcyCode = "RMB",
+                SeqNo = $"{DateTime.Now:yyyyMMddHHmmssfff}{new Random(IDGen.NextID().GetHashCode()).Next(100, 999)}",
+                TradeDate = DateTime.Now.ToString("yyyyMMdd").ToInt()!.Value,
+                TradeTime = DateTime.Now.ToString("HHmmss").ToInt()!.Value,
+            });
+            if (responseStop.Code.IsNotNull())
+            {
+                transaction.ErrorCode = responseStop.Code;
+                transaction.FailReason = responseStop.Errors?.FirstOrDefault()?.ErrorMessage ?? responseStop.Message;
+                transaction.PingAnPay.StopStt = "30";
+                transaction.PingAnPay.StopFailReason = transaction.FailReason;
+                await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+            }
+            else
+            {
+                if (responseStop.StopPayFlw.IsNotNull() && responseStop.Stt == "20")
+                {
+                    transaction.PingAnPay.FreezeNo = responseStop.StopPayFlw;
+                }
+                else
+                {
+                    var responseStopDetail = await utils.InquiryAccountStopPaymentDetails(new InquiryAccountStopPaymentDetailsRequest
+                    {
+                        CnsmrSeqNo = transaction.Code,
+                        AccountNo = transaction.PayerAccount,
+                        PageNo = "1",
+                    });
+                    if (responseStopDetail.Code.IsNotNull())
+                    {
+                        transaction.ErrorCode = responseStopDetail.Code;
+                        transaction.FailReason = responseStopDetail.Errors?.FirstOrDefault()?.ErrorMessage ?? responseStopDetail.Message;
+                        await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+                    }
+                    else if (responseStopDetail.List.IsNotNull())
+                    {
+                        transaction.PingAnPay.FreezeNo = responseStopDetail.List.FirstOrDefault(it => it.FreezeStatu == "0")?.StopPayFlw;
+                    }
+                    else
+                    {
+                        transaction.FailReason = "姝粯澶辫触骞舵湭鏌ヨ鍒版浠樼紪鍙�";
+                        await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+                    }
+                }
+            }
+            if (transaction.PingAnPay.FreezeNo.IsNotNull())
+            {
+                transaction.PingAnPay.ThirdVoucher = transaction.Code;
+                await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+
+                var responsePayment = await utils.SingleApplicationSuspensionPayment(new SingleApplicationSuspensionPaymentRequest
+                {
+                    CcyCode = "RMB",
+                    CnsmrSeqNo = transaction.Code,
+                    FreezeNo = transaction.PingAnPay.FreezeNo,
+                    ThirdVoucher = transaction.Code,
+                    OutAcctName = wallet.Name,
+                    OutAcctNo = wallet.Identity,
+                    InAcctBankName = transaction.ReceiveBank,
+                    InAcctName = transaction.ReceiveName,
+                    InAcctNo = transaction.ReceiveAccount,
+                    TranAmount = transaction.Amount.ToString(),
+                    UseEx = transaction.Purpose,
+                    UnionFlag = wallet.Bank == transaction.ReceiveBank ? "1" : "0",
+                    AddrFlag = "1"
+                });
+                if (responsePayment.Code.IsNotNull())
+                {
+                    transaction.ErrorCode = responsePayment.Code;
+                    transaction.FailReason = responsePayment.Errors?.FirstOrDefault()?.ErrorMessage ?? responsePayment.Message;
+                    transaction.TransactionStatus = EnumWalletTransactionStatus.Fail;
+                    await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+                }
+                else
+                {
+                    await GetTransactionDetail(wallet, transaction);
+
+                    if (transaction.TransactionStatus == EnumWalletTransactionStatus.Success)
+                    {
+                        await DownloadEreceiptUrl(wallet, transaction);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// 鏌ヨ浜ゆ槗璁板綍
+        /// </summary>
+        /// <param name="wallet"></param>
+        /// <param name="transaction"></param>
+        /// <returns></returns>
+        public async Task GetTransactionDetail(ChannelWallet wallet, ChannelWalletTransaction transaction)
+        {
+            var response = await utils.CorSingleTransferQuery(new CorSingleTransferQueryRequest
+            {
+                OrigThirdVoucher = transaction.Code,
+            });
+            if (response.Code.IsNotNull())
+            {
+                transaction.ErrorCode = response.Code;
+                transaction.FailReason = response.Errors?.FirstOrDefault()?.ErrorMessage ?? response.Message;
+                await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+            }
+            else
+            {
+                response.Adapt(transaction.PingAnPay);
+                transaction.TransDate = response.AccountDate.ToDateTime();
+                transaction.OrderFee = response.Fee.ToDecimal();
+                transaction.TransactionStatus = response.Stt == "20"
+                        ? EnumWalletTransactionStatus.Success
+                        : response.Stt == "30"
+                        ? EnumWalletTransactionStatus.Fail
+                        : EnumWalletTransactionStatus.Dealing;
+                if (transaction.TransactionStatus == EnumWalletTransactionStatus.Fail)
+                {
+                    transaction.ErrorCode = response.Stt;
+                    transaction.FailReason = response.BackRem;
+                }
+                else
+                {
+                    transaction.ErrorCode = null;
+                    transaction.FailReason = null;
+                }
+                if (transaction.TransactionStatus == EnumWalletTransactionStatus.Success && transaction.TransDate == null)
+                {
+                    transaction.TransDate = DateTime.Now;
+                }
+                await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+
+                if (transaction.TransactionStatus != EnumWalletTransactionStatus.Dealing)
+                {
+                    var responseStop = await utils.StopPaymentAndSettlementAccounts(new StopPaymentAndSettlementAccountsRequest
+                    {
+                        CnsmrSeqNo = transaction.Code,
+                        AccountNo = transaction.PayerAccount,
+                        StopPayFlw = transaction.PingAnPay.FreezeNo,
+                        OpType = "D",
+                        CcyCode = "RMB",
+                        SeqNo = $"{DateTime.Now:yyyyMMddHHmmssfff}{new Random(IDGen.NextID().GetHashCode()).Next(100, 999)}",
+                        TradeDate = DateTime.Now.ToString("yyyyMMdd").ToInt()!.Value,
+                        TradeTime = DateTime.Now.ToString("HHmmss").ToInt()!.Value,
+                    });
+                    if (responseStop.Code.IsNotNull())
+                    {
+                        transaction.PingAnPay.RemoveStopStt = "30";
+                        transaction.PingAnPay.RemoveStopFailReason = responseStop.Errors?.FirstOrDefault()?.ErrorMessage ?? responseStop.Message;
+                    }
+                    else
+                    {
+                        transaction.PingAnPay.RemoveStopStt = responseStop.Stt;
+                        transaction.PingAnPay.RemoveStopFailReason = responseStop.SttDesc;
+                    }
+                    await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 涓嬭浇鐢靛瓙鏀舵嵁
+        /// </summary>
+        /// <param name="wallet"></param>
+        /// <param name="transaction"></param>
+        /// <returns></returns>
+        public async Task DownloadEreceiptUrl(ChannelWallet wallet, ChannelWalletTransaction transaction)
+        {
+            var response = await utils.SameDayHistoryReceiptDataQuery(new SameDayHistoryReceiptDataQueryRequest
+            {
+                OutAccNo = transaction.PayerAccount,
+                AccountBeginDate = transaction.PingAnPay.AccountDate,
+                AccountEndDate = transaction.PingAnPay.AccountDate,
+                InAccNo = transaction.ReceiveAccount,
+                HostFlow = transaction.PingAnPay.HostFlowNo
+            });
+            if (response.Code.IsNotNull())
+            {
+                transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.FAIL;
+                transaction.EreceiptErrorMessage = response.Errors?.FirstOrDefault()?.ErrorMessage ?? response.Message;
+                await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+            }
+            else if (response.List.IsNull())
+            {
+                transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.FAIL;
+                transaction.EreceiptErrorMessage = "鏈壘鍒板洖鍗曡褰�";
+                await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+            }
+            else
+            {
+                var responseDownload = await utils.SingleOrBatchReceiptPDFMergeDownloadNew(new SingleOrBatchReceiptPDFMergeDownloadNewRequest
+                {
+                    OutAccNo = transaction.PayerAccount,
+                    List = response.List
+                        .Select(it => new SingleOrBatchReceiptPDFMergeDownloadNewRequestItem
+                        {
+                            RecepitType = it.ReceiptType,
+                            SeqNo = it.SeqNo,
+                            AccountDate = it.AccountDate
+                        })
+                        .ToList()
+                });
+                if (responseDownload.Code.IsNotNull())
+                {
+                    transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.FAIL;
+                    transaction.EreceiptErrorMessage = responseDownload.Errors?.FirstOrDefault()?.ErrorMessage ?? responseDownload.Message;
+                    await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+                }
+                else
+                {
+
+                    transaction.EreceiptFileId = responseDownload.DocID;
+                    transaction.EreceiptDownloadUrl = utils.DownloadFile(responseDownload.DocID, responseDownload.FileName);
+                    transaction.EreceiptDownloadOssUrl = AliyunOSSUtils.Upload(
+                        "PingAnPay",
+                        new MemoryStream(File.ReadAllBytes(transaction.EreceiptDownloadUrl)),
+                        $"鐢靛瓙鍥炲崟-{transaction.Code}.zip")
+                        .Url;
+                    transaction.EreceiptStatus = EnumWalletTransactionEreceiptStatus.SUCCESS;
+                    await channelWalletTransactionRepository.UpdateNowAsync(transaction);
+                }
+            }
+        }
+    }
+}

--
Gitblit v1.9.1