using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using NPOI.SS.Formula.Functions; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using OSS.Clients.Pay.Wechat; using OSS.Clients.Pay.Wechat.Basic; using StackExchange.Redis; namespace New_College.Common.Helper { public static class WeChatPayV3 { /// /// 扫码支付-Native下单API /// /// public static async Task QrCodePay(string outorderNo, decimal Price, string title) { ////使用 Native 支付,输出二维码并展示 MemoryStream fileStream = null;//输出图片的URL var price = (int)(Price * 100); var name = title + "-扫码支付"; WechatPayHelper.pay_config = new WechatPayConfig() { app_id = WeixinConfig.Appid, mch_id = WeixinConfig.MCHID, api_key = WeixinConfig.Secret, api_v3_key = WeixinConfig.KEY, cert_path = WeixinConfig.PrivateKey, cert_password = WeixinConfig.MCHID }; var nResp = await new WechatNativePayReq() { description = name, out_trade_no = outorderNo, notify_url = WeixinConfig.NotifyUrl, amount = new WechatPayAmount() { currency = "CNY", total = price } } // .SetContextConfig(new WechatPayConfig(){}) // 可以设置当前上下文的配置信息,设置后本次请求将使用此配置,方便多应用的用户 //.AddOptionalBodyPara("attach","附加数据") // 添加可选参数 .SendAsync();// //系统创建订单逻辑 //var result = await basePayApis.NativeAsync(requestData); ////进行安全签名验证 if (!string.IsNullOrEmpty(nResp.code_url)) { fileStream = QrCodeHelper.GerQrCodeStream(nResp.code_url); } else { fileStream = QrCodeHelper.GetTextImageStream("Native Pay 未能通过签名验证,无法显示二维码"); } return fileStream; } /** * * 统一下单 * @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; } /// /// 生成随机数 /// /// public static string GenerateNonceStr() { return Guid.NewGuid().ToString().Replace("-", ""); } /// /// POST请求 /// /// /// /// application/xml、application/json、application/text、application/x-www-form-urlencoded /// /// /// public static string HttpPost(string postData, string url, string contentType = null, int timeOut = 30, Dictionary 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; } } } } /// /// /// 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; } }