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;
|
|
/// <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 = transaction.PingAnPay ?? new ChannelWalletTransactionPingAnPay();
|
if (transaction.ReceiveAccount == "1234123412341234")
|
{
|
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);
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 查询交易记录
|
/// </summary>
|
/// <param name="wallet"></param>
|
/// <param name="transaction"></param>
|
/// <returns></returns>
|
public async Task GetTransactionDetail(ChannelWallet wallet, ChannelWalletTransaction transaction)
|
{
|
if (transaction.ReceiveAccount == "1234123412341234")
|
{
|
return;
|
}
|
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);
|
}
|
}
|
}
|
}
|
}
|