using BPA.KitChen.GroupMealOrder.Core; using BPA.KitChen.GroupMealOrder.Core.CacheOption; using BPA.KitChen.GroupMealOrder.Core.Common; using BPA.KitChen.GroupMealOrder.Core.Entity; using BPA.KitChen.GroupMealOrder.SqlSugar; using BPA.KitChen.WeChat.WechatServer.Dtos; using Essensoft.Paylink.WeChatPay.V2; using Essensoft.Paylink.WeChatPay.V2.Request; using Essensoft.Paylink.WeChatPay.V2.Response; using Furion; using Furion.DependencyInjection; using Furion.FriendlyException; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace BPA.KitChen.WeChat.WechatServer.Service { /// /// 微信支付 /// public class WechatPayService : IWechatPayService, ITransient { private readonly IMemoryCache _memoryCache; private readonly IWeChatPayClient _client; readonly IWebHostEnvironment _env; private readonly IHttpContextAccessor _httpContextAccessor; public WechatPayService(IMemoryCache memoryCache, IHttpContextAccessor httpContextAccessor, IWeChatPayClient client, IWebHostEnvironment env) { _memoryCache = memoryCache; _client = client; _httpContextAccessor = httpContextAccessor; _env = env; } /// /// 统一下单 /// /// 自己系统的订单ID /// /// public async Task PayLinkWechatPay(string openid, string ordernumber) { Console.WriteLine("进入支付接口"); var appid = _httpContextAccessor.HttpContext.Request.Headers["AppId"].ToString(); if (string.IsNullOrEmpty(appid)) { throw Oops.Oh("AppId不能为空!"); } var config = ApolloApplication.Configs.Find(x => x.Key == appid); if (config == null) { throw Oops.Oh("AppId不存在!"); } try { WechatConfigOptions opt = config.WechatConfig; WechatPayConfigOptions PayOpt = config.WechatPayConfig; //查询订单 var order = await SqlSugarDb.Db.Queryable() .ClearFilter() .FirstAsync(x => x.OrderNumber == ordernumber); if (order==null) { throw Oops.Oh("没有找到订单信息!"); } string body = $"{CurrentUser.StoreName}点餐"; string attach = CurrentUser.StoreName; string out_trade_no = order.OrderNumber; int total_fee = Convert.ToInt32(order.TotalAmount * 100); var request = new WeChatPayUnifiedOrderRequest { Body = body, OutTradeNo = out_trade_no, TotalFee = total_fee, Attach = attach, SpBillCreateIp = opt.MchIP, NotifyUrl = opt.WeChatPayNotifyUrl, TradeType = "JSAPI", OpenId =string.IsNullOrEmpty(openid)? order .CreateId: openid, }; var response = await _client.ExecuteAsync(request, PayOpt); if (response.ReturnCode == WeChatPayCode.Success && response.ResultCode == WeChatPayCode.Success) { var req = new WeChatPayJsApiSdkRequest { Package = "prepay_id=" + response.PrepayId }; var parameter = await _client.ExecuteAsync(req, PayOpt); parameter.Add("paymentId", out_trade_no); PaymentEntity payment = new(); payment.timeStamp = parameter.FirstOrDefault(x => x.Key == "timeStamp").Value; payment.nonceStr = parameter.FirstOrDefault(x => x.Key == "nonceStr").Value; payment.package = parameter.FirstOrDefault(x => x.Key == "package").Value; payment.paySign = parameter.FirstOrDefault(x => x.Key == "paySign").Value; payment.signType = parameter.FirstOrDefault(x => x.Key == "signType").Value; payment.trade_no = parameter.FirstOrDefault(x => x.Key == "paymentId").Value; order.TradeNo = payment.trade_no; var res = await SqlSugarDb.Db.Updateable(order).ExecuteCommandAsync(); if (res>0) { return new JsonResult(payment); } else { throw Oops.Oh("订单服务更新数据失败!"); } } else { throw Oops.Oh(response.ReturnMsg+"-"+response.ErrCode+"-"+response.ErrCodeDes); } } catch (Exception ex) { // BPALog.WriteLog("支付接口PayLinkWechatPay报错:"+ex.ToString()); throw Oops.Oh(ex.Message); } } /// /// 退款 /// /// /// /// public async Task Refund(WechatRefundInput input, ApolloApplicationConfig config) { WechatConfigOptions opt = config.WechatConfig; WechatPayConfigOptions PayOpt = config.WechatPayConfig; RefundDto dto = new(); var request = new WeChatPayRefundRequest { OutRefundNo = WechatCommon.GenerateOutTradeNo(), //TransactionId = input.transaction_id, OutTradeNo = input.out_trade_no, TotalFee = Convert.ToInt32(input.total_fee), RefundDesc = input.RefundDesc, RefundFee = Convert.ToInt32(input.refund_fee), NotifyUrl = opt.WeChatRefundUrl }; var response = await _client.ExecuteAsync(request, PayOpt); if (response.ReturnCode == WeChatPayCode.Success && response.ResultCode == WeChatPayCode.Success) { dto.res = true; dto.response = response; return dto; } else { //查询微信订单信息 var orderinfo = await PayOrderQuery(opt.Appid, input.transaction_id, ""); if (orderinfo != null) { Console.WriteLine("当前状态:" + orderinfo.TradeStateDesc); int totalfee = orderinfo.TotalFee; //已经退款,更新状态 if (orderinfo.TradeState == "REFUND") { //修改数据库订单状态为退款 config.WechatConfig.OrderAddress = "https://bpa.black-pa.com:21527/order"; //查询退款订单 var order = await SqlSugarDb.Db.Queryable() .FirstAsync(x => x.WeighOrderNumber == input.out_trade_no); //修改退款状态 if (order == null) { throw Oops.Bah($"退款失败:没有查询到退款订单"); } //MyDataResult ResResult = OrderWeApiHepler.Refundrefuc(config.WechatConfig.OrderAddress, input.transaction_id, orderinfo.OutTradeNo, 1, totalfee / 100, "微信已经退款,修订退款操作"); ////如果成功 //if (ResResult.isSuccess) //{ //} dto.res = true; dto.response = response; return dto; } } throw Oops.Bah($"退款失败:{response.ErrCodeDes}"); } } /// /// 充值 /// /// /// public async Task RechargePay(RechargeInput input) { Console.WriteLine("进入支付接口"); var appid = _httpContextAccessor.HttpContext.Request.Headers["AppId"].ToString(); if (string.IsNullOrEmpty(appid)) { throw Oops.Oh("AppId不能为空!"); } var config = ApolloApplication.Configs.Find(x => x.Key == appid); if (config == null) { throw Oops.Oh("AppId不存在!"); } try { WechatConfigOptions opt = config.WechatConfig; WechatPayConfigOptions PayOpt = config.WechatPayConfig; var money = (input.Money / 100).ToString(); string body = $"会员充值"; string attach = $"储值{money}元"; string out_trade_no = input.RechargeId; int total_fee = Convert.ToInt32(input.Money); var request = new WeChatPayUnifiedOrderRequest { Body = body, OutTradeNo = out_trade_no, TotalFee = total_fee, Attach = attach, SpBillCreateIp = opt.MchIP, NotifyUrl = opt.WeChatPayNotifyUrl, TradeType = "JSAPI", OpenId = input.OpenId }; var response = await _client.ExecuteAsync(request, PayOpt); if (response.ReturnCode == WeChatPayCode.Success && response.ResultCode == WeChatPayCode.Success) { var req = new WeChatPayJsApiSdkRequest { Package = "prepay_id=" + response.PrepayId }; var parameter = await _client.ExecuteAsync(req, PayOpt); parameter.Add("paymentId", out_trade_no); PaymentEntity payment = new(); payment.timeStamp = parameter.FirstOrDefault(x => x.Key == "timeStamp").Value; payment.nonceStr = parameter.FirstOrDefault(x => x.Key == "nonceStr").Value; payment.package = parameter.FirstOrDefault(x => x.Key == "package").Value; payment.paySign = parameter.FirstOrDefault(x => x.Key == "paySign").Value; payment.signType = parameter.FirstOrDefault(x => x.Key == "signType").Value; payment.trade_no = parameter.FirstOrDefault(x => x.Key == "paymentId").Value; return new JsonResult(payment); } else { // BPALog.WriteLog("支付接口返回PayLinkWechatPay:", param: response); throw Oops.Oh(response.ReturnMsg + "-" + response.ErrCode + "-" + response.ErrCodeDes); } } catch (Exception ex) { // BPALog.WriteLog("支付接口PayLinkWechatPay报错:" + ex.ToString()); throw Oops.Oh(ex.Message); } } /// /// 查询 /// /// appid /// 商家支付订单号 /// 商户订单号 /// public async Task PayOrderQuery(string AppId,string transaction_id, string out_trade_no) { var config = ApolloApplication.Configs.Find(x => x.Key == AppId); WechatPayConfigOptions opt = config.WechatPayConfig; var request = new WeChatPayOrderQueryRequest { OutTradeNo = out_trade_no, TransactionId = transaction_id, }; var response = await _client.ExecuteAsync(request, opt); return response; } /// /// 根据商家号退款 /// /// /// /// [IfException(ErrorMessage = "无效订单")] public async Task ToRefund(string appId,string ordernumid) { return null; //var config = ApolloApplication.Configs.Find(x => x.Key == appId); //MyDataResult info = OrderWeApiHepler.GetOrderInfoByNum(config.WechatConfig.OrderAddress,ordernumid); //if (!info.isSuccess) //{ // throw Oops.Oh("订单服务未找到订单信息"); //} //if (info.data.orderRealMoney <= 0 || string.IsNullOrEmpty(info.data.transactionId)) //{ // MyDataResult result = OrderWeApiHepler.Refundrefuc(config.WechatConfig.OrderAddress, info.data.transactionId, info.data.tradeNo, 1, 0, "测试数据修改为退款状态"); // if (!result.isSuccess) // { // throw Oops.Oh(result.msg); // } // else // { // return new JsonResult(true); // } //} //else //{ // if (info != null && (!string.IsNullOrEmpty(info.data.tradeNo) || !string.IsNullOrEmpty(info.data.transactionId))) // { // //查询微信订单信息 // var orderinfo = await PayOrderQuery(appId,info.data.transactionId, info.data.tradeNo); // if (orderinfo != null) // { // Console.WriteLine("当前状态:" + orderinfo.TradeStateDesc); // int totalfee = orderinfo.TotalFee; // //已经退款,更新状态 // if (orderinfo.TradeState == "REFUND") // { // BPALog.WriteLog($"{info.data.orderNumber}检测到微信平台已退款"); // //修改数据库订单状态为退款 // MyDataResult ResResult = OrderWeApiHepler.Refundrefuc(config.WechatConfig.OrderAddress,info.data.transactionId, info.data.tradeNo, 1, totalfee / 100, "微信已经退款,修订退款操作"); // //如果成功 // if (ResResult.isSuccess) // { // //_CouponService.Rebackcoupon(info.Order_Number); // BPALog.WriteLog($"{info.data.orderNumber}修改后台状态为退款成功!"); // return new JsonResult(true); // } // else // { // BPALog.WriteLog($"{info.data.orderNumber}{ResResult.msg}!"); // return new JsonResult(false); // } // } // else if (orderinfo.TradeState == "SUCCESS") // { // MyDataResult resultIng = OrderWeApiHepler.Refundrefuc(config.WechatConfig.OrderAddress, info.data.transactionId, info.data.tradeNo, 2, Convert.ToDecimal(totalfee) / 100, "微信查询为未退款,进行退款操作"); // if (resultIng.isSuccess) // { // //调用微信退款接口 // var refundres = await Refund( // new() // { // transaction_id = info.data.transactionId, // out_trade_no = info.data.tradeNo, // total_fee = totalfee, // refund_fee = totalfee, // }, config // ); // //如果返回成功,优惠券回退 // if (refundres.res) // { // BPALog.WriteLog($"{info.data.orderNumber}微信平台退款成功"); // //修改数据库订单状态为退款 // MyDataResult resultSuc = OrderWeApiHepler.Refundrefuc(config.WechatConfig.OrderAddress, info.data.transactionId, info.data.tradeNo, 1, Convert.ToDecimal(totalfee) / 100, "微信查询为未退款,进行退款操作"); // //如果成功 // if (resultSuc.isSuccess) // { // BPALog.WriteLog($"{info.data.orderNumber}订单平台退款状态修改成功!"); // return new JsonResult(true); // } // else // { // BPALog.WriteLog($"{info.data.orderNumber}订单平台退款状态修改失败!失败原因:{resultSuc.msg}"); // return new JsonResult(false); // } // } // else // { // //失败则回滚订单状态 // //string errcode = refundres.GetValue("err_code").ToString(); // MyDataResult result = OrderWeApiHepler.Refundrefuc(config.WechatConfig.OrderAddress,info.data.transactionId, info.data.tradeNo, 3, Convert.ToDecimal(totalfee) / 100, refundres.response.ErrCodeDes); // BPALog.WriteLog($" Refundrefuc方法执行结果:{ result.isSuccess}"); // BPALog.WriteLog($" 微信平台退款失败:{refundres.response.ErrCodeDes}订单流水号:{ info.data.orderNumber}"); // return new JsonResult(false); // //OrderWeApiHepler.ChangeOrderStutas(info.Order_Number, info.Order_Status, "微信平台退款失败:" + CacheHepler.GetInstance().GetRefundResultText(errcode) + $"({info.Order_Status})"); // } // } // else // { // BPALog.WriteLog("调用Refundrefuc方法:"+ resultIng.msg); // return new JsonResult(false); // } // } // else // { // BPALog.WriteLog("状态为:" + orderinfo.TradeState + ",此订单无法退款"); // return new JsonResult(false); // } // } // else // { // throw Oops.Oh("退款失败,没有找到订单"); // } // } // else // { // throw Oops.Oh("无效订单"); // } //} } /** * 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数 * @return 时间戳 */ public static string GenerateTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /** * 生成随机串,随机串包含字母或数字 * @return 随机串 */ public static string GenerateNonceStr() { return null; //RandomGenerator randomGenerator = new RandomGenerator(); //return randomGenerator.GetRandomUInt().ToString(); } /** * 参数数组转换为url格式 * @param map 参数名与参数值的映射表 * @return URL字符串 */ private string ToUrlParams(SortedDictionary map) { string buff = ""; foreach (KeyValuePair pair in map) { buff += pair.Key + "=" + pair.Value + "&"; } buff = buff.Trim('&'); return buff; } /// /// 付款码支付 /// /// /// /// public async Task MicropayPay(MicropayInput input) { return null; //var config = ApolloApplication.Configs.Find(x => x.Key == input.AppId); //WechatConfigOptions opt = config.WechatConfig; //WechatPayConfigOptions PayOpt = config.WechatPayConfig; ////PayOpt.CertificatePassword = PayOpt.MchId; ////PayOpt.Certificate = SystemConfig.CertificateAddress; //string body = "商品购买"; //string out_trade_no = string.Empty; //int total_fee =0; //if (!string.IsNullOrEmpty(input.OrderId)) //{ // MyDataResult res = OrderWeApiHepler.GetOrderInfoByNum(config.WechatConfig.OrderAddress, input.OrderId); // if (!res.isSuccess) // { // throw Oops.Oh("没有找到订单信息!"); // } // total_fee = Convert.ToInt32(input.TotalFee * 100); // out_trade_no = input.OrderId; // //OrderAllInfoDto orderinfo = res.data; //} //else //{ // out_trade_no = WechatCommon.GenerateOutTradeNo(); // total_fee = 1; //} //var request = new WeChatPayMicroPayRequest //{ // Body = body, // OutTradeNo = out_trade_no, // TotalFee = total_fee, // SpBillCreateIp = config.WechatConfig.MchIP, // AuthCode = input.AuthCode //}; //var response = await _client.ExecuteAsync(request, PayOpt); //if (response.ReturnCode == WeChatPayCode.Success && response.ResultCode == WeChatPayCode.Success) //{ // return new JsonResult(new MicropayOutput { Code=200, Msg ="交易成功", Success =true }); //} //return new JsonResult(new MicropayOutput { Code = 500, Msg = $"交易失败-ReturnMsg:{response.ReturnMsg},ErrCodeDes:{response.ErrCodeDes}", Success = false }); } public string NativePay(decimal amount, string orderid) { throw new NotImplementedException(); } } }