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
{
///
/// 接收方帐号(收到的OpenID)
///
public string ToUserName { get; set; }
///
/// 发送方帐号(一个OpenID)
///
public string FromUserName { get; set; }
///
/// 消息创建时间 (整型)
///
public string CreateTime { get; set; }
///
/// 消息类型
///
public string MsgType { get; set; }
///
/// 当前实体的XML字符串
///
public string Xml { get; set; }
}
///
/// wechatCheck 的摘要说明
///
public class wechatCheck : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
String StrXml = getPostStr();//获取请求数据
LogUtil.WriteLog(null, "xmlData:" + StrXml, DateTime.Now.ToString("yyyyMMdd_") + "xmlData");
//StrXml = @"
//
//1602492314
//
//
//
//";
//StrXml = @"
//
//1602494473
//
//
//
//
//";
//加载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 = "您好,欢迎关注!点击跳小程序";
//SendText(model.FromUserName, text);
//SendText(model.FromUserName, "您好,欢迎关注");
StringBuilder sb1 = new StringBuilder();
sb1.Append("您好,欢迎关注高速驿网会员!\n");
sb1.Append("◆休闲驿站,请戳→点击进入\n");
sb1.Append("◆直播平台,请戳→点击进入\n");
sb1.AppendFormat("◆驿网商城,请戳→点击进入\n", "wxb3235f202519f2c3");
sb1.Append("◆如遇任何服务质量问题,请直接在对话框留言,我们会及时处理!");
SendText(model.FromUserName, sb1.ToString());
StringBuilder sb2 = new StringBuilder();
sb2.AppendFormat("◆领取消费优惠券,请戳→点击进入", "wxec57324d9d721cea");
SendText(model.FromUserName, sb2.ToString());
break;
case "unsubscribe":
break;
case "SCAN":
//已经关注的
//SendText(model.FromUserName, "您好,欢迎回来");
StringBuilder sb = new StringBuilder();
sb.Append("您好,欢迎回来!\n");
sb.AppendFormat("◆领取消费优惠券,请戳→点击进入", "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);
}
///
/// 客服发送消息-POST
///
///
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;
}
///
/// 发送文本消息
///
///
///
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;
}
///
/// 验证微信签名
///
/// token
/// 签名
/// 时间戳
/// 随机数
///
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 生成二维码
///
/// 获取Ticket
///
///
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(result); //HttpClientHelper.PostResponse(url, postData);
if (ticket == null || string.IsNullOrEmpty(ticket.ticket))
{
}
return ticket.ticket;
}
///
/// 当AccessToken过期时 调用此方法
///
///
///
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(result); //HttpClientHelper.PostResponse(url, postData);
if (ticket == null || string.IsNullOrEmpty(ticket.ticket))
throw new Exception("Ticket为Null,AccessToken:" + token);
return ticket.ticket;
}
///
/// 根据Ticket获取二维码图片保存在本地
///
/// 二维码场景id
/// 图片存储路径
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("获取二维码图片失败!");
}
}
}
///
/// 根据SceneId 获取 二维码图片流
///
///
///
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
}
}