2025-03-28 09:49:56 +08:00

826 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
using System.Xml.Linq;
using HZQR.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Coop.Merchant.Handler
{
public class ReceiveModel
{
/// <summary>
/// 接收方帐号收到的OpenID
/// </summary>
public string ToUserName { get; set; }
/// <summary>
/// 发送方帐号一个OpenID
/// </summary>
public string FromUserName { get; set; }
/// <summary>
/// 消息创建时间 (整型)
/// </summary>
public string CreateTime { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public string MsgType { get; set; }
/// <summary>
/// 当前实体的XML字符串
/// </summary>
public string Xml { get; set; }
}
/// <summary>
/// wechatCheck 的摘要说明
/// </summary>
public class wechatCheck : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
String StrXml = getPostStr();//获取请求数据
LogUtil.WriteLog(null, "xmlData" + StrXml, DateTime.Now.ToString("yyyyMMdd_") + "xmlData");
//StrXml = @"<xml><ToUserName><![CDATA[gh_d5e3160d3115]]></ToUserName>
//<FromUserName><![CDATA[ohuAw6HAmNx3-FK4tr-acw_VpNv0]]></FromUserName>
//<CreateTime>1602492314</CreateTime>
//<MsgType><![CDATA[event]]></MsgType>
//<Event><![CDATA[subscribe]]></Event>
//<EventKey><![CDATA[]]></EventKey>
//</xml>";
//StrXml = @"<xml><ToUserName><![CDATA[gh_d5e3160d3115]]></ToUserName>
//<FromUserName><![CDATA[ohuAw6HAmNx3-FK4tr-acw_VpNv0]]></FromUserName>
//<CreateTime>1602494473</CreateTime>
//<MsgType><![CDATA[event]]></MsgType>
//<Event><![CDATA[SCAN]]></Event>
//<EventKey><![CDATA[123]]></EventKey>
//<Ticket><![CDATA[gQHK8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUk14cFZmNndjTUUxMDAwMDAwM0gAAgSsH4RfAwQAAAAA]]></Ticket>
//</xml>";
//加载xml
XmlDocument textXml = new XmlDocument();
textXml.LoadXml(StrXml);
XmlElement xmlElement = textXml.DocumentElement;
//转成model对象
ReceiveModel model = new ReceiveModel()
{
ToUserName = xmlElement.SelectSingleNode("ToUserName").InnerText,
FromUserName = xmlElement.SelectSingleNode("FromUserName").InnerText,
CreateTime = xmlElement.SelectSingleNode("CreateTime").InnerText,
MsgType = xmlElement.SelectSingleNode("MsgType").InnerText
};
if (model.MsgType == "event")
{
switch (xmlElement.SelectSingleNode("Event").InnerText)
{
case "subscribe":
//刚刚关注的
//string text = "您好,欢迎关注!<a href=\"\" data-miniprogram-appid=\"wxec57324d9d721cea\" data-miniprogram-path=\"pages/index/index\">点击跳小程序</a>";
//SendText(model.FromUserName, text);
//SendText(model.FromUserName, "您好,欢迎关注");
StringBuilder sb1 = new StringBuilder();
sb1.Append("您好,欢迎关注高速驿网会员!\n");
sb1.Append("◆休闲驿站,请戳→<a href=\"http://www.shandw.com/m/indexTemp/bannerindex.html?channel=13749&shieldbtn=1&shieldSDW=1&puregame=1&sdw_tl=1\">点击进入</a>\n");
sb1.Append("◆直播平台,请戳→<a href=\"https://hezhibo.migucloud.com/watch/CwDCiiYvunw\">点击进入</a>\n");
sb1.AppendFormat("◆驿网商城,请戳→<a>点击进入</a>\n", "wxb3235f202519f2c3");
sb1.Append("◆如遇任何服务质量问题,请直接在对话框留言,我们会及时处理!");
SendText(model.FromUserName, sb1.ToString());
StringBuilder sb2 = new StringBuilder();
sb2.AppendFormat("◆领取消费优惠券,请戳→<a>点击进入</a>", "wxec57324d9d721cea");
SendText(model.FromUserName, sb2.ToString());
break;
case "unsubscribe":
break;
case "SCAN":
//已经关注的
//SendText(model.FromUserName, "您好,欢迎回来");
StringBuilder sb = new StringBuilder();
sb.Append("您好,欢迎回来!\n");
sb.AppendFormat("◆领取消费优惠券,请戳→<a>点击进入</a>", "wxec57324d9d721cea");
SendText(model.FromUserName, sb.ToString());
break;
case "LOCATION":
break;
case "CLICK":
break;
case "VIEW":
break;
default:
break;
}
}
//验证token
string poststring = string.Empty;
string token = "aabbcc"; //验证token随意填写
if (string.IsNullOrEmpty(token))
{
return;
}
string echostring = HttpContext.Current.Request.QueryString["echostr"];
LogUtil.WriteLog("echostring=" + echostring);
string signature = HttpContext.Current.Request.QueryString["signature"];
string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
string nonce = HttpContext.Current.Request.QueryString["nonce"];
if (checksignature(token, signature, timestamp, nonce))
{
LogUtil.WriteLog("echostring=" + echostring);
if (!string.IsNullOrEmpty(echostring))
{
HttpContext.Current.Response.Write(echostring);
HttpContext.Current.Response.End();
}
}
context.Response.End();
}
public string getPostStr()
{
Int32 intLen = Convert.ToInt32(System.Web.HttpContext.Current.Request.InputStream.Length);
byte[] b = new byte[intLen];
System.Web.HttpContext.Current.Request.InputStream.Read(b, 0, intLen);
return System.Text.Encoding.UTF8.GetString(b);
}
/// <summary>
/// 客服发送消息-POST
/// </summary>
/// <returns></returns>
public string GetKFSend()
{
string accessToken = WeiXinHelper.GetAccessToken("wx0e7ca64a5be0612f", "75e198d9917c224b8ad9f9b8a4735194");
string url = string.Format("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}", accessToken);
return url;
}
/// <summary>
/// 发送文本消息
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public string SendText(string openid, string content)
{
string url = GetKFSend();
JObject data = new JObject();
data.Add("touser", openid);
data.Add("msgtype", "text");
data.Add("text", JObject.FromObject(new
{
content = content
}));
string result = Common.HttpUrlPost(data.ToString(), url);
return result;
}
/// <summary>
/// 验证微信签名
/// </summary>
/// <param name="token">token</param>
/// <param name="signature">签名</param>
/// <param name="timestamp">时间戳</param>
/// <param name="nonce">随机数</param>
/// <returns></returns>
public static bool checksignature(string token, string signature, string timestamp, string nonce)
{
string[] arrtmp = { token, timestamp, nonce };
//字典排序
Array.Sort(arrtmp);
//拼接
string tmpstr = string.Join("", arrtmp);
//sha1验证
tmpstr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpstr, "sha1");
//tmpstr = membership.createuser(tmpstr, "sha1");
LogUtil.WriteLog("tmpstr=" + tmpstr);
tmpstr = tmpstr.ToLower();
LogUtil.WriteLog("tmpstr2=" + tmpstr);
LogUtil.WriteLog("signature=" + signature);
if (tmpstr == signature)
{
return true;
}
else
{
return false;
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
///
/// 微信 需要用到的Url、Json常量
///
public class WeiXinConst
{
#region Value Const
///
/// 微信开发者 AppId
///
public const string AppId = "你的AppId";
///
/// 微信开发者 Secret
///
public const string Secret = "你得Secret";
///
/// V2:支付请求中 用于加密的秘钥Key可用于验证商户的唯一性对应支付场景中的AppKey
///
public static string PaySignKey = "V2.PaySignKey";
///
/// V2:财付通签名key
/// V3:商户支付密钥 Key。登录微信商户后台进入栏目【账户设置】 【密码安全 】【API 安全】 【API 密钥】 ,进入设置 API 密钥。
///
public const string PartnerKey = "PartnerKey";
///
/// 商户号
///
public const string PartnerId = "PartnerId";
///
/// 百度地图Api Ak
///
public const string BaiduAk = "BaiduAk";
///
/// 用于验证 请求 是否来自 微信
///
public const string Token = "Token";
///
/// 证书文件 路径
///
public const string CertPath = @"E:\cert\apiclient_cert.pem";
///
/// 证书文件密码(默认为商户号)
///
public const string CertPwd = "111";
#endregion
#region Url Const
#region AccessTokenUrl
///
/// 公众号 获取Access_Token的Url(需Format 0.AppId 1.Secret)
///
private const string AccessToken_Url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
///
/// 公众号 获取Token的Url
///
public static string WeiXin_AccessTokenUrl { get { return string.Format(AccessToken_Url, AppId, Secret); } }
#endregion
#region Url
///
/// 根据Code 获取用户OpenId Url
///
private const string User_GetOpenIdUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code";
///
/// 根据Code 获取用户OpenId的Url 需要Format 0.code
///
public static string WeiXin_User_OpenIdUrl { get { return string.Format(User_GetOpenIdUrl, AppId, Secret, "{0}"); } }
///
/// 根据OpenId 获取用户基本信息 Url需要Format0.access_token 1.openid
///
public const string WeiXin_User_GetInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN";
#endregion
#region OAuth2授权Url
///
/// OAuth2授权Url需要Format0.AppId 1.Uri 2.state
///
private const string OAuth2_Url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_base&state={2}#wechat_redirect";
///
/// OAuth2授权Url需要Format 0.Uri 1.state
///
public static string WeiXin_User_OAuth2Url { get { return string.Format(OAuth2_Url, AppId, "{0}", "{1}"); } }
#endregion
#region QrCode Url
///
/// 创建获取QrCode的Ticket Url 需要Format 0 access_token
///
public const string WeiXin_Ticket_CreateUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}";
///
/// 获取二维码图片Url,需要Format 0.ticket
///
public const string WeiXin_QrCode_GetUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}";
#endregion
#region Baidu Url
///
/// 经纬度 逆地理编码 Url 需要Format 0.ak 1.经度 2.纬度
///
private const string BaiduGeoCoding_ApiUrl = "http://api.map.baidu.com/geocoder/v2/?ak={0}&location={1},{2}&output=json&pois=0";
///
/// 经纬度 逆地理编码 Url 需要Format 0.经度 1.纬度
///
public static string Baidu_GeoCoding_ApiUrl
{
get
{
return string.Format(BaiduGeoCoding_ApiUrl, BaiduAk, "{0}", "{1}");
}
}
#endregion
#region Menu Url
///
/// 创建菜单Url 需要Format 0.access_token
///
public const string WeiXin_Menu_CreateUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}";
///
/// 获取菜单Url 需要Format 0.access_token
///
public const string WeiXin_Menu_GetUrl = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token={0}";
///
/// 删除菜单Url 需要Format 0.access_token
///
public const string WeiXin_Menu_DeleteUrl = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token={0}";
#endregion
#region Url
///
/// 生成预支付账单Url ,需替换 0 access_token
///
public const string WeiXin_Pay_PrePayUrl = "https://api.weixin.qq.com/pay/genprepay?access_token={0}";
///
/// 订单查询Url 需替换0 access_token
///
public const string WeiXin_Pay_OrderQueryUrl = "https://api.weixin.qq.com/pay/orderquery?access_token={0}";
///
/// 发货通知Url需替换 0 access_token
///
public const string WeiXin_Pay_DeliverNotifyUrl = "https://api.weixin.qq.com/pay/delivernotify?access_token={0}";
#region Url V3接口
///
/// 统一预支付Url
///
public const string WeiXin_Pay_UnifiedPrePayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
///
/// 订单查询Url
///
public const string WeiXin_Pay_UnifiedOrderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
///
/// 退款申请Url
///
public const string WeiXin_Pay_UnifiedOrderRefundUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
#endregion
#endregion
#endregion
#region Json Const
///
/// 获取二维码 所需Ticket 需要上传的Json字符串需要Format 0.scene_id
///
/// scene_id场景值ID 永久二维码时最大值为100000目前参数只支持1--100000
public const string WeiXin_QrCodeTicket_Create_JsonString = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\":{0}}}}";
#endregion
}
public class Ticket
{
public string ticket { get; set; }
public string url { get; set; }
}
public class WeiXinHelper
{
static public string access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
static public string GetAccessToken(string appid, string appsecret)
{
string requestUrl = access_token_url.Replace("APPID", appid).Replace("APPSECRET", appsecret);
WebResponse result = null;
WebRequest req = WebRequest.Create(requestUrl);
result = req.GetResponse();
Stream s = result.GetResponseStream();
XmlDictionaryReader xmlReader = JsonReaderWriterFactory.CreateJsonReader(s, XmlDictionaryReaderQuotas.Max);
xmlReader.Read();
string xml = xmlReader.ReadOuterXml();
s.Close();
s.Dispose();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlElement rootElement = doc.DocumentElement;
string access_token = rootElement.SelectSingleNode("access_token").InnerText.Trim();
return access_token;
}
#region
/// <summary>
/// 获取Ticket
/// </summary>
/// <returns></returns>
public static string CreateTicket(string scene_id)
{
var token = GetAccessToken("wx0e7ca64a5be0612f", "75e198d9917c224b8ad9f9b8a4735194");
string url = string.Format(WeiXinConst.WeiXin_Ticket_CreateUrl, token);
string postData = WeiXinConst.WeiXin_QrCodeTicket_Create_JsonString.Replace("{0}", scene_id);
string result = Common.HttpUrlPost(postData, url); //HttpContext.p HttpClientHelper.PostResponse();
Ticket ticket = JsonConvert.DeserializeObject<Ticket>(result); //HttpClientHelper.PostResponse<Ticket>(url, postData);
if (ticket == null || string.IsNullOrEmpty(ticket.ticket))
{
}
return ticket.ticket;
}
/// <summary>
/// 当AccessToken过期时 调用此方法
/// </summary>
/// <param name="scene_id"></param>
/// <returns></returns>
private static string CreateTicketByNewAccessToken(string scene_id)
{
var token = GetAccessToken("wxcf4dbe1815d5d872", "ba17c52167b086542256f2f6f40ffb1f");
if (string.IsNullOrEmpty(token))
throw new ArgumentNullException("Access_Token");
string url = string.Format(WeiXinConst.WeiXin_Ticket_CreateUrl, token);
string postData = WeiXinConst.WeiXin_QrCodeTicket_Create_JsonString.Replace("{0}", scene_id);
string result = Common.HttpUrlPost(postData, url); //HttpContext.p HttpClientHelper.PostResponse();
Ticket ticket = JsonConvert.DeserializeObject<Ticket>(result); //HttpClientHelper.PostResponse<Ticket>(url, postData);
if (ticket == null || string.IsNullOrEmpty(ticket.ticket))
throw new Exception("Ticket为NullAccessToken:" + token);
return ticket.ticket;
}
/// <summary>
/// 根据Ticket获取二维码图片保存在本地
/// </summary>
/// <param name="scene_id">二维码场景id</param>
/// <param name="imgPath">图片存储路径</param>
public static void SaveQrCodeImage(string scene_id, string imgPath)
{
string Ticket = CreateTicket(scene_id);
if (Ticket == null)
throw new ArgumentNullException("Ticket");
//ticket需 urlEncode
string stUrl = string.Format(WeiXinConst.WeiXin_QrCode_GetUrl, HttpUtility.UrlEncode(Ticket));
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(stUrl);
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse();
string strpath = myResponse.ResponseUri.ToString();
WebClient mywebclient = new WebClient();
try
{
mywebclient.DownloadFile(strpath, imgPath);
}
catch (Exception)
{
throw new Exception("获取二维码图片失败!");
}
}
}
/// <summary>
/// 根据SceneId 获取 二维码图片流
/// </summary>
/// <param name="scene_id"></param>
/// <returns></returns>
public static Stream GetQrCodeImageStream(string scene_id)
{
string Ticket = CreateTicket(scene_id);
if (Ticket == null)
throw new ArgumentNullException("Ticket");
//ticket需 urlEncode
string strUrl = string.Format(WeiXinConst.WeiXin_QrCode_GetUrl, HttpUtility.UrlEncode(Ticket));
try
{
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
Byte[] bytes = client.GetByteArrayAsync(strUrl).Result;
return new MemoryStream(bytes);
}
catch
{
throw new Exception("获取二维码图片失败!");
}
}
#endregion
}
}