diff --git a/src/0-core/HuanMeng.DotNetCore/Utility/HttpContextExtensions.cs b/src/0-core/HuanMeng.DotNetCore/Utility/HttpContextExtensions.cs new file mode 100644 index 0000000..3904fb9 --- /dev/null +++ b/src/0-core/HuanMeng.DotNetCore/Utility/HttpContextExtensions.cs @@ -0,0 +1,36 @@ +using Microsoft.AspNetCore.Http; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.DotNetCore.Utility +{ + public static class HttpContextExtensions + { + /// + /// 获取IP地址 + /// + /// + /// + public static string GetClientIpAddress(this HttpContext context) + { + // 尝试从X-Forwarded-For头部中获取IP地址 + var forwardedFor = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); + if (!string.IsNullOrEmpty(forwardedFor)) + { + // 处理可能的多个IP地址,通常第一个是客户端的真实IP + var ipAddresses = forwardedFor.Split(','); + if (ipAddresses.Length > 0) + { + return ipAddresses[0].Trim(); + } + } + + // 如果X-Forwarded-For头部不存在,使用RemoteIpAddress + return context.Connection.RemoteIpAddress?.ToString(); + } + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/ChatBLL.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/ChatBLL.cs index c06aea2..a3142ef 100644 --- a/src/0-core/HuanMeng.MiaoYu.Code/Chat/ChatBLL.cs +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/ChatBLL.cs @@ -269,7 +269,7 @@ public class ChatBLL : MiaoYuBase #endregion var claudeChatResponse = await Chat(charact, mess); - if (claudeChatResponse.Message.Contains("香港") || claudeChatResponse.Message.Contains("台湾")|||| claudeChatResponse.Message.Contains("摇头丸")) + if (claudeChatResponse.Message.Contains("香港") || claudeChatResponse.Message.Contains("台湾")|| claudeChatResponse.Message.Contains("摇头丸")) { var chatMessage = new ChatMessageDto() { diff --git a/src/0-core/HuanMeng.MiaoYu.Code/HuanMeng.MiaoYu.Code.csproj b/src/0-core/HuanMeng.MiaoYu.Code/HuanMeng.MiaoYu.Code.csproj index b6fefec..b637826 100644 --- a/src/0-core/HuanMeng.MiaoYu.Code/HuanMeng.MiaoYu.Code.csproj +++ b/src/0-core/HuanMeng.MiaoYu.Code/HuanMeng.MiaoYu.Code.csproj @@ -27,6 +27,10 @@ + + + + diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Order/OrderBLL.cs b/src/0-core/HuanMeng.MiaoYu.Code/Order/OrderBLL.cs index 4f2bcfa..a6a9350 100644 --- a/src/0-core/HuanMeng.MiaoYu.Code/Order/OrderBLL.cs +++ b/src/0-core/HuanMeng.MiaoYu.Code/Order/OrderBLL.cs @@ -47,8 +47,9 @@ namespace HuanMeng.MiaoYu.Code.Order //创建订单 try { + var ip = HttpContextAccessor.HttpContext.GetClientIpAddress(); var payment = PaymentExtend.GetPayment(paymentMethod); - (var orderId, var order) = payment.CreateOrder(product.ProductName, product.Price.ToString(), product); + (var orderId, var order) = await payment.CreateOrder(product.ProductName, product.Price, product, ip); var t = product.ToIntentOrder(paymentMethod, orderId); t.UserId = _UserId; Dao.daoDbMiaoYu.context.Add(t); diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs index ca02b9c..1d41821 100644 --- a/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs +++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/Alipay/AlipayPayment.cs @@ -18,30 +18,31 @@ namespace HuanMeng.MiaoYu.Code.Payment.Alipay /// public class AlipayPayment : IPayment { - public (string orderId, string order) CreateOrder(string productName, string price, params object[] args) + public Task<(string orderId, string order)> CreateOrder(string productName, decimal price, params object[] args) { if (string.IsNullOrEmpty(productName)) { throw new ArgumentNullException($"产品名称不能为空!"); } - if (string.IsNullOrEmpty(price)) + var priceStr = price.ToString(); + if (string.IsNullOrEmpty(priceStr)) { throw new ArgumentNullException($"价格不能为空!"); } var orderId = GenerateTimestampIdWithOffset(); //.SetOptions(GetConfig()); - var response = Factory.Payment.App().Optional("passback_params", "PaymentType%3Dzfb").Pay(productName, orderId, price); + var response = Factory.Payment.App().Optional("passback_params", "PaymentType%3Dzfb").Pay(productName, orderId, priceStr); if (ResponseChecker.Success(response)) { Console.WriteLine("调用成功"); } else { - throw new Exception("创建订单失败!"); + throw new Exception("创建订单失败!" + response.Body); } //.PreCreate("Apple iPhone11 128G", "2234567234890", "5799.00"); var zfbOrderId = response.Body; - return (orderId, zfbOrderId); + return Task.FromResult((orderId, zfbOrderId)); } private string GenerateTimestampIdWithOffset() { diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/Contract/IPayment.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/Contract/IPayment.cs index e98ef59..da8d257 100644 --- a/src/0-core/HuanMeng.MiaoYu.Code/Payment/Contract/IPayment.cs +++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/Contract/IPayment.cs @@ -19,6 +19,6 @@ namespace HuanMeng.MiaoYu.Code.Payment.Contract /// 价格 /// 其它参数 /// - (string orderId,string order) CreateOrder(string productName, string price, params object[] args); + Task<(string orderId, string order)> CreateOrder(string productName, decimal price, params object[] args); } } diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs index 25e0e38..1ae7b71 100644 --- a/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs +++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentExtend.cs @@ -3,17 +3,12 @@ using Alipay.EasySDK.Kernel; using HuanMeng.MiaoYu.Code.Payment.Alipay; using HuanMeng.MiaoYu.Code.Payment.Contract; +using HuanMeng.MiaoYu.Code.Payment.WeChat; using HuanMeng.MiaoYu.Model.Dto.Cache; -using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace HuanMeng.MiaoYu.Code.Payment { @@ -22,17 +17,27 @@ namespace HuanMeng.MiaoYu.Code.Payment /// public static class PaymentExtend { + //public static WXPayTradeApi WxApi { get; set; } /// /// 支付 /// /// /// - public static IHostApplicationBuilder AddAlipay(this IHostApplicationBuilder builder) + public static IHostApplicationBuilder AddPayment(this IHostApplicationBuilder builder) { AddAlipay(builder.Configuration); + + + var weChatConfig = builder.Configuration.GetSection("Payment:WeChatConfig").Get(); + + string key = Path.GetFullPath("DataStorage/1680394019/apiclient_key.pem"); + string key1 = Path.GetFullPath("DataStorage/1680394019/apiclient_cert.pem"); + return builder; } + + /// /// 支付 /// @@ -71,11 +76,12 @@ namespace HuanMeng.MiaoYu.Code.Payment /// public static IPayment GetPayment(string payment) { + if (payment == "zfb") { return new AlipayPayment(); } - return new AlipayPayment(); + return new WeChatPayment(); } /// diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatConfig.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatConfig.cs new file mode 100644 index 0000000..0ba9124 --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatConfig.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Payment.WeChat +{ + /// + /// + /// + public class WeChatConfig + { + /// + /// + /// + public string AppId { get; set; } + /// + /// + /// + public string AppSecret { get; set; } + /// + /// + /// + public string Key { get; set; } + public string MchId { get; set; } + public string NotifyUrl { get; set; } + } + + + +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatPayment.cs b/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatPayment.cs new file mode 100644 index 0000000..6fd05a0 --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Payment/WeChat/WeChatPayment.cs @@ -0,0 +1,34 @@ +using HuanMeng.MiaoYu.Code.Payment.Contract; + +namespace HuanMeng.MiaoYu.Code.Payment.WeChat +{ + /// + /// 微信支付 + /// + public class WeChatPayment() : IPayment + { + + public async Task<(string orderId, string order)> CreateOrder(string productName, decimal price, params object[] args) + { + + // WechatPayHelper.pay_config = new WechatPayConfig() + // { + // app_id = "xxxxxx", + // mch_id = "xxxxxx", + // api_key = "xxxxxx", + + // cert_path = "E:\\xxxxxx\\apiclient_cert.p12", + // cert_password = "xxxxxx" + // }; + var orderId = GenerateTimestampIdWithOffset(); + + return new(orderId, null); + } + private string GenerateTimestampIdWithOffset() + { + var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); // 获取Unix时间戳(毫秒) + var random = new Random().Next(1000, 9999); // 生成四位随机数 + return $"WX0{timestamp}J001Z{random}"; + } + } +} diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_cert.p12 b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_cert.p12 new file mode 100644 index 0000000..fd59988 Binary files /dev/null and b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_cert.p12 differ diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_cert.pem b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_cert.pem new file mode 100644 index 0000000..018fdf2 --- /dev/null +++ b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEKDCCAxCgAwIBAgIUHX+FwqWpjlJeDCLCPYNIqyDVfqYwDQYJKoZIhvcNAQEL +BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT +FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg +Q0EwHhcNMjQwODI1MDQyODU3WhcNMjkwODI0MDQyODU3WjCBgTETMBEGA1UEAwwK +MTY4MDM5NDAxOTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMS0wKwYDVQQL +DCTkuIrmtbflr7Dmoqbnp5HmioDlj5HlsZXmnInpmZDlhazlj7gxCzAJBgNVBAYT +AkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAPP0Cx8Ttk72htBxRfFA05qPnxoW8zVQfWJaeMDIqcizBKglESGOnH5a +4FJUfr3NGtgwM61HZx2LiwI0fDY+1bq7iS2yCLtYDYLvAw9qUS5WIS5MMxqIMCEp +IThxqbRwFIe/G/fsf3unQovA7lr5WeNUVdY8dNx7AMnR6s+myuFZ6xaY43iYgfMh +RVSnH1ohAbWIiWxG+Ucg0KQ7Ipsv4pQ7oOBMXZL5zovHUB5ldKh2vZpp7lcnAQb6 +Le2Y3i1RvJzeVg4Vd3jH/cpVabbkmwLJ3SN5l+Vjm+hZztjUvRo8hYipz/yYrSHt +W9ULBva9fZoabH/hDBBKCinKZtxe01cCAwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsG +A1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2Y2Eu +aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRC +MDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdB +OUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQAA6OtZ +DGfquaAO1nJI0RkEgdJD1nXKlqOyCyIVpswIIqAeGQFMeOhXVVqbGhIh2nFmqQM/ +4YypIlW0aduKIX51jS1HLiN2Yq7ad+TkbsbSFIQp7mOJX4mvmvHk+oovmOOsZspG +maAwlA2w0ParYWMWbXyi3euyNv9ne3M0CYpm+0UzcpqQC5Wq4DQV20+Q+Rcm+/qJ +sng9rkQdAOWQFrbGdaL5tXYhdLQPRo83NEYNZ6/4hNgnf6mvvtt+uKAhYcb0KhH2 +a7cinPdnZEwe+UWuJPdrZDFQbaYJoKs8npzDTYkdIJnj1U/F5+DyPCWuyqNKg/qE +NvMO1RInLugUTK4W +-----END CERTIFICATE----- diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_key.pem b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_key.pem new file mode 100644 index 0000000..6905385 --- /dev/null +++ b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDz9AsfE7ZO9obQ +cUXxQNOaj58aFvM1UH1iWnjAyKnIswSoJREhjpx+WuBSVH69zRrYMDOtR2cdi4sC +NHw2PtW6u4ktsgi7WA2C7wMPalEuViEuTDMaiDAhKSE4cam0cBSHvxv37H97p0KL +wO5a+VnjVFXWPHTcewDJ0erPpsrhWesWmON4mIHzIUVUpx9aIQG1iIlsRvlHINCk +OyKbL+KUO6DgTF2S+c6Lx1AeZXSodr2aae5XJwEG+i3tmN4tUbyc3lYOFXd4x/3K +VWm25JsCyd0jeZflY5voWc7Y1L0aPIWIqc/8mK0h7VvVCwb2vX2aGmx/4QwQSgop +ymbcXtNXAgMBAAECggEBAO27s2LTmOQWhoZ2/IwAerWypH+OQfCAwc+pDugAJMT6 +/9zEUo97JLJV6SkSQnjAehqXzqRcYvZ92DeL4kgSr8HLpAEt8ChxxKkGNts85mPb +d3Zgt6Rxd0W5iTAyRAkc+ETZTm4qwIlGFCmRGDb7rEdHFmcyf0elbr0+ni9CAY/c +Y4xn/GEiFrQwIyo9Wtm5xbJ92zxk2Mkvvp7d+MrVLETc44apnTSL0s8Pr2r9Bghu +SWw1hk2S9FzesIIBPQMDImqMqfy05+nEvIPNijCS1pIqfqQLOuxx0NHsRVezM93i +Zj7gXooBHzwVlG0qs3ZE+unbUy/JA7eeqbRXxE6uoTECgYEA/LcoNanUiqdQxlES +0FknErK77WETObOSO7920xgF/kad8a8z7N7PvJS+CSxxc58ddlABTXYafJFeDksi +plaVlVn0rBiu+3nq8EcDZVQq8ZPIRXpKTbN3GJBUuSr1UZucCYPeDaBntYtKihJI +ZpWXp+gCcrXyuegaufv1Zj5xtOMCgYEA9x+7jXSZTSOG1yxNcaHKX1M1m0HR9n/P +OtCHtH8fkd3PKZHemYQ+b3YRd+ajwoxA6HVHVzdqrMCifcwHo3aQpgg1owbPKDOQ +L8xw9kJ2KfiBfztIe5Ja1cHmtDouKZmutrZnxKjRK2uM8ISoYION1vunm7kw6xlB +i8u7lisQ5f0CgYEA+2aJjbkBQ13nMSJ+AN5vzF4aLa+gnIpTMzTpVF5Vt/swLLoK +gd218vhVhHK9+jOT75rvcMvI1ZsXYkjEk40XCZiPmpSDnpBOc/FxI2BzyBcn6FYb +jOi31avfXMWrfh+7Pov8Xrnv8d47rNc7RzIRyGs55Du019RaoiJQogIEw9kCgYEA +3+o60KNTvJdyOEmGKm4EpncI3ZK4IngQVyRXse51tn+ak/n+Dm/K+seqcE/lFgRr +U7XgXGB0Ie+xy/Yw/aYSzr4li4BB+BUwkn7V4+y4kLMA8z3OIVmtQH4fAjKtXThJ +HHkOcRzd2k/rNouc3UaWILOJXQpiDsOlpnuFjz2aZCkCgYEAz8xngAopZlMSDhnE +TxfnunhHUPVgt3H5Bq6xO/nqbvYZCNHOrK0sf0Lkw4OitgAq/f3Z0gzoyb4axBTI +IP6H0BcEoKQsF/P+LRpjvK4Vvdi96vQbr6hASy01KLnpacXrwaOmfRMJZltoqwtj ++yGTmiLKK822oTfcBkEwiOnmBTw= +-----END PRIVATE KEY----- diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/证书使用说明.txt b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/证书使用说明.txt new file mode 100644 index 0000000..9a0aab1 --- /dev/null +++ b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019/证书使用说明.txt @@ -0,0 +1,18 @@ +欢迎使用微信支付! +附件中的三份文件(证书pkcs12格式、证书pem格式、证书密钥pem格式),为接口中强制要求时需携带的证书文件。 +证书属于敏感信息,请妥善保管不要泄露和被他人复制。 +不同开发语言下的证书格式不同,以下为说明指引: + 证书pkcs12格式(apiclient_cert.p12) + 包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份 + 部分安全性要求较高的API需要使用该证书来确认您的调用身份 + windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户号(如:1900006031) + 证书pem格式(apiclient_cert.pem) + 从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制 + 部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供 + 您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem + 证书密钥pem格式(apiclient_key.pem) + 从apiclient_cert.p12中导出密钥部分的文件,为pem格式 + 部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供 + 您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem +备注说明: + 由于绝大部分操作系统已内置了微信支付服务器证书的根CA证书, 2018年3月6日后, 不再提供CA证书文件(rootca.pem)下载 \ No newline at end of file diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019_20240825_cert.zip b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019_20240825_cert.zip new file mode 100644 index 0000000..528069d Binary files /dev/null and b/src/2-api/HuanMeng.MiaoYu.WebApi/DataStorage/1680394019_20240825_cert.zip differ diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/HuanMeng.MiaoYu.WebApi.csproj b/src/2-api/HuanMeng.MiaoYu.WebApi/HuanMeng.MiaoYu.WebApi.csproj index 4b54bb5..7a8f456 100644 --- a/src/2-api/HuanMeng.MiaoYu.WebApi/HuanMeng.MiaoYu.WebApi.csproj +++ b/src/2-api/HuanMeng.MiaoYu.WebApi/HuanMeng.MiaoYu.WebApi.csproj @@ -31,6 +31,18 @@ + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs b/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs index 277b30b..2e4b6a6 100644 --- a/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs +++ b/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs @@ -132,7 +132,7 @@ builder.Services.AddSwaggerGen(c => }); //配置路由选项,使URL全部小写 //builder.Services.AddRouting(options => options.LowercaseUrls = true); -builder.AddAlipay(); +builder.AddPayment(); //添加多租户 builder.AddMultiTenantMiaoYu(); //添加腾讯云管理