Net8 微信支付分相关接口(创建支付分订单,取消支付分订单,完结支付分订单,退款,支付,及对应的回调,验签(暂时没写))
十年河东,十年河西,莫欺少年穷
学无止境,精益求精
我R它Ma的微信官方及微信官方文档撰写者,LJ腾讯从来不提供C#的SDK
R它奶奶的,算了,贴代码吧,搞了一天,弄了个支付分订单创建,不过这玩意是一通百通
,为了广大Net/NetCore开发者方便调用,奉献上简单的封装
类1:相关DTO
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace swapExternal.WeScore { public class WeScoreCreateOrderResponse { public string appid { get; set; } public string attach { get; set; } public string mchid { get; set; } public object location { get; set; } public string notify_url { get; set; } public string order_id { get; set; } public string out_order_no { get; set; } public string package { get; set; } public object post_discounts { get; set; } public object post_payments { get; set; } public risk_fundDto risk_fund { get; set; } public string service_id { get; set; } public string service_introduction { get; set; } public string state { get; set; } public time_rangeDto time_range { get; set; } } public class risk_fundDto { public int amount { get; set; } public string description { get; set; } public string name { get; set; } } public class time_rangeDto { public string start_time { get; set; } public string end_time { get; set; } public string end_time_remark { get; set; } } /// <summary> /// 微信分确认订单回调对象 /// </summary> public class WechatScoreConfigmOrderBackDto { public string id { get; set; } public string create_time { get; set; } public string resource_type { get; set; } public string event_type { get; set; } public string summary { get; set; } public WxPayResourceModel resource { get; set; } } public class WeScoreAesGcmDecryptDto { public string appid { get; set; } public string mchid { get; set; } public string out_order_no { get; set; } public string service_id { get; set; } public string openid { get; set; } public string state { get; set; }//DOING:服务订单进行中 public string state_description { get; set; } public long? total_amount { get; set; } public string service_introduction { get; set; } public object post_payments { get; set; }//数组 参考:https://pay.weixin.qq.com/doc/v3/merchant/4012587953 public object post_discounts { get; set; }//数组 参考:https://pay.weixin.qq.com/doc/v3/merchant/4012587953 public string risk_fund { get; set; } public string time_range { get; set; } public object location { get; set; } public string attach { get; set; } public string order_id { get; set; } public bool need_collection { get; set; } } public class post_paymentsDto { public string name { get; set; } public string description { get; set; } } /// <summary> /// 微信支付结果回调通知实体 /// </summary> public class WxPayNotifyModel { /// <summary> /// 通知的唯一ID /// </summary> public string id { set; get; } /// <summary> /// 通知创建时间,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示北京时间2015年05月20日13点29分35秒。 /// </summary> public string create_time { set; get; } /// <summary> /// 通知的类型,支付成功通知的类型为TRANSACTION.SUCCESS /// </summary> public string event_type { set; get; } /// <summary> /// 通知的资源数据类型,支付成功通知为encrypt-resource /// </summary> public string resource_type { set; get; } /// <summary> /// 通知资源数据,json格式 /// </summary> public WxPayResourceModel resource { set; get; } /// <summary> /// 回调摘要 /// </summary> public string summary { set; get; } } /// <summary> /// 微信支付回调通知结果resource实体 /// </summary> public class WxPayResourceModel { /// <summary> /// 对开启结果数据进行加密的加密算法,目前只支持AEAD_AES_256_GCM /// </summary> public string algorithm { set; get; } /// <summary> /// Base64编码后的开启/停用结果数据密文 /// </summary> public string ciphertext { set; get; } /// <summary> /// 附加数据 /// </summary> public string associated_data { set; get; } /// <summary> /// 原始回调类型,为transaction /// </summary> public string original_type { set; get; } /// <summary> /// 加密使用的随机串 /// </summary> public string nonce { set; get; } } /// <summary> /// 微信支付回调通知结果解密实体 /// </summary> public class WxPayResourceDecryptModel { /// <summary> /// 直连商户申请的公众号或移动应用appid /// </summary> public string appid { set; get; } /// <summary> /// 商户的商户号,由微信支付生成并下发。 /// </summary> public string mchid { set; get; } /// <summary> /// 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一。特殊规则:最小字符长度为6 /// </summary> public string out_trade_no { set; get; } /// <summary> /// 微信支付系统生成的订单号。 /// </summary> public string transaction_id { set; get; } /// <summary> /// 交易状态,枚举值: /// SUCCESS:支付成功 /// REFUND:转入退款 /// NOTPAY:未支付 /// CLOSED:已关闭 /// REVOKED:已撤销(付款码支付) /// USERPAYING:用户支付中(付款码支付) /// PAYERROR:支付失败(其他原因,如银行返回失败) /// ACCEPT:已接收,等待扣款 /// </summary> public string trade_state { get; set; } /// <summary> /// 交易状态描述 /// </summary> public string trade_state_desc { get; set; } /// <summary> /// 支付者信息 /// </summary> public WxPayerResourceDecryptModel payer { set; get; } } /// <summary> /// 支付用户信息实体 /// </summary> public class WxPayerResourceDecryptModel { /// <summary> /// 用户在直连商户appid下的唯一标识。 /// </summary> public string openid { get; set; } } public class RefundRequestModel { public RefundRequestModel() { this.notify_url = WeScoreHelper.RefundUrl; } public string transaction_id { get; set; } public string out_refund_no { get; set; } public string notify_url { get; set; } } public class RefundRequestAmountModel { public RefundRequestAmountModel() { this.currency = "CNY"; } public long refund { get; set; }//申请退款时传的退款金额,整型,单位为分。 public long total { get; set; }//原支付交易的订单总金额,单位为分,只能为整数。 public string currency { get; set; } } public class RefundnotifyModel { public string id { get; set; } public string create_time { get; set; } public string event_type { get; set; } public string summary { get; set; } public string resource_type { get; set; } public WxPayResourceModel resource { get; set; } } }
类2:相关帮助类接口
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.Json; using System.Threading.Tasks; using WuAnExternal; using System.Text.Json.Serialization; using System.Net.Http; using NPOI.SS.Formula.Functions; using static NPOI.HSSF.Util.HSSFColor; using System.Security.Cryptography.X509Certificates; using swapCommon; using System.Net; using Org.BouncyCastle.Asn1.Ocsp; using SQLitePCL; using NPOI.XWPF.UserModel; using System.Security.Policy; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; namespace swapExternal.WeScore { public class WeScoreHelper { // 微信支付 API 接口地址 /// <summary> /// 创建 、 查询 等 URL /// </summary> public const string ApiUrl = "https://api.mch.weixin.qq.com/v3/payscore/serviceorder"; // 替换为实际的 API 接口地址 // 微信支付凭据 (请替换为你的实际值) public const string MCH_ID = "17xxxxxx3"; // 商户号 public const string API_KEY = "a0axxxxxx4bf"; // API 密钥 public const string APPID = "wxxxxxxb9"; // 公众号/小程序 ID public const string SUB_MCH_ID = ""; // 子商户号 (可选) public const string OPENID = "or3xxxxxxdBg"; // 用户openid public const string SERVICE_ID = "00002xxxxxxxxxxx87"; // 服务ID public const string OUT_ORDER_NO = "123456789001"; // 商户订单号 public const string SerialNo = "7ExxxxxxxA86092"; /// <summary> /// 公钥 /// </summary> public const string publicKey = @"MIIBIjANBgkqhkiG9w0BAQEFAxzDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxD2ZRK6u8z2i0C4gBuU3qmGiJ7qkn rQIDAQAB"; /// <summary> /// 创建支付分订单回调URL /// </summary> public const string WeScoreUrl = "https://xxxx.com/xxxpay/api/V1/WeScoreBack/WetScoreConfimOrderBack"; /// <summary> /// 取消支付分订单 /// </summary> public const string WeScoreCancelUrl = "https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{0}/cancel"; /// <summary> /// 完结支付分订单 /// </summary> public const string WeScoreCompleteUrl = "https://api.mch.weixin.qq.com//v3/payscore/serviceorder/{0}/complete"; public const string RefundUrl = "https://xxxx.com/xxxpay/api/V1/WeScoreBack/RefundBack"; public static async Task<string> PostWithToken(string url, string postData, string token) { using (var httpClient = new HttpClient()) { // 设置请求头 httpClient.DefaultRequestHeaders.Add("Authorization", token); httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");//如果缺少这句代码就会导致下单接口请求失败,报400错误(Bad Request) // 4. 发送 HTTP 请求 var content = new StringContent(postData, Encoding.UTF8, "application/json"); HttpResponseMessage response = await httpClient.PostAsync(url, content); // 5. 处理响应 string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { Console.WriteLine(responseContent); // 解析响应,获取 order_id 等信息 return responseContent; } else { Console.WriteLine(responseContent); // 处理错误信息 return null; } } } public static async Task<string> GetWithToken(string url, string token) { using (var httpClient = new HttpClient()) { // 设置请求头 httpClient.DefaultRequestHeaders.Add("Authorization", token); httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");//如果缺少这句代码就会导致下单接口请求失败,报400错误(Bad Request) // 4. 发送 HTTP 请求 HttpResponseMessage response = await httpClient.GetAsync(url); // 5. 处理响应 string responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { Console.WriteLine(responseContent); // 解析响应,获取 order_id 等信息 return responseContent; } else { Console.WriteLine(responseContent); // 处理错误信息 return null; } } } /// <summary> /// 构造签名串 https://pay.weixin.qq.com/doc/v3/merchant/4012365336 /// </summary> /// <param name="method">HTTP请求方式(全大写)</param> /// <param name="body">API接口请求参数的json字符串</param> /// <param name="uri">API接口的相对路径</param> /// <returns></returns> //protected static string BuildPostAuthAsync(string method, string body, string uri) //{ // var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); // string nonce = Path.GetRandomFileName(); // string message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n"; // string signature = RequestSign(message); // return $"mchid=\"{MCH_ID}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{SerialNo}\",signature=\"{signature}\""; //} /// <summary> /// 生成签名 /// </summary> /// <param name="message"></param> /// <returns></returns> public static string RequestSign(string message) { //加载证书 _apiCertPath API证书物理路径 _certPwd API证书密码(默认是商户号) X509Certificate2 cer = new X509Certificate2(WechatConstants.WxPayCertPath, MCH_ID, X509KeyStorageFlags.Exportable); if (cer != null) { RSA rsa = cer.GetRSAPrivateKey(); //获取私钥 //查看在不同平台上的具体类型 byte[] data = Encoding.UTF8.GetBytes(message); return Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)); } else { return ""; } } /// <summary> /// 构建签名字符串 /// </summary> /// <param name="request"></param> /// <returns></returns> public static async Task<string> BuildAuthAsync(HttpRequestMessage request) { string method = request.Method.ToString(); string body = ""; if (method == "POST" || method == "PUT" || method == "PATCH") { var content = request.Content; body = await content.ReadAsStringAsync(); } string uri = request.RequestUri.PathAndQuery; var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); string nonce = Path.GetRandomFileName(); string message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n"; string signature = RequestSign(message); return $"mchid=\"{MCH_ID}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{SerialNo}\",signature=\"{signature}\""; } /// <summary> /// 最终提交请求时,需对敏感信息加密,如身份证、银行卡号。 /// 加密算法是RSA,使用从接口下载到的公钥进行加密,非后台下载到的私钥。 /// 感谢ISV(https://github.com/ndma-isv)提供示例 /// /// </summary> /// <param name="text">要加密的明文</param> /// <param name="publicKey"> -----BEGIN CERTIFICATE----- 开头的string,转为bytes </param> /// <returns></returns> public static string RSAEncrypt(string text, byte[] publicKey) { using (var x509 = new X509Certificate2(publicKey)) { using (var rsa = (RSACryptoServiceProvider)x509.PublicKey.Key) { var buff = rsa.Encrypt(Encoding.UTF8.GetBytes(text), true); return Convert.ToBase64String(buff); } } } /// <summary> /// 用户确认订单 回调算法 /// </summary> private static string ALGORITHM = "AES/GCM/NoPadding"; private static int TAG_LENGTH_BIT = 128; private static int NONCE_LENGTH_BYTE = 12; private static string AES_KEY = "ChengXiangZhiNeng"; //youkeyhere public static string AesGcmDecrypt(string associatedData, string nonce, string ciphertext) { GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine()); AeadParameters aeadParameters = new AeadParameters( new KeyParameter(Encoding.UTF8.GetBytes(AES_KEY)), 128, Encoding.UTF8.GetBytes(nonce), Encoding.UTF8.GetBytes(associatedData)); gcmBlockCipher.Init(false, aeadParameters); byte[] data = Convert.FromBase64String(ciphertext); byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(data.Length)]; int length = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plaintext, 0); gcmBlockCipher.DoFinal(plaintext, length); return Encoding.UTF8.GetString(plaintext); } } }
类3:相关请求接口
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace swapExternal.WeScore { public class WeScoreOrderHelper { /// <summary> /// 创建微信支付分订单 /// </summary> /// <returns></returns> public static async Task<WeScoreCreateOrderResponse> CreateOrderAsync() { // 1. 构造请求参数 var requestBody = new { appid = WeScoreHelper.APPID, service_id = WeScoreHelper.SERVICE_ID, out_order_no = DateTime.Now.ToString("yyyyMMddHHmmssfff"),//传递参数 openid = WeScoreHelper.OPENID,//传递参数 time_range = new { start_time = DateTime.Now.AddSeconds(10).ToString("yyyyMMddHHmmss"), // //存入数据库 用于验证 start_time_remark = Guid.NewGuid().ToString() //存入数据库 用于验证 }, service_introduction = "充电宝免押", attach = "充电宝免押", // 附加信息 (可选) risk_fund = new { name = "DEPOSIT", amount = 100,//冻结金额 实际支付金额需小于冻结金额 单位 分 传递参数 description = "租借充电宝免押金1元" }, notify_url = WeScoreHelper.WeScoreUrl }; string jsonRequestBody = JsonSerializer.Serialize(requestBody); string signature = await WeScoreHelper.BuildAuthAsync(new HttpRequestMessage() { Method = HttpMethod.Post, RequestUri = new Uri(WeScoreHelper.ApiUrl), Content = new StringContent(jsonRequestBody) }); string token = $"WECHATPAY2-SHA256-RSA2048 {signature}"; var result = await WeScoreHelper.PostWithToken(WeScoreHelper.ApiUrl, jsonRequestBody, token); return Newtonsoft.Json.JsonConvert.DeserializeObject<WeScoreCreateOrderResponse>(result); } /// <summary> /// 查询 /// </summary> /// <param name="out_order_no">用户订单号</param> /// <returns></returns> public static async Task<string> SearchOrderAsync(string out_order_no) { var ApiUrl = string.Format("https://api.mch.weixin.qq.com/v3/payscore/serviceorder?out_order_no={0}&service_id={1}&appid={2}", out_order_no, WeScoreHelper.SERVICE_ID, WeScoreHelper.APPID); //var url = $"/v3/payscore/serviceorder?out_order_no={out_order_no}&service_id={SERVICE_ID}&appid={APPID}"; var signature = await WeScoreHelper.BuildAuthAsync(new HttpRequestMessage() { Method = HttpMethod.Get, RequestUri = new Uri(ApiUrl) }); string token = $"WECHATPAY2-SHA256-RSA2048 {signature}"; var result = await WeScoreHelper.GetWithToken(ApiUrl, token); return result; } /// <summary> /// 取消支付分订单 /// </summary> /// <returns></returns> public static async Task<string> CancelOrderAsync(string out_order_no) { string url = string.Format(WeScoreHelper.WeScoreCancelUrl, out_order_no); // 1. 构造请求参数 var requestBody = new { appid = WeScoreHelper.APPID, service_id = WeScoreHelper.SERVICE_ID, reason = "测试",//传递参数 }; string jsonRequestBody = JsonSerializer.Serialize(requestBody); string signature = await WeScoreHelper.BuildAuthAsync(new HttpRequestMessage() { Method = HttpMethod.Post, RequestUri = new Uri(url), Content = new StringContent(jsonRequestBody) }); string token = $"WECHATPAY2-SHA256-RSA2048 {signature}"; var result = await WeScoreHelper.PostWithToken(url, jsonRequestBody, token); return result; } public static async Task<string> CompleteOrderAsync(string out_order_no) { string url = string.Format(WeScoreHelper.WeScoreCompleteUrl, out_order_no); // 1. 构造请求参数 var requestBody = new { appid = WeScoreHelper.APPID, service_id = WeScoreHelper.SERVICE_ID, post_payments = new List<post_paymentsDto>() { new post_paymentsDto() { name="收费标准",description="不超过99元"} },//传递参数 total_amount=10, time_range = new { end_time = DateTime.Now.AddSeconds(10).ToString("yyyyMMddHHmmss"), // //存入数据库 用于验证 end_time_remark = Guid.NewGuid().ToString() //存入数据库 用于验证 }, }; string jsonRequestBody = JsonSerializer.Serialize(requestBody); string signature = await WeScoreHelper.BuildAuthAsync(new HttpRequestMessage() { Method = HttpMethod.Post, RequestUri = new Uri(url), Content = new StringContent(jsonRequestBody) }); string token = $"WECHATPAY2-SHA256-RSA2048 {signature}"; var result = await WeScoreHelper.PostWithToken(url, jsonRequestBody, token); return result; } public static async Task<string> RefundOrderAsync(RefundRequestModel requestBody) { string jsonRequestBody = JsonSerializer.Serialize(requestBody); string signature = await WeScoreHelper.BuildAuthAsync(new HttpRequestMessage() { Method = HttpMethod.Post, RequestUri = new Uri(WeScoreHelper.RefundUrl), Content = new StringContent(jsonRequestBody) }); string token = $"WECHATPAY2-SHA256-RSA2048 {signature}"; var result = await WeScoreHelper.PostWithToken(WeScoreHelper.RefundUrl, jsonRequestBody, token); return result; } } }
类4:相关回调接口
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using NPOI.XWPF.UserModel; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using Org.BouncyCastle.X509; using swapCommon; using swapCommon.Ext; using swapExternal.WeScore; using swapRepository.Repository.weUser; using swapService.Interface.weUser; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using WuAnExternal; using WuAnExternal.PayDto; namespace xxxpay.Controllers.wechatPay { [AllowAnonymous] public class WeScoreBackController : ControllerBase { private readonly ILogger<WeScoreBackController> logger; public WeScoreBackController( ILogger<WeScoreBackController> logger) { this.logger = logger; } /// <summary> /// 支付分订单创建通知 /// { // "id":"EV-2018022511223320873", // "create_time":"2015-05-20T13:29:35+08:00", // "resource_type":"encrypt-resource", // "event_type":"PAYSCORE.USER_CONFIRM", // "resource" : { // "algorithm":"AEAD_AES_256_GCM", // "ciphertext": "...", // "nonce": "...", // "associated_data": "", // "original_type": "payscore" // }, // "summary": "确认订单" //} /// </summary> /// <returns></returns> [AllowAnonymous] [HttpPost] [Route("WetScoreConfimOrderBack")] public IActionResult WetScoreConfimOrderBack() { var buffer = new MemoryStream(); Request.Body.CopyTo(buffer); var str = Encoding.UTF8.GetString(buffer.GetBuffer()); var wxPayNotifyModel = str.ToObject<WechatScoreConfigmOrderBackDto>(); var resource = wxPayNotifyModel?.resource ?? new WxPayResourceModel(); var decryptStr = WeScoreHelper.AesGcmDecrypt(resource.associated_data, resource.nonce, resource.ciphertext); var decryptModel = decryptStr.ToObject<WeScoreAesGcmDecryptDto>(); if (decryptModel != null) { //验签 //业务逻辑 return Ok(); } return BadRequest(new { code= "FAIL", message ="失败"}); } /// <summary> /// 退款回调 /// </summary> /// <returns></returns> public IActionResult RefundBack() { var buffer = new MemoryStream(); Request.Body.CopyTo(buffer); var str = Encoding.UTF8.GetString(buffer.GetBuffer()); var wxPayNotifyModel = str.ToObject<RefundnotifyModel>(); var resource = wxPayNotifyModel?.resource ?? new WxPayResourceModel(); var decryptStr = WeScoreHelper.AesGcmDecrypt(resource.associated_data, resource.nonce, resource.ciphertext); var decryptModel = decryptStr.ToObject<WxPayResourceDecryptModel>(); if (decryptModel != null) { //验签 //业务逻辑 return Ok(); } return BadRequest(new { code = "FAIL", message = "失败" }); } /// <summary> /// 微信支付回调 /// </summary> /// <returns></returns> public IActionResult WxPayCallback() { var buffer = new MemoryStream(); Request.Body.CopyTo(buffer); var str = Encoding.UTF8.GetString(buffer.GetBuffer()); var wxPayNotifyModel = str.ToObject<WxPayNotifyModel>(); var resource = wxPayNotifyModel?.resource ?? new WxPayResourceModel(); var decryptStr = WeScoreHelper.AesGcmDecrypt(resource.associated_data, resource.nonce, resource.ciphertext); var decryptModel = decryptStr.ToObject<WxPayResourceDecryptModel>(); if (decryptModel != null) { //验签 //业务逻辑 return Ok(); } return BadRequest(new { code = "FAIL", message = "失败" }); } /// <summary> /// 验证数字签名是否有效,公钥验签 https://www.cnblogs.com/dawenyang/p/14458773.html /// </summary> /// <param name="plaintext">明文</param> /// <param name="ciphertext">base64密文</param> /// <param name="publicKey">公钥,纯净格式</param> /// <returns>签名是否一致</returns> public static bool VerifySignByPublicKey(string plaintext, string ciphertext, string publicKey) { // 构建 X509Certificate 证书 X509CertificateParser parser = new X509CertificateParser(); // publicKey 公钥是删除了 -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- \n 三种字符串 X509Certificate certificate = parser.ReadCertificate(Convert.FromBase64String(publicKey)); // 获取公钥 AsymmetricKeyParameter pubKey = certificate.GetPublicKey(); // 明文转 byte 数组 byte[] msgBytes = Encoding.UTF8.GetBytes(plaintext); // 密文转 byte 数组 byte[] sigBytes = Convert.FromBase64String(ciphertext); // 定义签名算法类型 SHA256WithRSA // 从证书描述里面获得 ISigner signer = SignerUtilities.GetSigner(certificate.SigAlgName); // 签名类初始化 // false表示不用于签名(此处是微信私钥签名,公钥验签,所以参数为false) signer.Init(false, pubKey); // 更新签名明文数据类容 signer.BlockUpdate(msgBytes, 0, msgBytes.Length); // 验证密文与原文是否签名一致 return signer.VerifySignature(sigBytes); } } }
类5:控制器请求
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using swapExternal.WeScore; using System.Threading.Tasks; namespace xxxpay.Controllers.wechatPay { [AllowAnonymous] public class WeScoreOrderController : BaseController { [HttpGet("CreateWeScoreOrder")] public async Task<IActionResult> CreateWeScoreOrder() { return Ok(await WeScoreOrderHelper.CreateOrderAsync()); } [HttpGet("SearchOrder")] public async Task<IActionResult> SearchOrder() { return Ok(await WeScoreOrderHelper.SearchOrderAsync("20250726084054665")); } [HttpGet("CancelOrder")] public async Task<IActionResult> CancelOrder() { return Ok(await WeScoreOrderHelper.CancelOrderAsync("20250726084054665")); } [HttpGet("CompleteOrderAsync")] public async Task<IActionResult> CompleteOrderAsync() { return Ok(await WeScoreOrderHelper.CompleteOrderAsync("20250726084054665")); } } }
验签接口,参考:https://www.cnblogs.com/dawenyang/p/14458773.html




结束之前,还是不解气,NN个腿的微信@腾讯

浙公网安备 33010602011771号