调整支付模块逻辑
parent
7f5c1f5197
commit
9ba902a573
|
|
@ -1,9 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using New_College.Common.Helper;
|
||||||
using New_College.IServices;
|
using New_College.IServices;
|
||||||
using New_College.Model;
|
using New_College.Model;
|
||||||
using New_College.Model.ViewModels;
|
using New_College.Model.ViewModels;
|
||||||
|
|
@ -20,6 +22,10 @@ namespace New_College.Api.Controllers.Front
|
||||||
v_OrderInfoServices = IV_OrderInfoServices;
|
v_OrderInfoServices = IV_OrderInfoServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下订单
|
/// 下订单
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using New_College.Common.Helper;
|
||||||
|
using New_College.IServices;
|
||||||
|
using New_College.Services;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace New_College.Api.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class PayQrCodeController : Controller
|
||||||
|
{
|
||||||
|
private readonly IV_OrderInfoServices v_OrderInfoServices;
|
||||||
|
public PayQrCodeController(IV_OrderInfoServices OrderInfoServices)
|
||||||
|
{
|
||||||
|
|
||||||
|
v_OrderInfoServices = OrderInfoServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成支付图片
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
[Route("/payqrcode/create")]
|
||||||
|
public async Task<IActionResult> Create([FromQuery] WeChatPayTransactionsNativeQuery query)
|
||||||
|
{
|
||||||
|
|
||||||
|
var filestream = await v_OrderInfoServices.QrCodePay(query);
|
||||||
|
|
||||||
|
return File(filestream, "image/png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -72,7 +72,7 @@ namespace New_College.Api.Controllers.Front
|
||||||
data.SetValue("openid", query.OpenId);
|
data.SetValue("openid", query.OpenId);
|
||||||
//可以将用户Id和订单Id同时封装在attach中
|
//可以将用户Id和订单Id同时封装在attach中
|
||||||
data.SetValue("attach", string.Format("{0}|{1}", query.OpenId, payNum));
|
data.SetValue("attach", string.Format("{0}|{1}", query.OpenId, payNum));
|
||||||
WxPayData result = UnifiedOrder(data);
|
WxPayData result = WeChatPayV3.UnifiedOrder(data);
|
||||||
if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")
|
if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")
|
||||||
{
|
{
|
||||||
resp.err_code_des = result.GetValue("err_code_des").ToString();
|
resp.err_code_des = result.GetValue("err_code_des").ToString();
|
||||||
|
|
@ -240,116 +240,6 @@ namespace New_College.Api.Controllers.Front
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* 统一下单
|
|
||||||
* @param WxPaydata inputObj 提交给统一下单API的参数
|
|
||||||
* @param int timeOut 超时时间
|
|
||||||
* @throws WePayException
|
|
||||||
* @return 成功时返回,其他抛异常
|
|
||||||
*/
|
|
||||||
public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 60)
|
|
||||||
{
|
|
||||||
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
|
||||||
//检测必填参数
|
|
||||||
if (!inputObj.IsSet("out_trade_no"))
|
|
||||||
{
|
|
||||||
throw new Exception("缺少统一支付接口必填参数out_trade_no!");
|
|
||||||
}
|
|
||||||
else if (!inputObj.IsSet("body"))
|
|
||||||
{
|
|
||||||
throw new Exception("缺少统一支付接口必填参数body!");
|
|
||||||
}
|
|
||||||
else if (!inputObj.IsSet("total_fee"))
|
|
||||||
{
|
|
||||||
throw new Exception("缺少统一支付接口必填参数total_fee!");
|
|
||||||
}
|
|
||||||
else if (!inputObj.IsSet("trade_type"))
|
|
||||||
{
|
|
||||||
throw new Exception("缺少统一支付接口必填参数trade_type!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//关联参数
|
|
||||||
if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
|
|
||||||
{
|
|
||||||
throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
|
|
||||||
}
|
|
||||||
if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
|
|
||||||
{
|
|
||||||
throw new Exception("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//异步通知url未设置,则使用配置文件中的url
|
|
||||||
if (!inputObj.IsSet("notify_url"))
|
|
||||||
{
|
|
||||||
inputObj.SetValue("notify_url", WeixinConfig.NotifyUrl);//异步通知url
|
|
||||||
}
|
|
||||||
|
|
||||||
inputObj.SetValue("appid", WeixinConfig.Appid);//公众账号ID
|
|
||||||
inputObj.SetValue("mch_id", WeixinConfig.MCHID);//商户号
|
|
||||||
inputObj.SetValue("spbill_create_ip", WePayConfig.IP);//终端ip
|
|
||||||
inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
|
|
||||||
|
|
||||||
//签名
|
|
||||||
inputObj.SetValue("sign", inputObj.MakeSign());
|
|
||||||
string xml = inputObj.ToXml();
|
|
||||||
|
|
||||||
var start = DateTime.Now;
|
|
||||||
|
|
||||||
// Log.Info("XcxPayApi", "UnfiedOrder request : " + xml);
|
|
||||||
string response = HttpPost(xml, url, "application/xml", timeOut);
|
|
||||||
//Log.Info("XcxPayApi", "UnfiedOrder response : " + response);
|
|
||||||
// WebHookHelper.WebHookmarkdownSend(response);
|
|
||||||
|
|
||||||
var end = DateTime.Now;
|
|
||||||
int timeCost = (int)((end - start).TotalMilliseconds);
|
|
||||||
|
|
||||||
WxPayData result = new WxPayData();
|
|
||||||
result.FromXml(response);
|
|
||||||
// ReportCostTime(url, timeCost, result);//测速上报网络不好时使用
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 生成随机数
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GenerateNonceStr()
|
|
||||||
{
|
|
||||||
return Guid.NewGuid().ToString().Replace("-", "");
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// POST请求
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="postData"></param>
|
|
||||||
/// <param name="url"></param>
|
|
||||||
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
|
|
||||||
/// <param name="timeOut"></param>
|
|
||||||
/// <param name="headers"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string HttpPost(string postData, string url, string contentType = null, int timeOut = 30, Dictionary<string, string> headers = null)
|
|
||||||
{
|
|
||||||
postData = postData ?? "";
|
|
||||||
|
|
||||||
var httpClientHandler = new HttpClientHandler
|
|
||||||
{
|
|
||||||
ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true
|
|
||||||
};
|
|
||||||
using (HttpClient httpClient = new HttpClient(httpClientHandler))
|
|
||||||
{
|
|
||||||
if (headers != null)
|
|
||||||
{
|
|
||||||
foreach (var header in headers)
|
|
||||||
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
|
|
||||||
}
|
|
||||||
using (HttpContent client = new StringContent(postData, Encoding.UTF8))
|
|
||||||
{
|
|
||||||
if (contentType != null)
|
|
||||||
client.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
|
|
||||||
|
|
||||||
HttpResponseMessage response = httpClient.PostAsync(url, client).Result;
|
|
||||||
return response.Content.ReadAsStringAsync().Result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3495,11 +3495,6 @@
|
||||||
支付结果回调URL
|
支付结果回调URL
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="T:New_College.Model.ViewModels.WePayConfig">
|
|
||||||
<summary>
|
|
||||||
|
|
||||||
</summary>
|
|
||||||
</member>
|
|
||||||
<member name="P:New_College.Model.ViewModels.NameBaseQuery.Type">
|
<member name="P:New_College.Model.ViewModels.NameBaseQuery.Type">
|
||||||
<summary>
|
<summary>
|
||||||
本科/专科大类 1本科 2 专科
|
本科/专科大类 1本科 2 专科
|
||||||
|
|
|
||||||
|
|
@ -970,31 +970,6 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:New_College.Api.Controllers.Front.WeixinPayController.UnifiedOrder(New_College.Common.WxPayData,System.Int32)">
|
|
||||||
|
|
||||||
统一下单
|
|
||||||
@param WxPaydata inputObj 提交给统一下单API的参数
|
|
||||||
@param int timeOut 超时时间
|
|
||||||
@throws WePayException
|
|
||||||
@return 成功时返回,其他抛异常
|
|
||||||
</member>
|
|
||||||
<member name="M:New_College.Api.Controllers.Front.WeixinPayController.GenerateNonceStr">
|
|
||||||
<summary>
|
|
||||||
生成随机数
|
|
||||||
</summary>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:New_College.Api.Controllers.Front.WeixinPayController.HttpPost(System.String,System.String,System.String,System.Int32,System.Collections.Generic.Dictionary{System.String,System.String})">
|
|
||||||
<summary>
|
|
||||||
POST请求
|
|
||||||
</summary>
|
|
||||||
<param name="postData"></param>
|
|
||||||
<param name="url"></param>
|
|
||||||
<param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
|
|
||||||
<param name="timeOut"></param>
|
|
||||||
<param name="headers"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="F:New_College.Api.Controllers.HighSchoolRankController._d_HighSchoolRankServices">
|
<member name="F:New_College.Api.Controllers.HighSchoolRankController._d_HighSchoolRankServices">
|
||||||
<summary>
|
<summary>
|
||||||
服务器接口,因为是模板生成,所以首字母是大写的,自己可以重构下
|
服务器接口,因为是模板生成,所以首字母是大写的,自己可以重构下
|
||||||
|
|
@ -1019,6 +994,13 @@
|
||||||
<param name="request"></param>
|
<param name="request"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:New_College.Api.Controllers.PayQrCodeController.Create(New_College.Common.Helper.WeChatPayTransactionsNativeQuery)">
|
||||||
|
<summary>
|
||||||
|
生成支付图片
|
||||||
|
</summary>
|
||||||
|
<param name="query"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="F:New_College.Api.Controllers.SeVolunteerInitializationController._d_SeVolunteerInitializationServices">
|
<member name="F:New_College.Api.Controllers.SeVolunteerInitializationController._d_SeVolunteerInitializationServices">
|
||||||
<summary>
|
<summary>
|
||||||
服务器接口,因为是模板生成,所以首字母是大写的,自己可以重构下
|
服务器接口,因为是模板生成,所以首字母是大写的,自己可以重构下
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,7 @@ using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using New_College.Model.ViewModels;
|
using New_College.Model.ViewModels;
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay;
|
|
||||||
using Essensoft.AspNetCore.Payment.Alipay;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||||
|
|
@ -30,6 +29,7 @@ using System.Text.Encodings.Web;
|
||||||
using System.Text.Unicode;
|
using System.Text.Unicode;
|
||||||
using Microsoft.AspNetCore.ResponseCompression;
|
using Microsoft.AspNetCore.ResponseCompression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Senparc.Weixin.RegisterServices;
|
||||||
|
|
||||||
namespace New_College
|
namespace New_College
|
||||||
{
|
{
|
||||||
|
|
@ -83,7 +83,6 @@ namespace New_College
|
||||||
CasdoorConfig.CallbackPath = Appsettings.app(new string[] { "Casdoor", "CallbackPath" });
|
CasdoorConfig.CallbackPath = Appsettings.app(new string[] { "Casdoor", "CallbackPath" });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
services.AddMemoryCacheSetup();
|
services.AddMemoryCacheSetup();
|
||||||
services.AddSqlsugarSetup();
|
services.AddSqlsugarSetup();
|
||||||
services.AddDbSetup();
|
services.AddDbSetup();
|
||||||
|
|
@ -95,8 +94,9 @@ namespace New_College
|
||||||
services.AddHttpContextSetup();
|
services.AddHttpContextSetup();
|
||||||
services.AddAppConfigSetup();
|
services.AddAppConfigSetup();
|
||||||
services.AddHttpApi();
|
services.AddHttpApi();
|
||||||
|
|
||||||
|
|
||||||
|
//Senparc.Weixin 注册(必须)
|
||||||
|
services.AddSenparcWeixinServices(Configuration);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -215,6 +215,8 @@ namespace New_College
|
||||||
// 封装Swagger展示
|
// 封装Swagger展示
|
||||||
app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("New_College.Api.index.html"));
|
app.UseSwaggerMildd(() => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("New_College.Api.index.html"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ↓↓↓↓↓↓ 注意下边这些中间件的顺序,很重要 ↓↓↓↓↓↓
|
// ↓↓↓↓↓↓ 注意下边这些中间件的顺序,很重要 ↓↓↓↓↓↓
|
||||||
|
|
||||||
// CORS跨域
|
// CORS跨域
|
||||||
|
|
|
||||||
|
|
@ -216,5 +216,38 @@
|
||||||
"ClientSecret": "cc385a5d0efd5f7bf693d8c4574126158f7b0a8f",
|
"ClientSecret": "cc385a5d0efd5f7bf693d8c4574126158f7b0a8f",
|
||||||
"CallbackPath": "http://test.sso.ycymedu.com/login/oauth/authorize?client_id=4c6d761417dbbdd665be&response_type=code&redirect_uri=http://192.168.100.129:8081/Home/FirstPage&scope=read&state=casdoor",
|
"CallbackPath": "http://test.sso.ycymedu.com/login/oauth/authorize?client_id=4c6d761417dbbdd665be&response_type=code&redirect_uri=http://192.168.100.129:8081/Home/FirstPage&scope=read&state=casdoor",
|
||||||
"RequireHttpsMetadata": false
|
"RequireHttpsMetadata": false
|
||||||
|
},
|
||||||
|
"WeChatPay": {
|
||||||
|
// 应用号
|
||||||
|
// 如:微信公众平台AppId、微信开放平台AppId、微信小程序AppId、企业微信CorpId等
|
||||||
|
"AppId": "wx1bfbd8233a2d3261",
|
||||||
|
"AppSecret": "c12d2bf676a3b11d542efd7f477a72f3",
|
||||||
|
// 商户号
|
||||||
|
// 为微信支付商户平台的商户号
|
||||||
|
"MchId": "1614987630",
|
||||||
|
|
||||||
|
// 商户API密钥
|
||||||
|
// 为微信支付商户平台的API密钥,请注意不是APIv3密钥
|
||||||
|
"APIKey": "",
|
||||||
|
|
||||||
|
// 商户APIv3密钥
|
||||||
|
// 为微信支付商户平台的APIv3密钥,请注意不是API密钥,v3接口必填
|
||||||
|
"APIv3Key": "brapuk6fon0wachiMlth2t3lb4a0h7ji",
|
||||||
|
|
||||||
|
// 商户API证书
|
||||||
|
// 使用V2退款、付款等接口时必填
|
||||||
|
// 使用V3接口时必填
|
||||||
|
// 可为证书文件路径 / 证书文件的base64字符串
|
||||||
|
"Certificate": "MIID9jCCAt6gAwIBAgIUX7aJQ2iVIFJNjycVSZIGI+dcI10wDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsTFFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3QgQ0EwHhcNMjIxMjEyMDUxMjE1WhcNMjcxMjExMDUxMjE1WjCBhzETMBEGA1UEAwwKMTYxNDk4NzYzMDEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTMwMQYDVQQLDCrkuIrmtbfkuIDojYnkuIDmnKjmlZnogrLnp5HmioDmnInpmZDlhazlj7gxCzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALlWoiOOEEecInVwlNxl78d7xkk+Q1ZMZHaVyiyrBbY0ik55fRwg76s3u3q67IYv/UDgik8thWRc0KvL/rhiyb+h9F9/aTWZ2LXoCXiFbtzNBV40aHshi4QNOfmdEPHmMytwohRJB/MUPo8lJpG1hB/6OgNJjsqbBNXTm7HtU4A9okqSaUUgzgbaWuDOON8BXHqBsR36gHAWCfr2ecFw0QBh/9mwn/DkF25vbR/QLXCsKIw3LF6BkWOdBUNvnJYHxF2yMvMV5cflsutkf63bfSF5qznVNAiMfMmhhfM3OqtOvk48PtLkHDcfC0XJuud9VFAxp8GaLSU6IJr2vM6KDjkCAwEAAaOBgTB/MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MGUGA1UdHwReMFwwWqBYoFaGVGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4RUJEMjANBgkqhkiG9w0BAQsFAAOCAQEAU39wePx6nBiHGKsRkfIDgQH1VEcoyXDIdORkyV2UvhX5MPo9fCOSU2vT4HiuyTKs5W74I7+4jEmqLtS5UzUhAu6K5Bl80yYmXErHRZIaF0fpxT+LAHocsCIC5B8grVWNDztu6F9UqB7Ngr8bfHm1j2esnb0x48UvWm2Uqn2Z38RT4BPty048yYdcVVndYRPigL+I4QfkVZZVJmxAi/wZXiKBSOb9Rp2du8NyNrEPiBDZWXRF5HLxgJoJtXY8tLJPUY5Lm6M1TlhnCvNbVSode8HazI6paCOvQHYN73D27Ie+G5SEic8iR0MFfsXNeKol+sF8iAeDN94EpvPD0ZkfPg==",
|
||||||
|
// 商户API私钥
|
||||||
|
// 当配置了P12格式证书时,已包含私钥,不必再单独配置API私钥。
|
||||||
|
// PEM格式证书,需要单独配置。
|
||||||
|
"APIPrivateKey": "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5VqIjjhBHnCJ1cJTcZe/He8ZJPkNWTGR2lcosqwW2NIpOeX0cIO+rN7t6uuyGL/1A4IpPLYVkXNCry/64Ysm/ofRff2k1mdi16Al4hW7czQVeNGh7IYuEDTn5nRDx5jMrcKIUSQfzFD6PJSaRtYQf+joDSY7KmwTV05ux7VOAPaJKkmlFIM4G2lrgzjjfAVx6gbEd+oBwFgn69nnBcNEAYf/ZsJ/w5Bdub20f0C1wrCiMNyxegZFjnQVDb5yWB8RdsjLzFeXH5bLrZH+t230heas51TQIjHzJoYXzNzqrTr5OPD7S5Bw3HwtFybrnfVRQMafBmi0lOiCa9rzOig45AgMBAAECggEABiuyPkjOlfPG2e4jpqrmLtgaI/okt8zXU3NtRctz5zscl7xHxBX8pNC4Nz/d/CHA5tYTBMvZMxw7/lxOYMk5Ol4kCsHtONGke3n8Rrz6kfNpiFdqWx8kzAK8uWjXVZZ6ganAW7iKwTcdVhrAi/1lJsNoBw/95xT+NjhTaLskGpLkQPEwct1Ygc7Ce+5d/UCphdk351sRzhEf1dgaAbn+/fHD599fpo87YCO1QPChTy+jp7e+d6B3QxspNCeTcpCdxevM1EVAYlDYOivONM9RQSAPWjsErIxKyN5nvusFhO4xrSIfg6uRkGEVKiDMIU6C8O3XVcwH9vIw3az5SUFRAQKBgQDcYcRZP+GNU3YpFj2Zcn2I9WNXwSU32Wp1wNEgKwvTv9fXDxYiuK6OjIM76DhcsuO1ew7dTtFXfSrmEkIXRBf4XmMes0I6RD/Ds1tB+hCo71b3OX28C4bzCd4IicY/9JpG8cYRReFKd42XX/9N7qxxZ8vefSq5xNzbDOtKRnBJCQKBgQDXSvPpiDRMTDuQ+hkyW4s+dYt9Mj9xSKiKQiGc84yPcboLgMYwf3A0P6eDCHFN1G63MKuwg36cgI8uhkNjv757NzR5195jDx56tvnx1s+DqPKLX5Cd0UOQLtjFSxTyRaOAHz4Fc06zQBQ0Zp3P+xZQFZe8K2cIBy4hM0FNqknXsQKBgE9pDzZVtXGWVGqDsBidz6xNN8nEOCQCvMDHhNOBj1Zyt1SwA/ro70VATn2EtOJ6N2EKgZWvM/HBkXart5Lon3aIlFDYqRGTzCI5e7WvZNdqvryAw9TBlpP2x0HuWzhqbDkKH6PTuVV69NNJ7RXo3cxTaXu3QHEGBcsMwa/W59j5AoGBALvzhWj1LaMGUmJI1MJvxOosODB+M4C0i97XyPx6atW31VHBhERGnTAf+h+cuT3XHSj0Zo7c3SXH3jghoqdsd+Cd20QbvtwAEP3Uy/PjMpqgXc5rCZedXzx6iWgEGi8/uHNb0wtzFNvML1dn1pIBhAM6NpNh2LrbedwmIPaqmXihAoGASTRxC8cOvjEwGrwxHkN9ZPOIK3OTFGkPrJxF3byskQEpc7zOKRx+kxeRvZ5jKacMqW2ns3yMR+JZO9devWotpx+mj5mlWMUC5bQB9BnwForuD4vKDjb5Y8IEAQTopUxWApzK2CQCLETUhCDl1+eQ+EUUoISFHO99qBT6Vpu7qNE=",
|
||||||
|
// RSA公钥
|
||||||
|
// 目前仅调用"企业付款到银行卡API [V2]"时使用,执行本示例中的"获取RSA加密公钥API [V2]"即可获取。
|
||||||
|
"RsaPublicKey": "/apiclient_cert.p12",
|
||||||
|
|
||||||
|
//回调地址
|
||||||
|
"NotifyUrl": "https://pay.ycymedu.com/api/notify/transactions"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -216,5 +216,37 @@
|
||||||
"ClientSecret": "d556f0692052a2df56614282dd86895b04783262",
|
"ClientSecret": "d556f0692052a2df56614282dd86895b04783262",
|
||||||
"CallbackPath": "http://192.168.103.119:8000/login/oauth/authorize?client_id=ae6bdccc3a7821232b31&response_type=code&redirect_uri=http://192.168.103.100:8083/callback&scope=read&state=casdoor",
|
"CallbackPath": "http://192.168.103.119:8000/login/oauth/authorize?client_id=ae6bdccc3a7821232b31&response_type=code&redirect_uri=http://192.168.103.100:8083/callback&scope=read&state=casdoor",
|
||||||
"RequireHttpsMetadata": false
|
"RequireHttpsMetadata": false
|
||||||
|
},
|
||||||
|
"SenparcWeixinSetting": {
|
||||||
|
//以下为 Senparc.Weixin 的 SenparcWeixinSetting 微信配置
|
||||||
|
//注意:所有的字符串值都可能被用于字典索引,因此请勿留空字符串(但可以根据需要,删除对应的整条设置)!
|
||||||
|
|
||||||
|
//微信全局
|
||||||
|
"IsDebug": true,
|
||||||
|
|
||||||
|
//以下不使用的参数可以删除,key 修改后将会失效
|
||||||
|
|
||||||
|
//公众号
|
||||||
|
"Token": "#{Token}#", //说明:字符串内两侧#和{}符号为 Azure DevOps 默认的占位符格式,如果您有明文信息,请删除同占位符,修改整体字符串,不保留#和{},如:{"Token": "MyFullToken"}
|
||||||
|
"EncodingAESKey": "#{EncodingAESKey}#",
|
||||||
|
"WeixinAppId": "#{WeixinAppId}#",
|
||||||
|
"WeixinAppSecret": "#{WeixinAppSecret}#",
|
||||||
|
|
||||||
|
//微信支付V3
|
||||||
|
"TenPayV3_AppId": "#{TenPayV3_AppId}#",
|
||||||
|
"TenPayV3_AppSecret": "#{TenPayV3_AppSecret}#",
|
||||||
|
"TenPayV3_SubAppId": "#{TenPayV3_SubAppId}#",
|
||||||
|
"TenPayV3_SubAppSecret": "#{TenPayV3_SubAppSecret}#",
|
||||||
|
"TenPayV3_MchId": "#{TenPayV3_MchId}#",
|
||||||
|
"TenPayV3_SubMchId": "#{TenPayV3_SubMchId}#", //子商户,没有可留空
|
||||||
|
"TenPayV3_Key": "#{TenPayV3_Key}#",
|
||||||
|
"TenPayV3_TenpayNotify": "#{TenPayV3_TenpayNotify}#", //https://YourDomainName/TenpayApiV3/PayNotifyUrl
|
||||||
|
/* 支付证书私钥
|
||||||
|
* 1、支持明文私钥(无换行字符)
|
||||||
|
* 2、私钥文件路径(如:~/App_Data/cert/apiclient_key.pem),注意:必须放在 App_Data 等受保护的目录下,避免泄露
|
||||||
|
*/
|
||||||
|
"TenPayV3_PrivateKey": "#{TenPayV3_PrivateKey}#", //(新)证书私钥
|
||||||
|
"TenPayV3_SerialNumber": "#{TenPayV3_SerialNumber}#", //(新)证书序列号
|
||||||
|
"TenPayV3_ApiV3Key": "#{TenPayV3_APIv3Key}#" //(新)APIv3 密钥
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ZXing;
|
||||||
|
using ZXing.Common;
|
||||||
|
|
||||||
|
namespace New_College.Common
|
||||||
|
{
|
||||||
|
public static class QrCodeHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 生成二维码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static MemoryStream GerQrCodeStream(string url)
|
||||||
|
{
|
||||||
|
BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 300, 300);
|
||||||
|
var bw = new ZXing.BarcodeWriterPixelData();
|
||||||
|
|
||||||
|
var pixelData = bw.Write(bitMatrix);
|
||||||
|
var bitmap = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
|
||||||
|
var fileStream = new MemoryStream();
|
||||||
|
var bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// we assume that the row stride of the bitmap is aligned to 4 byte multiplied by the width of the image
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
bitmap.UnlockBits(bitmapData);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileStream.Flush();//.net core 必须要加
|
||||||
|
fileStream.Position = 0;//.net core 必须要加
|
||||||
|
|
||||||
|
bitmap.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||||
|
|
||||||
|
fileStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
return fileStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文字图片信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static MemoryStream GetTextImageStream(string text)
|
||||||
|
{
|
||||||
|
MemoryStream fileStream = new MemoryStream();
|
||||||
|
var fontSize = 14;
|
||||||
|
var wordLength = 0;
|
||||||
|
for (int i = 0; i < text.Length; i++)
|
||||||
|
{
|
||||||
|
byte[] bytes = Encoding.Default.GetBytes(text.Substring(i, 1));
|
||||||
|
wordLength += bytes.Length > 1 ? 2 : 1;
|
||||||
|
}
|
||||||
|
using (var bitmap = new System.Drawing.Bitmap(wordLength * fontSize + 20, 14 + 40, System.Drawing.Imaging.PixelFormat.Format32bppRgb))
|
||||||
|
{
|
||||||
|
using (Graphics g = Graphics.FromImage(bitmap))
|
||||||
|
{
|
||||||
|
g.ResetTransform();//重置图像
|
||||||
|
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
|
||||||
|
g.DrawString(text, new Font("宋体", fontSize, FontStyle.Bold), Brushes.White, 10, 10);
|
||||||
|
bitmap.Save(fileStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
return fileStream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V2;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V2.Request;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V2.Response;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
|
|
||||||
namespace New_College.Common.Helper
|
|
||||||
{
|
|
||||||
public class WeChatPay
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 订单查询
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="_client"></param>
|
|
||||||
/// <param name="_optionsAccessor"></param>
|
|
||||||
/// <param name="viewModel"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<WeChatPayOrderQueryResponse> OrderQuery(IWeChatPayClient _client,
|
|
||||||
IOptions<WeChatPayOptions> _optionsAccessor, WeChatPayOrderQuery viewModel)
|
|
||||||
{
|
|
||||||
var request = new WeChatPayOrderQueryRequest
|
|
||||||
{
|
|
||||||
TransactionId = viewModel.TransactionId,
|
|
||||||
OutTradeNo = viewModel.OutTradeNo
|
|
||||||
};
|
|
||||||
return await _client.ExecuteAsync(request, _optionsAccessor.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 返回微信支付链接
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="viewModel"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static async Task<WeChatPayUnifiedOrderResponse> GetMwebUrl(IWeChatPayClient _client, IOptions<WeChatPayOptions> _optionsAccessor,
|
|
||||||
WeChatPayPayRequest viewModel)
|
|
||||||
{
|
|
||||||
var request = new WeChatPayUnifiedOrderRequest
|
|
||||||
{
|
|
||||||
Body = viewModel.Body,
|
|
||||||
OutTradeNo = viewModel.OutTradeNo,
|
|
||||||
TotalFee = viewModel.TotalFee,
|
|
||||||
SpBillCreateIp = viewModel.SpBillCreateIp,
|
|
||||||
NotifyUrl = viewModel.NotifyUrl,
|
|
||||||
TradeType = viewModel.TradeType
|
|
||||||
};
|
|
||||||
return await _client.ExecuteAsync(request, _optionsAccessor.Value);
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 退款
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="_client"></param>
|
|
||||||
/// <param name="_optionsAccessor"></param>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static async Task<WeChatPayRefundResponse> Refund(IWeChatPayClient _client, IOptions<WeChatPayOptions> _optionsAccessor,
|
|
||||||
WeChatPayRefundQuery query)
|
|
||||||
{
|
|
||||||
var request = new WeChatPayRefundRequest
|
|
||||||
{
|
|
||||||
OutRefundNo = query.OutRefundNo,
|
|
||||||
TransactionId = query.TransactionId,
|
|
||||||
OutTradeNo = query.OutTradeNo,
|
|
||||||
TotalFee = query.TotalFee,
|
|
||||||
RefundFee = query.RefundFee,
|
|
||||||
RefundDesc = query.RefundDesc,
|
|
||||||
NotifyUrl = query.NotifyUrl
|
|
||||||
};
|
|
||||||
var response = await _client.ExecuteAsync(request, _optionsAccessor.Value);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +1,198 @@
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V3;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V3.Domain;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V3.Request;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using NPOI.SS.Formula.Functions;
|
||||||
|
using Senparc.Weixin.TenPayV3;
|
||||||
|
using Senparc.Weixin.TenPayV3.Apis;
|
||||||
|
using Senparc.Weixin.TenPayV3.Apis.BasePay;
|
||||||
|
using Senparc.Weixin.TenPayV3.Entities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
namespace New_College.Common.Helper
|
namespace New_College.Common.Helper
|
||||||
{
|
{
|
||||||
public class WeChatPayV3
|
public static class WeChatPayV3
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 扫码支付-Native下单API
|
/// 扫码支付-Native下单API
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="_client"></param>
|
|
||||||
/// <param name="_optionsAccessor"></param>
|
|
||||||
/// <param name="viewModel"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static async Task<dynamic> QrCodePay(IWeChatPayClient _client,
|
public static async Task<MemoryStream> QrCodePay(int Price, string title)
|
||||||
IOptions<WeChatPayOptions> _optionsAccessor, WeChatPayTransactionsNativeQuery viewModel)
|
|
||||||
{
|
{
|
||||||
var model = new WeChatPayTransactionsNativeBodyModel
|
///native
|
||||||
|
string url = "https://api.mch.weixin.qq.com/v3/pay/transactions/native";
|
||||||
|
|
||||||
|
//使用 Native 支付,输出二维码并展示
|
||||||
|
MemoryStream fileStream = null;//输出图片的URL
|
||||||
|
var price = (int)(Price * 100);
|
||||||
|
var name = title + " - Native 支付";
|
||||||
|
var sp_billno = string.Format("{0}{1}{2}", WeixinConfig.MCHID, SystemTime.Now.ToString("yyyyMMddHHmmss"),
|
||||||
|
TenPayV3Util.BuildRandomStr(6));
|
||||||
|
var notifyUrl = WeixinConfig.NotifyUrl;
|
||||||
|
TransactionsRequestData requestData = new(WeixinConfig.Appid, WeixinConfig.MCHID, name, sp_billno, new TenpayDateTime(DateTime.Now.AddHours(1)), null, notifyUrl, null, new() { currency = "CNY", total = price }, null, null, null, null);
|
||||||
|
BasePayApis basePayApis = new BasePayApis();
|
||||||
|
var result = await basePayApis.NativeAsync(requestData);
|
||||||
|
//进行安全签名验证
|
||||||
|
if (result.VerifySignSuccess == true)
|
||||||
{
|
{
|
||||||
AppId = _optionsAccessor.Value.AppId,
|
fileStream = QrCodeHelper.GerQrCodeStream(result.code_url);
|
||||||
MchId = _optionsAccessor.Value.MchId,
|
}
|
||||||
Amount = new Essensoft.AspNetCore.Payment.WeChatPay.V3.Domain.Amount { Total = viewModel.Total, Currency = "CNY" },
|
else
|
||||||
Description = viewModel.Description,
|
{
|
||||||
NotifyUrl = viewModel.NotifyUrl,
|
fileStream = QrCodeHelper.GetTextImageStream("Native Pay 未能通过签名验证,无法显示二维码");
|
||||||
OutTradeNo = viewModel.OutTradeNo,
|
}
|
||||||
};
|
return fileStream;
|
||||||
var request = new WeChatPayTransactionsNativeRequest();
|
|
||||||
request.SetBodyModel(model);
|
|
||||||
return await _client.ExecuteAsync(request, _optionsAccessor.Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 统一下单
|
||||||
|
* @param WxPaydata inputObj 提交给统一下单API的参数
|
||||||
|
* @param int timeOut 超时时间
|
||||||
|
* @throws WePayException
|
||||||
|
* @return 成功时返回,其他抛异常
|
||||||
|
*/
|
||||||
|
public static WxPayData UnifiedOrder(WxPayData inputObj, int timeOut = 60)
|
||||||
|
{
|
||||||
|
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
|
||||||
|
//检测必填参数
|
||||||
|
if (!inputObj.IsSet("out_trade_no"))
|
||||||
|
{
|
||||||
|
throw new Exception("缺少统一支付接口必填参数out_trade_no!");
|
||||||
|
}
|
||||||
|
else if (!inputObj.IsSet("body"))
|
||||||
|
{
|
||||||
|
throw new Exception("缺少统一支付接口必填参数body!");
|
||||||
|
}
|
||||||
|
else if (!inputObj.IsSet("total_fee"))
|
||||||
|
{
|
||||||
|
throw new Exception("缺少统一支付接口必填参数total_fee!");
|
||||||
|
}
|
||||||
|
else if (!inputObj.IsSet("trade_type"))
|
||||||
|
{
|
||||||
|
throw new Exception("缺少统一支付接口必填参数trade_type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//关联参数
|
||||||
|
if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
|
||||||
|
{
|
||||||
|
throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
|
||||||
|
}
|
||||||
|
if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
|
||||||
|
{
|
||||||
|
throw new Exception("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//异步通知url未设置,则使用配置文件中的url
|
||||||
|
if (!inputObj.IsSet("notify_url"))
|
||||||
|
{
|
||||||
|
inputObj.SetValue("notify_url", WeixinConfig.NotifyUrl);//异步通知url
|
||||||
|
}
|
||||||
|
|
||||||
|
inputObj.SetValue("appid", WeixinConfig.Appid);//公众账号ID
|
||||||
|
inputObj.SetValue("mch_id", WeixinConfig.MCHID);//商户号
|
||||||
|
inputObj.SetValue("spbill_create_ip", WePayConfig.IP);//终端ip
|
||||||
|
inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
|
||||||
|
|
||||||
|
//签名
|
||||||
|
inputObj.SetValue("sign", inputObj.MakeSign());
|
||||||
|
string xml = inputObj.ToXml();
|
||||||
|
|
||||||
|
var start = DateTime.Now;
|
||||||
|
|
||||||
|
// Log.Info("XcxPayApi", "UnfiedOrder request : " + xml);
|
||||||
|
string response = HttpPost(xml, url, "application/xml", timeOut);
|
||||||
|
//Log.Info("XcxPayApi", "UnfiedOrder response : " + response);
|
||||||
|
// WebHookHelper.WebHookmarkdownSend(response);
|
||||||
|
|
||||||
|
var end = DateTime.Now;
|
||||||
|
int timeCost = (int)((end - start).TotalMilliseconds);
|
||||||
|
|
||||||
|
WxPayData result = new WxPayData();
|
||||||
|
result.FromXml(response);
|
||||||
|
// ReportCostTime(url, timeCost, result);//测速上报网络不好时使用
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 生成随机数
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GenerateNonceStr()
|
||||||
|
{
|
||||||
|
return Guid.NewGuid().ToString().Replace("-", "");
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// POST请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="postData"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="contentType">application/xml、application/json、application/text、application/x-www-form-urlencoded</param>
|
||||||
|
/// <param name="timeOut"></param>
|
||||||
|
/// <param name="headers"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string HttpPost(string postData, string url, string contentType = null, int timeOut = 30, Dictionary<string, string> headers = null)
|
||||||
|
{
|
||||||
|
postData = postData ?? "";
|
||||||
|
|
||||||
|
var httpClientHandler = new HttpClientHandler
|
||||||
|
{
|
||||||
|
ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true
|
||||||
|
};
|
||||||
|
using (HttpClient httpClient = new HttpClient(httpClientHandler))
|
||||||
|
{
|
||||||
|
if (headers != null)
|
||||||
|
{
|
||||||
|
foreach (var header in headers)
|
||||||
|
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
|
||||||
|
}
|
||||||
|
using (HttpContent client = new StringContent(postData, Encoding.UTF8))
|
||||||
|
{
|
||||||
|
if (contentType != null)
|
||||||
|
client.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
|
||||||
|
|
||||||
|
HttpResponseMessage response = httpClient.PostAsync(url, client).Result;
|
||||||
|
return response.Content.ReadAsStringAsync().Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class WePayConfig
|
||||||
|
{
|
||||||
|
//=======【商户系统后台机器IP】=====================================
|
||||||
|
/* 此参数可手动配置也可在程序中自动获取
|
||||||
|
*/
|
||||||
|
public const string IP = "8.8.8.8";
|
||||||
|
|
||||||
|
|
||||||
|
//=======【代理服务器设置】===================================
|
||||||
|
/* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)
|
||||||
|
*/
|
||||||
|
public const string PROXY_URL = "";
|
||||||
|
|
||||||
|
//=======【上报信息配置】===================================
|
||||||
|
/* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报
|
||||||
|
*/
|
||||||
|
public const int REPORT_LEVENL = 1;
|
||||||
|
|
||||||
|
//=======【日志级别】===================================
|
||||||
|
/* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息
|
||||||
|
*/
|
||||||
|
public const int LOG_LEVENL = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Domain;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NPOI.SS.Formula.Functions;
|
using NPOI.SS.Formula.Functions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,6 @@
|
||||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.10.0" />
|
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.10.0" />
|
||||||
<PackageReference Include="DingtalkChatbotSdk" Version="1.0.1" />
|
<PackageReference Include="DingtalkChatbotSdk" Version="1.0.1" />
|
||||||
<PackageReference Include="DinkToPdf.Standard" Version="1.1.0" />
|
<PackageReference Include="DinkToPdf.Standard" Version="1.1.0" />
|
||||||
<PackageReference Include="Essensoft.AspNetCore.Payment.Alipay" Version="3.3.2" />
|
|
||||||
<PackageReference Include="Essensoft.AspNetCore.Payment.Security" Version="3.3.2" />
|
|
||||||
<PackageReference Include="Essensoft.AspNetCore.Payment.WeChatPay" Version="3.3.2" />
|
|
||||||
<PackageReference Include="log4net" Version="2.0.15" />
|
<PackageReference Include="log4net" Version="2.0.15" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
|
||||||
|
|
@ -25,6 +22,7 @@
|
||||||
<PackageReference Include="NPOI" Version="2.6.0" />
|
<PackageReference Include="NPOI" Version="2.6.0" />
|
||||||
<PackageReference Include="PdfSharpCore" Version="1.3.62" />
|
<PackageReference Include="PdfSharpCore" Version="1.3.62" />
|
||||||
<PackageReference Include="RestSharp" Version="106.15.0" />
|
<PackageReference Include="RestSharp" Version="106.15.0" />
|
||||||
|
<PackageReference Include="Senparc.Weixin.TenPayV3" Version="1.2.0" />
|
||||||
<PackageReference Include="StackExchange.Redis" Version="2.1.30" />
|
<PackageReference Include="StackExchange.Redis" Version="2.1.30" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.5.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.5.0" />
|
||||||
|
|
||||||
|
|
@ -32,6 +30,7 @@
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="3.3.0-dev-00152" />
|
<PackageReference Include="Serilog.AspNetCore" Version="3.3.0-dev-00152" />
|
||||||
<PackageReference Include="WebApiClient.Extensions.DependencyInjection" Version="2.0.3" />
|
<PackageReference Include="WebApiClient.Extensions.DependencyInjection" Version="2.0.3" />
|
||||||
<PackageReference Include="WebApiClient.JIT" Version="1.1.3" />
|
<PackageReference Include="WebApiClient.JIT" Version="1.1.3" />
|
||||||
|
<PackageReference Include="ZXing.Net" Version="0.16.9" />
|
||||||
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
using New_College.Common;
|
using New_College.Common;
|
||||||
|
using New_College.Common.Helper;
|
||||||
using New_College.IServices.BASE;
|
using New_College.IServices.BASE;
|
||||||
using New_College.Model;
|
using New_College.Model;
|
||||||
using New_College.Model.Models;
|
using New_College.Model.Models;
|
||||||
using New_College.Model.ViewModels;
|
using New_College.Model.ViewModels;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace New_College.IServices
|
namespace New_College.IServices
|
||||||
|
|
@ -13,31 +15,16 @@ namespace New_College.IServices
|
||||||
public interface IV_OrderInfoServices : IBaseServices<V_OrderInfo>
|
public interface IV_OrderInfoServices : IBaseServices<V_OrderInfo>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Task<MemoryStream> QrCodePay(WeChatPayTransactionsNativeQuery viewModel);
|
||||||
|
|
||||||
Task<CreateOrderModel> CreateOrder(UniOrderQuery query);
|
Task<CreateOrderModel> CreateOrder(UniOrderQuery query);
|
||||||
|
|
||||||
Task<bool> UpdateOrderStatus(string orderNo, EnumPayType payType, string trade_no);
|
Task<bool> UpdateOrderStatus(string orderNo, EnumPayType payType, string trade_no);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 唤醒微信H5支付
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<MessageModel<string>> WechatPubPay(WeChatPayQuery query);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 微信订单查询确认 传用户Id
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<MessageModel<bool>> WeChatPayStatus(IdQuery query);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 支付宝 订单确认
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<MessageModel<bool>> AliPayStatus(IdQuery query);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取vip信息(分页)
|
/// 获取vip信息(分页)
|
||||||
|
|
@ -53,12 +40,7 @@ namespace New_College.IServices
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<MessageModel<string>> PaySuccess(V_OrderInfo query);
|
Task<MessageModel<string>> PaySuccess(V_OrderInfo query);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 支付宝H5支付
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<MessageModel<AliOrderResult>> AliH5Pay(WeChatPayQuery query);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
using New_College.Common.Helper;
|
|
||||||
using New_College.IServices.BASE;
|
|
||||||
using New_College.Model.Models;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace New_College.IServices
|
|
||||||
{
|
|
||||||
public interface IWeiChatPayServicesV3 : IBaseServices<V_OrderInfo>
|
|
||||||
{
|
|
||||||
Task<string> QrCodePay(WeChatPayTransactionsNativeQuery viewModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Domain;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
|
||||||
|
|
@ -40,30 +40,5 @@ namespace New_College.Model.ViewModels
|
||||||
public static string NotifyUrl { get; set; }
|
public static string NotifyUrl { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public class WePayConfig
|
|
||||||
{
|
|
||||||
//=======【商户系统后台机器IP】=====================================
|
|
||||||
/* 此参数可手动配置也可在程序中自动获取
|
|
||||||
*/
|
|
||||||
public const string IP = "8.8.8.8";
|
|
||||||
|
|
||||||
|
|
||||||
//=======【代理服务器设置】===================================
|
|
||||||
/* 默认IP和端口号分别为0.0.0.0和0,此时不开启代理(如有需要才设置)
|
|
||||||
*/
|
|
||||||
public const string PROXY_URL = "";
|
|
||||||
|
|
||||||
//=======【上报信息配置】===================================
|
|
||||||
/* 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报
|
|
||||||
*/
|
|
||||||
public const int REPORT_LEVENL = 1;
|
|
||||||
|
|
||||||
//=======【日志级别】===================================
|
|
||||||
/* 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息
|
|
||||||
*/
|
|
||||||
public const int LOG_LEVENL = 3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Domain;
|
using New_College.IRepository;
|
||||||
using New_College.IRepository;
|
|
||||||
using New_College.IRepository.UnitOfWork;
|
using New_College.IRepository.UnitOfWork;
|
||||||
using New_College.Model.Models;
|
using New_College.Model.Models;
|
||||||
using New_College.Model.ViewModels;
|
using New_College.Model.ViewModels;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ using System.Text;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using Org.BouncyCastle.Asn1.Ocsp;
|
using Org.BouncyCastle.Asn1.Ocsp;
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Domain;
|
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
using New_College.Repository;
|
using New_College.Repository;
|
||||||
using NPOI.Util.ArrayExtensions;
|
using NPOI.Util.ArrayExtensions;
|
||||||
|
|
|
||||||
|
|
@ -13,31 +13,16 @@ using YIJIYI.Core.Common.Helper;
|
||||||
using System;
|
using System;
|
||||||
using New_College.Model;
|
using New_College.Model;
|
||||||
using New_College.Common.Helper;
|
using New_College.Common.Helper;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay;
|
|
||||||
using Essensoft.AspNetCore.Payment.Alipay;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Domain;
|
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Request;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using LinqKit;
|
using LinqKit;
|
||||||
using System.Collections.Specialized;
|
using System.IO;
|
||||||
using Org.BouncyCastle.Asn1.Ocsp;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NPOI.SS.Formula.Functions;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V2.Request;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V2;
|
|
||||||
|
|
||||||
namespace New_College.Services
|
namespace New_College.Services
|
||||||
{
|
{
|
||||||
public class V_OrderInfoServices : BaseServices<V_OrderInfo>, IV_OrderInfoServices
|
public class V_OrderInfoServices : BaseServices<V_OrderInfo>, IV_OrderInfoServices
|
||||||
{
|
{
|
||||||
private readonly IWeChatPayClient _client;
|
|
||||||
private readonly IOptions<WeChatPayOptions> _optionsAccessor;
|
|
||||||
private readonly IAlipayClient alipayClient;
|
|
||||||
private readonly IOptions<AlipayOptions> alipayoptions;
|
|
||||||
|
|
||||||
private readonly IBaseRepository<V_OrderInfo> _dal;
|
private readonly IBaseRepository<V_OrderInfo> _dal;
|
||||||
private readonly IUnitOfWork _unitOfWork;
|
private readonly IUnitOfWork _unitOfWork;
|
||||||
private readonly IV_CustomerInfoRepository v_CustomerInfoRepository;
|
private readonly IV_CustomerInfoRepository v_CustomerInfoRepository;
|
||||||
|
|
@ -45,23 +30,16 @@ namespace New_College.Services
|
||||||
private readonly IV_VipCardTypeRepository v_VipCardTypeRepository;
|
private readonly IV_VipCardTypeRepository v_VipCardTypeRepository;
|
||||||
|
|
||||||
private readonly ILogger<V_OrderInfo> logger;
|
private readonly ILogger<V_OrderInfo> logger;
|
||||||
private readonly IWeiChatPayServicesV3 _weiChatPayServicesV3;
|
|
||||||
|
|
||||||
public int Nums = 10;
|
public int Nums = 10;
|
||||||
public V_OrderInfoServices(IWeChatPayClient client, IOptions<WeChatPayOptions> optionsAccessor
|
public V_OrderInfoServices( IBaseRepository<V_OrderInfo> dal
|
||||||
, IAlipayClient IAlipayClient, IOptions<AlipayOptions> alipayopt
|
|
||||||
, IBaseRepository<V_OrderInfo> dal
|
|
||||||
, IUnitOfWork IUnitOfWork
|
, IUnitOfWork IUnitOfWork
|
||||||
, IV_CustomerInfoRepository IV_CustomerInfoRepository
|
, IV_CustomerInfoRepository IV_CustomerInfoRepository
|
||||||
, IV_VipCardInfoRepository IV_VipCardInfoRepository
|
, IV_VipCardInfoRepository IV_VipCardInfoRepository
|
||||||
, IV_VipCardTypeRepository IV_VipCardTypeRepository
|
, IV_VipCardTypeRepository IV_VipCardTypeRepository
|
||||||
, ILogger<V_OrderInfo> loggers, IWeiChatPayServicesV3 weiChatPayServicesV3
|
, ILogger<V_OrderInfo> loggers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_client = client;
|
|
||||||
_optionsAccessor = optionsAccessor;
|
|
||||||
alipayClient = IAlipayClient;
|
|
||||||
alipayoptions = alipayopt;
|
|
||||||
this._dal = dal;
|
this._dal = dal;
|
||||||
_unitOfWork = IUnitOfWork;
|
_unitOfWork = IUnitOfWork;
|
||||||
v_CustomerInfoRepository = IV_CustomerInfoRepository;
|
v_CustomerInfoRepository = IV_CustomerInfoRepository;
|
||||||
|
|
@ -69,7 +47,6 @@ namespace New_College.Services
|
||||||
v_VipCardTypeRepository = IV_VipCardTypeRepository;
|
v_VipCardTypeRepository = IV_VipCardTypeRepository;
|
||||||
logger = loggers;
|
logger = loggers;
|
||||||
base.BaseDal = dal;
|
base.BaseDal = dal;
|
||||||
_weiChatPayServicesV3 = weiChatPayServicesV3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -77,9 +54,15 @@ namespace New_College.Services
|
||||||
/// 扫码支付-Native下单API
|
/// 扫码支付-Native下单API
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="viewModel"></param>
|
/// <param name="viewModel"></param>
|
||||||
public async Task<string> QrCodePay(WeChatPayTransactionsNativeQuery viewModel)
|
public async Task<MemoryStream> QrCodePay(WeChatPayTransactionsNativeQuery viewModel)
|
||||||
{
|
{
|
||||||
return await _weiChatPayServicesV3.QrCodePay(viewModel);
|
viewModel.OutTradeNo = OrderGenerateHelper.GenerateOrderNo("ZY");
|
||||||
|
viewModel.Total = 99 * 100;
|
||||||
|
|
||||||
|
|
||||||
|
return await WeChatPayV3.QrCodePay(viewModel.Total.Value,"demo");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -285,194 +268,8 @@ namespace New_College.Services
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 唤醒微信H5支付
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<MessageModel<string>> WechatPubPay(WeChatPayQuery query)
|
|
||||||
{
|
|
||||||
string out_trade_no = DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
|
||||||
logger.LogInformation(out_trade_no + "唤醒支付");
|
|
||||||
WeChatPayPayRequest viewModel = new WeChatPayPayRequest() { };
|
|
||||||
//viewModel.NotifyUrl = string.Format("{0}/api/front/WeixinPay/PayNotify", PayInfoQuery.ApiUrl);
|
|
||||||
viewModel.NotifyUrl = string.Format("{0}/api/front/HFivePay/WeChartOrderConfirm", PayInfoQuery.ApiUrl);
|
|
||||||
//viewModel.NotifyUrl = string.Format("{0}/api/front/HFivePay/WeChartOrderConfirm?out_trade_no={1}", PayInfoQuery.ApiUrl, out_trade_no);
|
|
||||||
viewModel.SpBillCreateIp = PayInfoQuery.CreateIp;
|
|
||||||
viewModel.OutTradeNo = out_trade_no;
|
|
||||||
viewModel.TotalFee = Convert.ToInt32(query.Money * 100);
|
|
||||||
viewModel.Body = "六纬志愿VIP";
|
|
||||||
viewModel.TradeType = "MWEB";
|
|
||||||
|
|
||||||
var response = await WeChatPay.GetMwebUrl(_client, _optionsAccessor, viewModel);
|
|
||||||
if (response.ReturnCode == "SUCCESS" && response.ReturnMsg == "OK")
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//_unitOfWork.BeginTran();
|
|
||||||
var order = await _dal.Add(new V_OrderInfo
|
|
||||||
{
|
|
||||||
out_trade_no = out_trade_no,
|
|
||||||
PayType = EnumPayType.WeiPay,
|
|
||||||
CardTypeId = query.CardTypeId,
|
|
||||||
Status = EnumOrderType.payment,
|
|
||||||
CustomerId = query.CustomerId,
|
|
||||||
Price = query.Money,
|
|
||||||
PayPrice = query.Money,
|
|
||||||
Name = "六纬志愿VIP开通",
|
|
||||||
CardNo = "0",
|
|
||||||
CardId = 0
|
|
||||||
});
|
|
||||||
if (order > 0)
|
|
||||||
{
|
|
||||||
logger.LogInformation(out_trade_no + "唤醒成功");
|
|
||||||
//_unitOfWork.CommitTran();
|
|
||||||
return new MessageModel<string>()
|
|
||||||
{
|
|
||||||
success = true,
|
|
||||||
msg = "成功",
|
|
||||||
response = string.Format("{0}&redirect_url={1}", response.MwebUrl, string.Format("{0}?out_trade_no={1}", string.Format("{0}/api/front/HFivePay/WeChartOrderConfirm", PayInfoQuery.ApiUrl), out_trade_no))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//_unitOfWork.RollbackTran();
|
|
||||||
return new MessageModel<string>() { success = false, msg = "唤醒微信失败,请重试" };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return new MessageModel<string>() { success = false, msg = "唤醒微信失败,请重试" };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 微信订单查询确认 传用户Id
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<MessageModel<bool>> WeChatPayStatus(IdQuery query)
|
|
||||||
{
|
|
||||||
var orderinfo = await _dal.Query(x => x.CustomerId == query.Id && x.IsDelete == false && x.PayType == EnumPayType.WeiPay);
|
|
||||||
if (orderinfo.Count <= 0)
|
|
||||||
return new MessageModel<bool>() { success = false, msg = "未查询到用户订单" };
|
|
||||||
var result = orderinfo.OrderByDescending(x => x.Id).FirstOrDefault();
|
|
||||||
if (result.Status == EnumOrderType.payoff)
|
|
||||||
{
|
|
||||||
return new MessageModel<bool>() { success = true, msg = "已支付成功" };
|
|
||||||
}
|
|
||||||
var request = new WeChatPayOrderQueryRequest
|
|
||||||
{
|
|
||||||
OutTradeNo = result.out_trade_no
|
|
||||||
};
|
|
||||||
//如果订单状态是
|
|
||||||
var response = await _client.ExecuteAsync(request, _optionsAccessor.Value);
|
|
||||||
if (response.TradeState == "NOTPAY")
|
|
||||||
{
|
|
||||||
return new MessageModel<bool>() { success = false, msg = "您还未支付订单,请重新支付" };
|
|
||||||
}
|
|
||||||
if (response.ReturnCode == "SUCCESS" && response.ReturnMsg == "OK")
|
|
||||||
{
|
|
||||||
var payresult = await PaySuccess(result);
|
|
||||||
if (payresult.success == true)
|
|
||||||
{
|
|
||||||
logger.LogInformation("SUCCESS:" + result.out_trade_no);
|
|
||||||
return new MessageModel<bool>() { success = true, msg = "支付成功" };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new MessageModel<bool>() { success = false, msg = "支付成功,业务处理错误,请联系客服" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new MessageModel<bool>() { success = false, msg = "您还未支付订单,请重新支付或联系客服" };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 支付宝 订单确认
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<MessageModel<bool>> AliPayStatus(IdQuery query)
|
|
||||||
{
|
|
||||||
logger.LogInformation("订单确认(支付宝)");
|
|
||||||
var orderinfo = await _dal.Query(x => x.CustomerId == query.Id && x.IsDelete == false && x.PayType == EnumPayType.AliPay);
|
|
||||||
if (orderinfo.Count <= 0)
|
|
||||||
return new MessageModel<bool>() { success = false, msg = "未查询到用户订单" };
|
|
||||||
var result = orderinfo.OrderByDescending(x => x.CreateTime).FirstOrDefault();
|
|
||||||
if (result.Status == EnumOrderType.payoff)
|
|
||||||
{
|
|
||||||
return new MessageModel<bool>() { success = true, msg = "已支付成功" };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new MessageModel<bool>() { success = false, msg = "未支付,如有疑问请联系客服" };
|
|
||||||
}
|
|
||||||
|
|
||||||
//var model = new AlipayTradeWapPayModel
|
|
||||||
//{
|
|
||||||
// OutTradeNo = query.out_trade_no,
|
|
||||||
//};
|
|
||||||
//var req = new AlipayTradeWapPayRequest();
|
|
||||||
//req.SetBizModel(model);
|
|
||||||
//var response = await alipayClient.PageExecuteAsync(req, alipayoptions.Value);
|
|
||||||
//logger.LogInformation(query.out_trade_no + "返回参数" + response.Body);
|
|
||||||
////response.Body
|
|
||||||
////根绝回调的返回 确认是否支付成功 此处还存在问题----------------------------------
|
|
||||||
////if(response.)
|
|
||||||
//var payresult = await PaySuccess(result);
|
|
||||||
//if (payresult.success == true)
|
|
||||||
//{
|
|
||||||
// logger.LogInformation("SUCCESS(支付宝订单确认成功):" + result.out_trade_no);
|
|
||||||
// return new MessageModel<bool>() { success = true, msg = "支付成功" };
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// return new MessageModel<bool>() { success = false, msg = "支付成功,业务处理错误,请联系客服" };
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// 微信订单回调确认
|
|
||||||
///// </summary>
|
|
||||||
///// <param name="query"></param>
|
|
||||||
///// <returns></returns>
|
|
||||||
//public async Task<MessageModel<string>> WeChartOrderConfirm(XmlQuery query)
|
|
||||||
//{
|
|
||||||
// string xmlstr = "";
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// var response = XmlSerializeHelper.XMLToObject<WeChatPayOrderResponse>(query.xml);
|
|
||||||
// if (response == null)
|
|
||||||
// return new MessageModel<string>() { success = false, msg = "订单确认失败", response = xmlstr };
|
|
||||||
// var result = (await _dal.Query(x => x.out_trade_no == response.out_trade_no && x.PayType == EnumPayType.WeiPay)).FirstOrDefault();
|
|
||||||
// if (result != null && result.Status == EnumOrderType.payoff)
|
|
||||||
// {
|
|
||||||
// xmlstr = "<xml>< return_code >< ![CDATA[SUCCESS]] ></ return_code >< return_msg >< ![CDATA[OK]] ></return_msg </ xml>";
|
|
||||||
// return new MessageModel<string>() { success = true, msg = "成功", response = xmlstr };
|
|
||||||
// }
|
|
||||||
// if (response.result_code == "SUCCESS")
|
|
||||||
// {
|
|
||||||
// //记录流水
|
|
||||||
// var payresult = await PaySuccess(result);
|
|
||||||
// if (payresult.success == true)
|
|
||||||
// {
|
|
||||||
// xmlstr = "<xml>< return_code >< ![CDATA[SUCCESS]] ></ return_code >< return_msg >< ![CDATA[OK]] ></return_msg </ xml>";
|
|
||||||
// return new MessageModel<string>() { success = true, msg = "成功", response = xmlstr };
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// payresult.response = xmlstr;
|
|
||||||
// return payresult;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// return new MessageModel<string>() { success = false, msg = "失败", response = xmlstr };
|
|
||||||
// }
|
|
||||||
// catch (Exception ex)
|
|
||||||
// {
|
|
||||||
// return new MessageModel<string>() { success = false, msg = "失败", response = xmlstr };
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付成功后操作
|
/// 支付成功后操作
|
||||||
|
|
@ -586,85 +383,7 @@ namespace New_College.Services
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 支付宝H5支付
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<MessageModel<AliOrderResult>> AliH5Pay(WeChatPayQuery query)
|
|
||||||
{
|
|
||||||
logger.LogInformation("唤醒支付宝" + query.CustomerId);
|
|
||||||
AliOrderResult aliOrder = new AliOrderResult();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string out_trade_no = query.CustomerId + "1" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
|
||||||
|
|
||||||
AlipayTradeWapPayQuery viewMode = new AlipayTradeWapPayQuery() { };
|
|
||||||
string NotifyUrl = string.Format("{0}/api/front/HFivePay/AliOrderConfirm", PayInfoQuery.ApiUrl);
|
|
||||||
//生成订单
|
|
||||||
//或者失败
|
|
||||||
var model = new AlipayTradeWapPayModel
|
|
||||||
{
|
|
||||||
Body = "六纬志愿VIP",
|
|
||||||
Subject = "六纬志愿VIP",
|
|
||||||
TotalAmount = query.Money.ToString(),
|
|
||||||
OutTradeNo = out_trade_no,
|
|
||||||
ProductCode = "QUICK_WAP_WAY",
|
|
||||||
TimeoutExpress = "90m"
|
|
||||||
};
|
|
||||||
var req = new AlipayTradeWapPayRequest();
|
|
||||||
req.SetBizModel(model);
|
|
||||||
req.SetNotifyUrl(NotifyUrl);
|
|
||||||
req.SetReturnUrl("https://payment.yrtsedu.cn/alipay.html");
|
|
||||||
var response = await alipayClient.PageExecuteAsync(req, alipayoptions.Value);
|
|
||||||
if (response == null)
|
|
||||||
{
|
|
||||||
logger.LogInformation("唤醒失败" + out_trade_no);
|
|
||||||
return new MessageModel<AliOrderResult>() { success = false, msg = "支付宝唤醒失败" };
|
|
||||||
}
|
|
||||||
logger.LogInformation("唤醒成功" + out_trade_no);
|
|
||||||
//_unitOfWork.BeginTran();
|
|
||||||
var order = await _dal.Add(new V_OrderInfo
|
|
||||||
{
|
|
||||||
out_trade_no = out_trade_no,
|
|
||||||
PayType = EnumPayType.AliPay,
|
|
||||||
CardTypeId = query.CardTypeId,
|
|
||||||
Status = EnumOrderType.payment,
|
|
||||||
CustomerId = query.CustomerId,
|
|
||||||
Price = query.Money,
|
|
||||||
PayPrice = query.Money,
|
|
||||||
Name = "六纬志愿VIP开通",
|
|
||||||
CardNo = "0",
|
|
||||||
CardId = 0
|
|
||||||
});
|
|
||||||
if (order > 0)
|
|
||||||
{
|
|
||||||
logger.LogInformation(out_trade_no + "唤醒成功");
|
|
||||||
//_unitOfWork.CommitTran();
|
|
||||||
return new MessageModel<AliOrderResult>()
|
|
||||||
{
|
|
||||||
//?payType='alipay'&&success=true&&customerId=" + query.CustomerId + "&&out_trade_no=" + out_trade_no
|
|
||||||
success = true,
|
|
||||||
msg = "获取成功",
|
|
||||||
response = new AliOrderResult()
|
|
||||||
{
|
|
||||||
Body = response.Body,
|
|
||||||
CustomerId = query.CustomerId,
|
|
||||||
out_trade_no = out_trade_no,
|
|
||||||
PayType = "alipay",
|
|
||||||
Success = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return new MessageModel<AliOrderResult>() { success = false, msg = "订单添加失败" };
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
//_unitOfWork.RollbackTran();
|
|
||||||
logger.LogInformation("唤醒异常" + ex.ToString());
|
|
||||||
return new MessageModel<AliOrderResult>() { success = false, msg = "支付宝唤醒失败" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
|
|
||||||
using New_College.IServices;
|
|
||||||
using New_College.Model.Models;
|
|
||||||
using New_College.Services.BASE;
|
|
||||||
using New_College.IRepository.Base;
|
|
||||||
using New_College.IRepository.UnitOfWork;
|
|
||||||
using New_College.Model.ViewModels;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using New_College.Common;
|
|
||||||
using New_College.IRepository;
|
|
||||||
using System.Linq;
|
|
||||||
using YIJIYI.Core.Common.Helper;
|
|
||||||
using System;
|
|
||||||
using New_College.Model;
|
|
||||||
using New_College.Common.Helper;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay;
|
|
||||||
using Essensoft.AspNetCore.Payment.Alipay;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Domain;
|
|
||||||
using Essensoft.AspNetCore.Payment.Alipay.Request;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using LinqKit;
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using Org.BouncyCastle.Asn1.Ocsp;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using NPOI.SS.Formula.Functions;
|
|
||||||
using Essensoft.AspNetCore.Payment.WeChatPay.V3;
|
|
||||||
|
|
||||||
namespace New_College.Services
|
|
||||||
{
|
|
||||||
public class WeiChatPayServicesV3 : BaseServices<V_OrderInfo>, IWeiChatPayServicesV3
|
|
||||||
{
|
|
||||||
private readonly IWeChatPayClient _client;
|
|
||||||
private readonly IOptions<WeChatPayOptions> _optionsAccessor;
|
|
||||||
private readonly IAlipayClient alipayClient;
|
|
||||||
private readonly IOptions<AlipayOptions> alipayoptions;
|
|
||||||
|
|
||||||
private readonly IBaseRepository<V_OrderInfo> _dal;
|
|
||||||
private readonly IUnitOfWork _unitOfWork;
|
|
||||||
private readonly IV_CustomerInfoRepository v_CustomerInfoRepository;
|
|
||||||
private readonly IV_VipCardInfoRepository v_VipCardInfoRepository;
|
|
||||||
private readonly IV_VipCardTypeRepository v_VipCardTypeRepository;
|
|
||||||
|
|
||||||
private readonly ILogger<V_OrderInfo> logger;
|
|
||||||
|
|
||||||
public int Nums = 10;
|
|
||||||
public WeiChatPayServicesV3(IWeChatPayClient client, IOptions<WeChatPayOptions> optionsAccessor
|
|
||||||
, IAlipayClient IAlipayClient, IOptions<AlipayOptions> alipayopt
|
|
||||||
, IBaseRepository<V_OrderInfo> dal
|
|
||||||
, IUnitOfWork IUnitOfWork
|
|
||||||
, IV_CustomerInfoRepository IV_CustomerInfoRepository
|
|
||||||
, IV_VipCardInfoRepository IV_VipCardInfoRepository
|
|
||||||
, IV_VipCardTypeRepository IV_VipCardTypeRepository
|
|
||||||
, ILogger<V_OrderInfo> loggers
|
|
||||||
)
|
|
||||||
{
|
|
||||||
_client = client;
|
|
||||||
_optionsAccessor = optionsAccessor;
|
|
||||||
alipayClient = IAlipayClient;
|
|
||||||
alipayoptions = alipayopt;
|
|
||||||
this._dal = dal;
|
|
||||||
_unitOfWork = IUnitOfWork;
|
|
||||||
v_CustomerInfoRepository = IV_CustomerInfoRepository;
|
|
||||||
v_VipCardInfoRepository = IV_VipCardInfoRepository;
|
|
||||||
v_VipCardTypeRepository = IV_VipCardTypeRepository;
|
|
||||||
logger = loggers;
|
|
||||||
base.BaseDal = dal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// PC端扫描支付生成URL
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="viewModel"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public async Task<string> QrCodePay(WeChatPayTransactionsNativeQuery viewModel)
|
|
||||||
{
|
|
||||||
return await WeChatPayV3.QrCodePay(_client, _optionsAccessor, viewModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue