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