123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- using System;
- using System.Web;
- using WingServerCommon.Service;
- using WingInterfaceLibrary.Interface;
- using System.Threading.Tasks;
- using WingInterfaceLibrary.DTO.Payment;
- using WingInterfaceLibrary.Request.Payment;
- using WingInterfaceLibrary.Result;
- using System.Collections.Generic;
- using WingInterfaceLibrary.Interface.DBInterface;
- using WingInterfaceLibrary.DB.Request;
- using WingServerCommon.Log;
- using WingPaymentService.Common;
- using WingInterfaceLibrary.Enum;
- using WingInterfaceLibrary.Request;
- using WingPaymentService.Common.WeChat;
- using WingInterfaceLibrary.Request.Courses;
- namespace WingPaymentService.Service
- {
- public class PaymentService : JsonRpcService, IPaymentService
- {
- private IEducationService _educationService;
- private IAuthenticationService _authenticationService;
- private IPaymentDBService _paymentDBService;
- private AlipayCommon _alipayCommon;
- private WeChatCommon _weChatCommon;
- public override void Load(JsonRpcClientPool jsonRpcClientPool)
- {
- _alipayCommon = new AlipayCommon();
- _weChatCommon = new WeChatCommon();
- base.Load(jsonRpcClientPool);
- _paymentDBService = GetProxy<IPaymentDBService>();
- _authenticationService = GetProxy<IAuthenticationService>();
- _educationService = GetProxy<IEducationService>();
- }
- /// <summary>
- /// 购买接口
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- public async Task<CreateOrderResultDTO> CreateOrderAsync(CreateOrderRequest request)
- {
- var dbRequest = new CreateOrderDBRequest();
- dbRequest.OrderAmount = request.OrderAmount;
- dbRequest.OrderTitle = request.OrderTitle;
- dbRequest.OrderType = request.OrderType;
- if (string.IsNullOrWhiteSpace(request.OrderUserCode))
- {
- request.OrderUserCode = await ValidateTokenAsync(request.Token);
- if (string.IsNullOrWhiteSpace(request.OrderUserCode))
- {
- ThrowCustomerException(CustomerRpcCode.UserNotFind, "UserNotFind");
- }
- }
- dbRequest.OrderUserCode = request.OrderUserCode;
- dbRequest.PayStatus = PayStatusEnum.NoPay;
- dbRequest.PayTime = DateTime.UtcNow;
- dbRequest.ProductCode = request.ProductCode;
- dbRequest.TPORderCode = request.TPORderCode;
- return await _paymentDBService.CreateOrderAsync(dbRequest);
- }
- /// <summary>
- /// 订单详情接口
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- public async Task<OrderDetailDTO> GetOrderDetailAsync(GetOrderDetailRequest request)
- {
- return await _paymentDBService.GetOrderDetailAsync(new GetOrderDetailDBRequest { OrderCode = request.OrderCode });
- }
- /// <summary>
- /// 订单列表接口
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- public async Task<PageResult<OrderDetailDTO>> GetOrderPagesAsync(GetOrderPagesRequest request)
- {
- return await _paymentDBService.GetOrderPagesAsync(new GetOrderPagesDBRequest
- {
- CurrentPage = request.PageIndex,
- PageSize = request.PageSize,
- KeyWord = request.KeyWord
- });
- }
- /// <summary>
- /// 发起支付请求
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- public async Task<PayInfoDTO> GoToPayAsync(GoToPayRequest request)
- {
- if (!string.IsNullOrWhiteSpace(request.OrderCode))
- {
- var orderInfo = await _paymentDBService.GetOrderDetailAsync(new GetOrderDetailDBRequest { OrderCode = request.OrderCode });
- if (orderInfo != null && orderInfo.OrderAmount > 0)
- {
- string recordCode = Guid.NewGuid().ToString("N");
- (string payUrl, string recordContent) payContent = (string.Empty,string.Empty);
- switch (request.PayType)
- {
- case PayTypeEnum.Alipay_PAGE:
- payContent = _alipayCommon.AlipayPagePay(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode);
- break;
- case PayTypeEnum.Alipay_WAP:
- payContent = _alipayCommon.AlipayWapPay(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode);
- break;
- case PayTypeEnum.WeChat_PAGE:
- payContent = await _weChatCommon.GetWebPayUrlAsync(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode, string.Empty, string.Empty);
- break;
- case PayTypeEnum.WeChat_WAP:
- payContent = await _weChatCommon.GetWapPayUrlAsync(orderInfo.OrderTitle, orderInfo.OrderAmount, orderInfo.Code, recordCode, string.Empty, string.Empty);
- break;
- }
- await CreatePayStatusReq(recordCode, payContent.recordContent);
- if (!string.IsNullOrWhiteSpace(payContent.payUrl))
- {
- return new PayInfoDTO
- {
- IsSuccess = true,
- PayUrl = payContent.payUrl
- };
- }
- }
- }
- return new PayInfoDTO
- {
- IsSuccess = false,
- PayUrl = string.Empty
- };
- }
- /// <summary>
- /// 支付后回调
- /// </summary>
- /// <param name="src">来源</param>
- /// <param name="request">请求信息</param>
- /// <returns></returns>
- public async Task<PayCallbackDTO> PayCallbackAsync(string src, string request)
- {
- bool isSuccess = false;
- try
- {
- switch (src)
- {
- case "alipay":
- isSuccess = await AlipayCallback(request);
- break;
- case "wechat":
- isSuccess = await WeChatCallback(request);
- break;
- }
- return new PayCallbackDTO { IsSuccess = isSuccess };
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"PayCallback error {ex}");
- return new PayCallbackDTO { IsSuccess = false };
- }
- }
- /// <summary>
- /// 支付宝回调
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- private async Task<bool> AlipayCallback(string request)
- {
- Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
- var uriParams = HttpUtility.UrlDecode(request);
- if (uriParams != null)
- {
- var paramsArr = uriParams.Split('&');
- foreach (string param in paramsArr)
- {
- var keyValue = param.Split('=');
- var key = keyValue[0];
- var value = keyValue.Length > 1 ? keyValue[1] : string.Empty;
- keyValuePairs.Add(key, value);
- }
- }
- var payOutTradeNo = keyValuePairs.GetValueOrDefault("out_trade_no");
- var totalAmount = keyValuePairs.GetValueOrDefault("total_amount");
- var payRecordCode = keyValuePairs.GetValueOrDefault("pay_record_code");
- var payStatus = keyValuePairs.GetValueOrDefault("trade_status") == "TRADE_SUCCESS" ? WingInterfaceLibrary.Enum.PayStatusEnum.Paid : WingInterfaceLibrary.Enum.PayStatusEnum.NoPay;
- var payTime = DateTime.UtcNow;
- return await PayRecordWriteRes(payOutTradeNo, payRecordCode, totalAmount, payStatus, payTime, request);
- }
- /// <summary>
- /// 微信回调
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- private async Task<bool> WeChatCallback(string request)
- {
- //转换数据格式, 取消签名校验,签名调用方自己调用,兼容支付和退款
- WxPayData data = new WxPayData();
- var paramValues = data.FromXml(request, false);//回调不用签名校验
- var payOutTradeNo = paramValues.GetValueOrDefault("out_trade_no")?.ToString();
- var totalAmount = (double.Parse(paramValues.GetValueOrDefault("total_fee")?.ToString()) / 100).ToString("0.00");
- var payRecordCode = paramValues.GetValueOrDefault("pay_record_code")?.ToString();
- var payStatus = paramValues.GetValueOrDefault("result_code")?.ToString() == "SUCCESS" ? PayStatusEnum.Paid : PayStatusEnum.NoPay;
- var payTime = DateTime.UtcNow;
- return await PayRecordWriteRes(payOutTradeNo, payRecordCode, totalAmount, payStatus, payTime, request);
- }
- /// <summary>
- /// 支付记录
- /// </summary>
- /// <param name="orderCode">订单编码</param>
- /// <param name="payRecordCode">支付记录编码</param>
- /// <param name="totalAmount">支付金额</param>
- /// <param name="payStatus">支付状态</param>
- /// <param name="payTime">支付时间</param>
- /// <param name="request">支付原始请求</param>
- /// <returns></returns>
- private async Task<bool> PayRecordWriteRes(string orderCode, string payRecordCode, string totalAmount, PayStatusEnum payStatus, DateTime payTime, string res)
- {
- if (string.IsNullOrWhiteSpace(payRecordCode))
- {
- Logger.WriteLineError("Pay record code is empty");
- return false;
- }
- await UpdatePayStatusRes(payRecordCode, payStatus, res, payTime);
- if (string.IsNullOrWhiteSpace(orderCode))
- {
- Logger.WriteLineError("Order code is empty");
- return false;
- }
- if (payStatus == PayStatusEnum.Paid)
- {
- return await UpdateOrderStatus(orderCode, payStatus, totalAmount, payTime);
- }
- return false;
- }
- private async Task<bool> UpdateOrderStatus(string orderCode, PayStatusEnum payStatus, string totalAmount, DateTime payTime)
- {
- var orderInfo = await _paymentDBService.GetOrderDetailAsync(new GetOrderDetailDBRequest { OrderCode = orderCode });
- if (orderInfo.OrderAmount.ToString("0.00") != totalAmount)
- {
- Logger.WriteLineError($"OrderCode:{orderInfo.Code} pay status {payStatus}, total amount error, order amount {orderInfo.OrderAmount.ToString("0.00")} paid amount {totalAmount}");
- return false;
- }
- var result = await _paymentDBService.UpdateOrderAsync(new UpdateOrderDBRequest
- {
- OrderCode = orderCode,
- PayStatus = payStatus
- });
- await _educationService.PaymentCallbackAsync(new PaymentCallbackRequest
- {
- PaymentOrderCode = orderCode,
- PayStatus = payStatus,
- PayTime = payTime
- });
- return result.IsSuccess;
- }
- private async Task<CreatePaymentRecordResultDTO> CreatePayStatusReq(string paymentRecordCode, string payReqContent)
- {
- var createRecordInfo = new CreatePaymentRecordDBRequest();
- createRecordInfo.PayReqContent = payReqContent;
- return await _paymentDBService.CreatePaymentRecordAsync(createRecordInfo);
- }
- private async Task<UpdatePaymentRecordResultDTO> UpdatePayStatusRes(string paymentRecordCode, PayStatusEnum payStatus, string payResContent, DateTime payTime)
- {
- var updateRecordInfo = new UpdatePaymentRecordDBRequest();
- updateRecordInfo.Code = paymentRecordCode;
- updateRecordInfo.PayTime = payTime;
- updateRecordInfo.PayStatus = payStatus;
- updateRecordInfo.PayResContent = payResContent;
- return await _paymentDBService.UpdatePaymentRecordAsync(updateRecordInfo);
- }
- /// <summary>
- /// 客户端用户验证
- /// </summary>
- /// <param name="request"></param>
- /// <returns>User Code</returns>
- private async Task<string> ValidateTokenAsync(string token)
- {
- var request = new TokenRequest() { Token = token };
- var result = await _authenticationService.GetTokenAsync(request);
- return result.ClientId; //return User code
- }
- private void ThrowCustomerException(CustomerRpcCode customerRpcCodeEnum, string msg)
- {
- ThrowRpcException((int)customerRpcCodeEnum, msg);
- }
- }
- }
|