using 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;
///
/// 查询企业钱包余额
///
///
///
public async Task 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;
}
///
/// 转账
///
///
///
///
public async Task Transfer(ChannelWallet wallet, ChannelWalletTransaction transaction)
{
transaction.PingAnPay = transaction.PingAnPay ?? new ChannelWalletTransactionPingAnPay();
if (transaction.ReceiveAccount == "123")
{
transaction.ErrorCode = "500";
transaction.FailReason = "卡号错误";
transaction.TransactionStatus = EnumWalletTransactionStatus.Fail;
await channelWalletTransactionRepository.UpdateNowAsync(transaction);
}
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);
}
}
}
}
///
/// 查询交易记录
///
///
///
///
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);
}
}
}
///
/// 下载电子收据
///
///
///
///
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);
}
}
}
}
}