Files
juipnet/Services/Hncore.Pass.PaymentCenter/Controllers/PaymentController.cs
wanyongkang d318014316 初始提交
2020-10-07 20:25:03 +08:00

272 lines
9.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.PaymentCenter.Domain;
using Hncore.Pass.PaymentCenter.Pay.WxPay;
using Hncore.Pass.PaymentCenter.Response;
using Hncore.Pass.PaymentCenter.Response.PaymentRecord;
using Hncore.Pass.PaymentCenter.Service;
using Hncore.Pass.PaymentCenter.WeiFuTong;
using Hncore.Pass.PaymentCenter.WeiFuTong.Notify;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace Hncore.Pass.PaymentCenter.Controllers
{
[ApiVersion("1.0")]
[Route("api/paymentcenter/v{version:apiVersion}/Payment/[action]")]
public class PaymentController : PaymentControllerBase
{
private PaymentRecordService m_PaymentRecordService;
private WeiFuTongService m_WeiFuTongService;
private InternalNotifySerivce m_InternalNotifySerivce;
private WxPayClient m_WxPayClient { get; set; }
public PaymentController(
PaymentRecordService _PaymentRecordService
, InternalNotifySerivce internalNotifySerivce
, TenantService _TenantService
, WxPayClient _WxPayClient
, WeiFuTongService weiFuTongService
, IConfiguration _Configuration) : base(_TenantService, _Configuration)
{
// m_WeiFuTongService = weiFuTongService;
m_PaymentRecordService = _PaymentRecordService;
m_InternalNotifySerivce = internalNotifySerivce;
m_WxPayClient = _WxPayClient;
}
private async Task<QueryOrderResponse> QueryOrderByPaymentRecordAsync(PaymentRecord paymentRecord)
{
QueryOrderResponse result = null;
//威富通的订单
if (paymentRecord.PaymentChannel == PaymentChannel.WeiFuTong
|| paymentRecord.PaymentChannel == PaymentChannel.QuanFuTong
&& paymentRecord.FromPos==0)
{
var mchInfo = await GetMchInfoAsync(paymentRecord.TenantId
, paymentRecord.StoreId
, paymentRecord.PaymentChannel);
result = await m_WeiFuTongService.QueryOrderAsync(paymentRecord, mchInfo);
await UofCommitAsync();
}
return result;
}
/// <summary>
/// 通用订单查询
/// </summary>
/// <param name="orderNo"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult> QueryOrder(string orderNo = "", int? recordId = 0)
{
PaymentRecord paymentRecord = null;
if (recordId == null || recordId == 0)
{
paymentRecord = await m_PaymentRecordService.Query(false)
.OrderByDescending(t => t.Id)
.FirstOrDefaultAsync(t => t.OrderId == orderNo);
}
else if (recordId > 0)
{
paymentRecord = await m_PaymentRecordService.GetById(recordId.ToInt());
}
CheckHelper.NotNull(paymentRecord, "支付记录不存在");
var result = await QueryOrderByPaymentRecordAsync(paymentRecord);
if (result == null)
{
return Error("未知的支付渠道");
}
return Success(result);
}
/// <summary>
/// 根据orderid查询一条支付记录
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
[HttpGet]
public async Task<ApiResult> GetDetail([FromQuery] string orderId)
{
return Success(await QueryPaymentRecordByOrderIdResponse.Query(
m_PaymentRecordService.Query(false)
, orderId)
);
}
/// <summary>
/// 威富通、全付通 接收通知
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<string> HWCNotify()
{
try
{
string xml = "";
if (Request.Body.CanSeek)
{
Request.Body.Position = 0;
}
using (System.IO.StreamReader reader = new System.IO.StreamReader(Request.Body))
{
xml = reader.ReadToEnd();
}
LogHelper.Trace("收到威富通支付通知,原始数据:", $"{xml}");
var notifyEntity = XML.XmlDeserialize<NotifyResponse>(xml);
// 给支付平台的订单号为支付记录id
int paymentRecordId = notifyEntity.OutTradeNo.ToInt();
var paymentRecord = await m_PaymentRecordService.GetById(paymentRecordId);
var mchInfo = await GetMchInfoAsync(paymentRecord.TenantId, paymentRecord.StoreId,
paymentRecord.PaymentChannel);
Util.CheckSignFromXml(xml, mchInfo);
if (notifyEntity.PayResult == 0) //支付成功
{
paymentRecord.SetPaySuccessed(notifyEntity.TransactionId, notifyEntity.GetPaySuccessTime());
paymentRecord.SetPaymentTypeFromTradeType(notifyEntity.TradeType);
}
else
{
paymentRecord.SetPayFailed();
}
await m_PaymentRecordService.Update(paymentRecord);
var status = notifyEntity.PayResult == 0 ? "成功" : "失败";
LogHelper.Info("威富通回调信息:",
$"支付记录Id{paymentRecord.Id}\n订单号{paymentRecord.OrderId}\n交易号{paymentRecord.TransactionId}\n支付状态{status}\n发起时间{paymentRecord.RequestTime.Format("yyyy-MM-dd HH:mm:ss")}\n付款成功时间{notifyEntity.GetPaySuccessTime().Format("yyyy-MM-dd HH:mm:ss")}\n收到通知时间{DateTime.Now.Format("yyyy-MM-dd HH:mm:ss")}\n总用时{(DateTime.Now - paymentRecord.RequestTime).TotalSeconds}秒");
if (notifyEntity.PayResult == 0)
{
//发起内部通知
await m_InternalNotifySerivce.Notify(paymentRecord);
}
}
catch (Exception e)
{
LogHelper.Error("威富通通知处理失败", e);
return "fail";
}
return "success";
}
/// <summary>
/// 微信支付回调 接收通知
/// </summary>
/// <returns></returns>
[HttpPost, AllowAnonymous]
public async Task<string> Notify()
{
try
{
string xml = "";
LogHelper.Trace("微信支付回调开始","Notify");
if (Request.Body.CanSeek)
{
Request.Body.Position = 0;
}
using (System.IO.StreamReader reader = new System.IO.StreamReader(Request.Body))
{
xml = reader.ReadToEnd();
}
LogHelper.Trace("微信支付回调,原始数据:", $"{xml}");
WxPayChecker payData = new WxPayChecker();
payData.FromXmlNoCheckSign(xml);
if (!payData.IsSet("out_trade_no"))
{
return FailXml();
}
// 给支付平台的订单号为支付记录id
string orderId = payData["out_trade_no"];
string TransactionId = payData["transaction_id"];
var paymentRecord = await m_PaymentRecordService.GetOneByOrderId(orderId);
if (paymentRecord.TransactionId.NotHas())
{
paymentRecord.TransactionId = TransactionId;
await m_PaymentRecordService.Update(paymentRecord);
}
var mchInfo = await GetMchInfoAsync(paymentRecord.TenantId, paymentRecord.StoreId,
paymentRecord.PaymentChannel);
payData.MchKey = mchInfo.Key;
var queryRet = await m_WxPayClient.OrderQuery(new WxJsPayOrderQueryRequest()
{
AppId = paymentRecord.Appid,
MchId = mchInfo.MchId,
NonceStr = payData.GenerateNonceStr(),
TransactionId = TransactionId
}, mchInfo);
if (!queryRet) return FailXml();
if (!payData.CheckSign()) return FailXml();
paymentRecord.PaymentStatus = PaymentStatus.OkPay;
paymentRecord.UpdateTime = DateTime.Now;
paymentRecord.PaymentCompletionTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
await m_PaymentRecordService.Update(paymentRecord);
//发起内部通知
await m_InternalNotifySerivce.Notify(paymentRecord);
}
catch (Exception e)
{
LogHelper.Error("微信支付通知处理失败", e);
return FailXml();
}
return SuccessXml();
}
public string FailXml()
{
return "<xml><return_code>FAIL</return_code> </xml>";
}
private string SuccessXml()
{
return "<xml><return_code>SUCCESS</return_code> </xml>";
}
}
}