初始提交

This commit is contained in:
wanyongkang
2020-10-07 20:25:03 +08:00
commit d318014316
3809 changed files with 263103 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Service;
using Home.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq.Expressions;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.EntitiesExtension;
using System.Threading.Tasks;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace Home.Controllers
{
public class ArticleController : MvcBaseController
{
ArticleService m_ArticleServce;
public ArticleController(ArticleService _ArticleServce)
{
m_ArticleServce = _ArticleServce;
}
[HttpGet]
public async Task<IActionResult> Index([FromQuery]ArticleSearchModel request)
{
request = request ?? new ArticleSearchModel();
Expression<Func<ArticleEntity, bool>> exp = m => 1 == 1;
if (request.Catalog > 0)
{
exp = exp.And(m => m.CatalogId == request.Catalog);
}
if (request.KeyWord.Has())
{
exp = exp.And(m => m.Title.Contains(request.KeyWord) || m.SubTitle.Contains(request.KeyWord));
}
var ret = await m_ArticleServce.Page(request.PageIndex, request.PageSize, exp);
return View(ret);
}
[HttpGet]
public async Task<IActionResult> Search([FromQuery]ArticleSearchModel request)
{
request = request ?? new ArticleSearchModel();
Expression<Func<ArticleEntity, bool>> exp = m => 1 == 1;
if (request.Catalog > 0)
{
exp = exp.And(m => m.CatalogId == request.Catalog);
}
if (request.KeyWord.Has())
{
exp = exp.And(m => m.Title.Contains(request.KeyWord) || m.SubTitle.Contains(request.KeyWord));
}
var ret = await m_ArticleServce.Page(request.PageIndex, request.PageSize, exp);
return View(ret);
}
[HttpGet]
public async Task<IActionResult> Info(int id)
{
var prev = await m_ArticleServce.Query(m => m.Id < id).OrderByDescending(m => m.Id).FirstOrDefaultAsync();
var ret = await m_ArticleServce.GetById(id);
var next = await m_ArticleServce.Query(m => m.Id > id).OrderBy(m => m.Id).FirstOrDefaultAsync();
return View(new ArticleInfoMode()
{
Prev = prev,
Info = ret,
Next = next
});
}
[HttpGet]
public IActionResult TaoBao()
{
return View();
}
}
}

View File

@@ -0,0 +1,50 @@
using Hncore.Pass.Vpn.Service;
using Home.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Hncore.Infrastructure.Extension;
namespace Home.Controllers
{
public class HomeController : MvcBaseController
{
ProductService m_ProductService;
ArticleService m_ArticleService;
ProductOrderService m_ProductOrderService;
public HomeController(ProductService _ProductService, ArticleService _ArticleService, ProductOrderService _ProductOrderService)
{
m_ProductService = _ProductService;
m_ArticleService = _ArticleService;
m_ProductOrderService = _ProductOrderService;
}
[Route("/")]
public async Task<IActionResult> Index()
{
var prodectList=await m_ProductService.Query(m=>m.OnLine==1).ToListAsync();
var model = prodectList.MapsTo<ProductModel>();
return View(model);
}
[Route("/h")]
public IActionResult Test()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[Route("/Test1")]
public async Task Test1()
{
await m_ProductOrderService.TestProcessOrderAccount();
}
}
}

View File

@@ -0,0 +1,106 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.EntitiesExtension;
using Hncore.Infrastructure.Extension;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Service;
using Home.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace Home.Controllers
{
public class LineListController : MvcBaseController
{
ProductRouteService m_ProductRouteService;
ProductService m_ProductService;
public LineListController(ProductRouteService _ProductRouteService, ProductService _ProductService)
{
m_ProductRouteService = _ProductRouteService;
m_ProductService = _ProductService;
}
[HttpGet]
public async Task<IActionResult> Index([FromQuery]LineSearchModel request)
{
request = request ?? new LineSearchModel();
Expression<Func<ProductRouteEntity, bool>> exp =null;
if (request.ProductId > 0)
{
exp = m => m.ProductId == request.ProductId;
}
if (request.KeyWord.Has())
{
Expression<Func<ProductRouteEntity, bool>> filterExpr = m =>
m.Province.Contains(request.KeyWord)
|| m.City.Contains(request.KeyWord)
|| m.Name.Contains(request.KeyWord)
|| m.ServerUrl.Contains(request.KeyWord);
if (exp == null)
exp = filterExpr;
else exp=exp.And(filterExpr);
}
var ret = await m_ProductRouteService.Query(exp).OrderBy(m=>m.Sort).ToListAsync();
var products = await m_ProductService.Query(m=>m.OnLine == 1).ToListAsync();
ViewData["products"] = products;
return View(ret);
}
[HttpGet]
public async Task<IActionResult> Excel([FromQuery]LineSearchModel request)
{
request = request ?? new LineSearchModel();
Expression<Func<ProductRouteEntity, bool>> exp = m => 1 == 1;
if (request.ProductId > 0)
{
exp = exp.And(m => m.ProductId == request.ProductId);
}
if (request.KeyWord.Has())
{
exp = exp.Or(m => m.Province.Contains(request.KeyWord));
exp = exp.Or(m => m.City.Contains(request.KeyWord));
exp = exp.Or(m => m.Name.Contains(request.KeyWord));
exp = exp.Or(m => m.KeyWord.Contains(request.KeyWord));
}
var ret = await m_ProductRouteService.Query(exp).ToListAsync();
var data = new ExcelData<ProductRouteEntity>
{
SheetName ="线路表",
Data = ret
};
var title = new List<ExcelTitle>(){
new ExcelTitle { Property = "ProductName", Title = "产品" },
new ExcelTitle { Property = "Province", Title = "省份" },
new ExcelTitle { Property = "City", Title = "城市" },
new ExcelTitle { Property = "Name", Title = "运营商" },
new ExcelTitle { Property = "ServerUrl", Title = "服务器" },
new ExcelTitle { Property = "BandWidth", Title = "实时带宽" },
new ExcelTitle { Property = "IpRemark", Title = "IP量" },
new ExcelTitle { Property = "Status", Title = "状态" },
};
var fileBytes = ExcelHelper.ExportListToExcel(data, title);
var fileName = $"线路表.xlsx";
Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
return File(fileBytes, "application/octet-stream", fileName);
}
}
}

View File

@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Home.Controllers
{
[Controller]
[AllowAnonymous]
[Route("[Controller]/[Action]")]
public abstract class MvcBaseController : Controller
{
}
}

View File

@@ -0,0 +1,750 @@
using Alipay.AopSdk.Core;
using Alipay.AopSdk.Core.Domain;
using Alipay.AopSdk.Core.Request;
using Alipay.AopSdk.Core.Util;
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.PaymentCenter.Model;
using Hncore.Pass.PaymentCenter.Pay.WxPay;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Request.Product;
using Hncore.Pass.Vpn.Response.Product;
using Hncore.Pass.Vpn.Service;
using Home.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Hncore.Infrastructure.Extension;
namespace Home.Controllers
{
public class productController : MvcBaseController
{
string Ali_APP_ID ="";
string Ali_APP_PRIVATE_KEY = "";
string ALIPAY_PUBLIC_KEY = "";
string Wx_AppId = "";
string Wx_MchId = "";
string Wx_MchKey = "";
ProductService m_ProductService;
ProductPackageService m_ProductPackageService;
private ProductOrderService m_ProductOrderService;
private IConfiguration m_Configuration;
private WxPayClient m_WxPayClient;
ProductAccountService m_ProductAccountService;
WxAppUserService m_WxAppUserService;
UserService m_UserService;
ProductUserPriceService m_ProductUserPriceService;
public productController(ProductService _ProductService
, ProductOrderService _ProductOrderService
, ProductPackageService _ProductPackageService
, WxPayClient _WxPayClient
,ProductAccountService _ProductAccountService
, WxAppUserService _WxAppUserService
,UserService _UserService
, ProductUserPriceService _ProductUserPriceService
, IConfiguration _Configuration)
{
m_ProductService = _ProductService;
m_ProductOrderService = _ProductOrderService;
m_ProductPackageService = _ProductPackageService;
m_Configuration = _Configuration;
m_WxPayClient = _WxPayClient;
Ali_APP_ID = m_Configuration["Aliyun:Pay:AppId"];
Ali_APP_PRIVATE_KEY = m_Configuration["Aliyun:Pay:PrivateKey"];
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:Pay:PublicKey"];//支付宝的公钥,而不是应用的公钥
Wx_AppId = m_Configuration["WxApps:AppID"];
Wx_MchId = m_Configuration["WxApps:MchId"];
Wx_MchKey = m_Configuration["WxApps:MchKey"];
m_ProductAccountService = _ProductAccountService;
m_WxAppUserService = _WxAppUserService;
m_UserService = _UserService;
m_ProductUserPriceService = _ProductUserPriceService;
}
[HttpGet]
public async Task<IActionResult> Index()
{
var respList = await m_ProductService.ProductWithPackage(1);
var userInfo = this.Request.GetUserInfo();
if (userInfo != null)
{
var userPrices = await m_ProductUserPriceService.GetProductUserPrice(userInfo.UserId);
foreach(var product in respList)
{
product.Packages.ForEach(m => {
var userPrice = userPrices.FirstOrDefault(p => p.PackageId == m.Id && p.ProductId == m.ProductId);
if (userPrice != null && userPrice.UserPrice > 0)
{
m.Price = userPrice.UserPrice;
}
});
}
}
return View(respList);
}
[HttpPost,UserAuth]
public async Task<ApiResult> CreateOrder([FromBody]CreateOrderRequest request)
{
var userId = this.Request.GetUserInfo().UserId;
var ret = await m_ProductOrderService.CreateOrder(request, userId);
if (ret.Code != ResultCode.C_SUCCESS)
{
return ret;
}
if (ret.Data.OtherPayAmount == 0)
{
await m_ProductOrderService.ProcessOrderAccount(ret.Data);
return new ApiResult("00");
}
var data = new OrderPayModel()
{
OrderInfo = ret.Data,
};
if (ret.Data.PayType == PayType.Wechat)
{
var url = await CreateWxPayOrder(ret.Data);
data.PayData = url;
return new ApiResult(data);
}
else
{
var body = await CreateAliPayOrder(ret.Data);
data.PayData = body;
}
return new ApiResult(data);
}
#region
private async Task<string> CreateWxPayOrder(ProductOrderEntity request)
{
string callBackUrl = m_Configuration["NotifyUrl"];
var mchInfo = new MchInfo()
{
MchId = Wx_MchId,
Key = Wx_MchKey
};
var createOrderRes = "";
var pName=request.Accounts.Split(",").FirstOrDefault();
var oName = $"{request.ProductName}-{request.PackageName}";
if (pName.Has()) oName = $"{oName}-{pName}";
if (request.PayChannel == PayChannel.WxPc)
{
var payRequest = new WxScanPayCreateOrderRequest()
{
AppId = Wx_AppId,
Body = oName,
MchId = Wx_MchId,
NotifyUrl = callBackUrl,
OutTradeNo = request.OrderNo,
StoreId = 2,
TenantId = 1157,
TotalFee = (int)(request.OtherPayAmount * 100),
ProductId = request.ProductId.ToString(),
TimeExpire=DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss")
};
createOrderRes = await m_WxPayClient.ScanPayCreateOrderAsync(payRequest, mchInfo);
}
else if (request.PayChannel == PayChannel.WxH5)
{
var payRequest = new WxH5PayCreateOrderRequest()
{
AppId = Wx_AppId,
Body = oName,
MchId = Wx_MchId,
NotifyUrl = callBackUrl,
OutTradeNo = request.OrderNo,
StoreId = 2,
TenantId = 1157,
TotalFee = (int)(request.OtherPayAmount * 100),
ProductId = request.ProductId.ToString(),
TimeExpire = DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss")
};
createOrderRes = await m_WxPayClient.H5PayCreateOrderAsync(payRequest, mchInfo);
}
else
{
var wxUserInfo = await m_WxAppUserService.GetWxUser(Wx_AppId, request.UserId);
var payRequest = new WxJsPayCreateOrderRequest()
{
AppId = Wx_AppId,
Body = oName,
MchId = Wx_MchId,
NotifyUrl = callBackUrl,
OutTradeNo = request.OrderNo,
StoreId = 2,
TenantId = 1157,
TotalFee = (int)(request.OtherPayAmount * 100),
UserOpenId = wxUserInfo.Openid,
TimeExpire = DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss")
};
createOrderRes = await m_WxPayClient.JsPayCreateOrderAsync(payRequest, mchInfo);
}
return createOrderRes;
}
[HttpPost, AllowAnonymous]
public async Task<string> WxOrderCallBack()
{
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 order = await m_ProductOrderService.GetOrderByNo(orderId);
if(order.OrderState== OrderStatus.Complete|| order.OrderState == OrderStatus.PayOk)
return SuccessXml();
var queryRet = await m_WxPayClient.OrderQuery(new WxJsPayOrderQueryRequest()
{
AppId = Wx_AppId,
NonceStr = payData.GenerateNonceStr(),
TransactionId = TransactionId
}, new MchInfo() { MchId = Wx_MchId, Key = Wx_MchKey });
if (!queryRet) return FailXml();
payData.MchKey = Wx_MchKey;
if (!payData.CheckSign()) return FailXml();
order.OrderState = OrderStatus.PayOk;
order.TradeNo = TransactionId;
order.UpdateTime = DateTime.Now;
await m_ProductOrderService.Update(order);
await m_ProductOrderService.ProcessOrderAccount(order);
}
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>";
}
#endregion
#region
private async Task<string> CreateAliPayOrder(ProductOrderEntity request)
{
string callBackUrl = m_Configuration["Aliyun:Pay:NotifyUrl"];
string ReturnUrl = m_Configuration["Aliyun:Pay:ReturnUrl"];
var pName = request.Accounts.Split(",").FirstOrDefault();
var oName = $"{request.ProductName}-{request.PackageName}";
if (pName.Has()) oName = $"{oName}-{pName}";
if (request.PayChannel == PayChannel.AliPc)
{
// 组装业务参数model
AlipayTradePagePayModel model = new AlipayTradePagePayModel
{
Body = request.PackageName,
Subject = oName,
TotalAmount = request.OtherPayAmount.ToString(),
OutTradeNo = request.OrderNo,
ProductCode = "FAST_INSTANT_TRADE_PAY",//QUICK_WAP_PAY
TimeoutExpress="15m"
};
AlipayTradePagePayRequest aliRequest = new AlipayTradePagePayRequest();
// 设置同步回调地址
aliRequest.SetReturnUrl(ReturnUrl);
// 设置异步通知接收地址
aliRequest.SetNotifyUrl(callBackUrl);
// 将业务model载入到request
aliRequest.SetBizModel(model);
var _aopClient = new DefaultAopClient("https://openapi.alipay.com/gateway.do", Ali_APP_ID, Ali_APP_PRIVATE_KEY);
var response = await _aopClient.PageExecuteAsync(aliRequest);
return response.Body;
}
else if (request.PayChannel == PayChannel.AliH5)
{
Ali_APP_ID = m_Configuration["Aliyun:PayH5:AppId"];
Ali_APP_PRIVATE_KEY = m_Configuration["Aliyun:PayH5:PrivateKey"];
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:PayH5:PublicKey"];
callBackUrl = m_Configuration["Aliyun:PayH5:NotifyUrl"];
ReturnUrl = m_Configuration["Aliyun:PayH5:ReturnUrl"];
// 组装业务参数model
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel
{
Body = request.PackageName,
Subject = oName,
TotalAmount = request.OtherPayAmount.ToString(),
OutTradeNo = request.OrderNo,
ProductCode = "QUICK_WAP_PAY",
QuitUrl =this.Request.GetUrl(),
TimeoutExpress = "15m"
};
AlipayTradeWapPayRequest aliRequest = new AlipayTradeWapPayRequest();
// 设置同步回调地址
aliRequest.SetReturnUrl(ReturnUrl);
// 设置异步通知接收地址
aliRequest.SetNotifyUrl(callBackUrl);
// 将业务model载入到request
aliRequest.SetBizModel(model);
var _aopClient = new DefaultAopClient("https://openapi.alipay.com/gateway.do", Ali_APP_ID, Ali_APP_PRIVATE_KEY);
var response = await _aopClient.PageExecuteAsync(aliRequest);
return response.Body;
}
return "";
}
/// <summary>
/// 支付同步回调
/// </summary>
[HttpGet, AllowAnonymous]
public IActionResult AliReturn()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
Dictionary<string, string> sArray = GetRequestGet();
if (sArray.Count != 0)
{
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
var ordereNo = sArray["out_trade_no"];
// var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
Console.WriteLine($"同步验证通过,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证通过";
}
else
{
Console.WriteLine($"同步验证失败,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证失败";
}
}
return Redirect("~/User/MyAccounts");
}
[HttpPost, AllowAnonymous]
public async Task AliNotify()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
Dictionary<string, string> sArray = GetRequestPost();
LogHelper.Info("AliNotify", AlipaySignature.GetSignContent(sArray));
if (sArray.Count != 0)
{
// bool flag = AlipaySignature.RSA2Check(sArray, ALIPAY_PUBLIC_KEY);
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
//交易状态
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理根据订单号out_trade_no在商户网站的订单系统中查到该笔订单的详细并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
try
{
var ordereNo = sArray["out_trade_no"];
var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
if (order.OrderState == OrderStatus.Complete|| order.OrderState == OrderStatus.PayOk)
{
await Response.WriteAsync("success");
return;
}
order.OrderState = OrderStatus.PayOk;
order.TradeNo = sArray["trade_no"];
order.UpdateTime = DateTime.Now;
await m_ProductOrderService.Update(order);
await m_ProductOrderService.ProcessOrderAccount(order);
Console.WriteLine(Request.Form["trade_status"]);
await Response.WriteAsync("success");
}catch(Exception ex)
{
LogHelper.Error("AliNotify.Exception", ex.Message);
await Response.WriteAsync("fail");
}
}
else
{
LogHelper.Error("AliNotify.Error", "签名校验失败");
await Response.WriteAsync("fail");
}
}
}
/// <summary>
/// 支付同步回调
/// </summary>
[HttpGet, AllowAnonymous]
public IActionResult AliReturnH5()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:PayH5:PublicKey"];
Dictionary<string, string> sArray = GetRequestGet();
if (sArray.Count != 0)
{
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
var ordereNo = sArray["out_trade_no"];
// var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
Console.WriteLine($"同步验证通过,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证通过";
}
else
{
Console.WriteLine($"同步验证失败,订单号:{sArray["out_trade_no"]}");
ViewData["PayResult"] = "同步验证失败";
}
}
return Redirect("~/User/MyAccounts");
}
[HttpPost, AllowAnonymous]
public async Task AliNotifyH5()
{
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3、校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4、验证app_id是否为该商户本身。
*/
ALIPAY_PUBLIC_KEY = m_Configuration["Aliyun:PayH5:PublicKey"];
Dictionary<string, string> sArray = GetRequestPost();
LogHelper.Info("AliNotify", AlipaySignature.GetSignContent(sArray));
if (sArray.Count != 0)
{
// bool flag = AlipaySignature.RSA2Check(sArray, ALIPAY_PUBLIC_KEY);
bool flag = AlipaySignature.RSACheckV2(sArray, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2", false);
if (flag)
{
//交易状态
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理根据订单号out_trade_no在商户网站的订单系统中查到该笔订单的详细并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
try
{
var ordereNo = sArray["out_trade_no"];
var order = await m_ProductOrderService.GetOrderByNo(ordereNo);
if (order.OrderState == OrderStatus.Complete || order.OrderState == OrderStatus.PayOk)
{
await Response.WriteAsync("success");
return;
}
order.OrderState = OrderStatus.PayOk;
order.TradeNo = sArray["trade_no"];
order.UpdateTime = DateTime.Now;
await m_ProductOrderService.Update(order);
await m_ProductOrderService.ProcessOrderAccount(order);
Console.WriteLine(Request.Form["trade_status"]);
await Response.WriteAsync("success");
}
catch (Exception ex)
{
LogHelper.Error("AliNotify.Exception", ex.Message);
await Response.WriteAsync("fail");
}
}
else
{
LogHelper.Error("AliNotify.Error", "签名校验失败");
await Response.WriteAsync("fail");
}
}
}
private Dictionary<string, string> GetRequestGet()
{
Dictionary<string, string> sArray = new Dictionary<string, string>();
ICollection<string> requestItem = Request.Query.Keys;
foreach (var item in requestItem)
{
sArray.Add(item, Request.Query[item]);
}
return sArray;
}
private Dictionary<string, string> GetRequestPost()
{
Dictionary<string, string> sArray = new Dictionary<string, string>();
ICollection<string> requestItem = Request.Form.Keys;
foreach (var item in requestItem)
{
sArray.Add(item, Request.Form[item]);
}
return sArray;
}
#endregion
//[HttpGet]
//public async Task<IActionResult> Success()
//{
// return Content("Success");
//}
//[HttpGet]
//public async Task<IActionResult> ErrorInfo()
//{
// return Content("Error");
//}
[HttpGet, UserAuth]
public async Task<IActionResult> TestIndex(int id)
{
var userId = this.Request.GetUserInfo().UserId;
var product = await m_ProductService.GetById(id);
var package = await m_ProductPackageService.Query(m => m.IsTest == 1 && m.ProductId == id).FirstOrDefaultAsync();
var restTimes = await m_ProductAccountService.GetRestTestCount(userId);
return View("Test", new PackageInfoResponse()
{
Package = package,
Product = product,
RestTimes = restTimes
});
}
[HttpGet, UserAuth]
public async Task<IActionResult> Test(int id)
{
var product = await m_ProductService.GetById(id);
var package = await m_ProductPackageService.Query(m => m.IsTest == 1 && m.ProductId == id).FirstOrDefaultAsync();
var restTimes = 0;
var userInfo = this.Request.GetUserInfo();
if (userInfo != null)
{
var userId = userInfo.UserId;
restTimes = await m_ProductAccountService.GetRestTestCount(userId);
}
return View("Test", new PackageInfoResponse()
{
Package = package,
Product = product,
RestTimes = restTimes
});
}
[HttpGet]
public async Task<IActionResult> Soft()
{
var ret = await m_ProductService.Query(true).ToListAsync();
return View(ret);
}
[HttpGet, AllowAnonymous]
public async Task<ApiResult> IsPay(string orderNo)
{
var orderInfo=await m_ProductOrderService.GetOrderByNo(orderNo);
if (orderInfo.OrderState == OrderStatus.PayOk || orderInfo.OrderState == OrderStatus.Complete)
return new ApiResult(1);
else
return new ApiResult(0);
}
[HttpGet,UserAuth]
public async Task<IActionResult> Buy(int id)
{
var userId = this.Request.GetUserInfo().UserId;
var package = await m_ProductPackageService.GetById(id);
var product = await m_ProductService.GetById(package.ProductId);
var userPrice = await m_ProductUserPriceService.GetPackageUserPrice(package.Id, userId);
if (userPrice != null && userPrice.UserPrice > 0)
{
package.Price = userPrice.UserPrice;
}
return View("buy", new PackageInfoResponse()
{
Package = package,
Product = product
});
}
[HttpGet]
public async Task<IActionResult> ReBuyIndex(string accounts,int productId=0)
{
ViewBag.accounts = "";
ViewBag.errorTip = "";
var model = new ProductWithPackageResponse();
if (accounts.NotHas())
{
ViewBag.errorTip = "请选择账号";
return View(model);
}
var accountList = await m_ProductAccountService.GetAccounts(accounts);
if (productId > 0)
accountList = accountList.Where(m => m.ProductId == productId).ToList();
var productIds = accountList.Select(m => m.ProductId);
var connectCountList = accountList.Select(m => m.ConnectCount);
if (productIds.Distinct().Count() != 1 || connectCountList.Distinct().Count() != 1)
{
ViewBag.errorTip = "续费账号必须为同一种产品且相同的连接数";
return View(model);
}
ViewBag.accounts = accounts;
var id = productIds.First().Value;
var respList = await m_ProductService.GetOneProductWithPackage(id);
var userInfo = this.Request.GetUserInfo();
if (userInfo != null)
{
var userPrices = await m_ProductUserPriceService.GetProductUserPrice(id, userInfo.UserId);
respList.Packages.ForEach(m =>
{
var userPrice = userPrices.FirstOrDefault(p => p.PackageId == m.Id);
if (userPrice != null && userPrice.UserPrice > 0)
{
m.Price = userPrice.UserPrice;
}
});
}
return View(respList);
}
[HttpGet,UserAuth]
public async Task<IActionResult> ReBuy(int packageId, string accounts)
{
var package = await m_ProductPackageService.GetById(packageId);
var product = await m_ProductService.GetById(package.ProductId);
var account = "";
if (accounts.IndexOf(",") == -1)
{
account = accounts;
}
else
{
account = accounts.Split(',')[0];
}
var accountEntity = await m_ProductAccountService.GetProductAccountInfo(package.ProductId, account);
var userId = this.Request.GetUserInfo().UserId;
var userPrice = await m_ProductUserPriceService.GetPackageUserPrice(packageId, userId);
if (userPrice != null && userPrice.UserPrice > 0)
{
package.Price = userPrice.UserPrice;
}
var model = new PackageInfoResponse()
{
Package = package,
Product = product
};
ViewBag.accounts = accounts;
ViewBag.orderType = accounts.Split(",").Count() > 1 ? 4 : 3;
ViewBag.ConnectCount = accountEntity == null ? 1 : accountEntity.ConnectCount;
return View(model);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using Hncore.Pass.BaseInfo.Service;
using Hncore.Pass.Sells.Service;
using Hncore.Wx.Open;
using Home.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Senparc.NeuChar.App.Entities;
using Senparc.Weixin.MP;
using System;
using System.Threading.Tasks;
namespace Home.Controllers
{
[AllowAnonymous]
[Controller]
[Route("[Controller]/[Action]")]
public class WeiXinController : Controller
{
WxAppUserService m_WxAppUserService;
CouponService m_CouponService;
IConfiguration m_Configuration;
public WeiXinController(IConfiguration _Configuration
, WxAppUserService _WxAppUserService
, CouponService _CouponService)
{
m_WxAppUserService = _WxAppUserService;
m_CouponService = _CouponService;
m_Configuration = _Configuration;
}
[HttpGet]
[ActionName("Index")]
public ActionResult Get(string signature, string timestamp, string nonce, string echostr)
{
if (CheckSignature.Check(signature, timestamp, nonce, "hualian"))
{
return Content(echostr); //返回随机字符串则表示验证通过
}
else
{
return Content("failed");
}
}
/// <summary>
/// 最简化的处理流程(不加密)
/// </summary>
[HttpPost]
[ActionName("Index")]
public ActionResult Post(PostModel postModel)
{
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, "hualian"))
{
return Content("参数错误!");
}
postModel.Token ="hualian";
postModel.EncodingAESKey = m_Configuration["WxApps:EncodingAESKey"];//根据自己后台的设置保持一致
postModel.AppId = m_Configuration["WxApps:AppID"];//根据自己后台的设置保持一致
var messageHandler = new MyMessageHandler(Request.Body, m_WxAppUserService,m_CouponService);
messageHandler.Execute();//执行微信处理过程
return Content(messageHandler.ResponseDocument.ToString());//v0.7-
//return new WeixinResult(messageHandler);//v0.8+
// return new FixWeixinBugWeixinResult(messageHandler);//v0.8+
}
/// <summary>
/// 微信后台推送过来的用户与公众号交互的信息 消息和事件
/// </summary>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <param name="encrypt_type"></param>
/// <param name="msg_signature"></param>
/// <returns></returns>
[HttpPost("{appid}"), AllowAnonymous]
public async Task<string> msg_notice(string appid, string timestamp, string nonce, string encrypt_type, string msg_signature)
{
LogHelper.Debug("公众号交互消息", $"appid={appid}{timestamp},{nonce},{encrypt_type},{msg_signature}");
var msg = await this.Request.Body.ReadAsStringAsync();
LogHelper.Debug("公众号交互消息-加密", msg);
var token = m_Configuration["WxOpen:Token"];
var decyptKey = m_Configuration["WxOpen:DecyptKey"];
var appID = m_Configuration["WxOpen:AppID"];
string decMsg = "";
var wxcpt = new WxOpenCrypt(token, decyptKey, appID);
var ret = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, msg, ref decMsg);
if (ret != 0)
{
LogHelper.Error("开放平台推送的消息-解密失败", ret);
return "faild";
}
var flag = false;
try
{
var requestMessage = MessageFactory.GetRequestEntity(decMsg);
if (requestMessage != null)
{
requestMessage.AppId = appid;
flag = await requestMessage.Handler();
}
}
catch (Exception ex)
{
LogHelper.Fatal("微信开放平台的消息-解析失败", ex.Message);
LogHelper.Error("开放平台推送的消息-解密的消息", decMsg);
flag = false;
}
return flag ? "success" : "faild";
}
}
}