您的位置:首页 > 移动开发 > 微信开发

c# 微信授权登录与微信支付

2017-07-21 15:30 337 查看
c# 微信授权登录与微信支付

起因:最近工作上有一个项目需要在公众号页面用到评论然后发起微信支付的操作,之前未接触过微信,

特别记录一下开发过程的一些细节

stemp1:阅读微信公众号开发文档,十分重要

登录授权:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN

微信支付:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4

2个页面讲解参数是比较清晰的,但是细节方面其实很多开发者都查阅了很多其他文献才能继续调试开发

stemp2: 登录授权需要前台获取到code 然后提交给后台,后台拿到code才能提交到微信拿到

//通过code获取openid
private string getToken(string code)
{
string _url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
WebClient wc = new WebClient();
//取得微信返回的openid,access_token数据
String strReturn = wc.DownloadString(_url);
return strReturn;
}

此处直接使用WebClient,是比较笨的方法,后来使用了几个统一的方法

多参数使用     string param = JSONHelper.ObjectToJSON(obj);转化后的串/// <summary>
/// POST方式调用接口
/// </summary>
/// <param name="Url">要请求Url</param>
/// <returns></returns>
public static string RequestUrlByPOST(string Url, string postData = "UTF-8")
{
string strHtml = "";
try
{
HttpWebRequest wr;
System.GC.Collect();
wr = (HttpWebRequest)WebRequest.Create(Url);
wr.Headers.Add("charset:utf-8");
var encoding = Encoding.GetEncoding("utf-8");
byte[] bytes = encoding.GetBytes(postData);
wr.Method = "POST";
wr.Timeout = Int32.MaxValue;
wr.Credentials = CredentialCache.DefaultCredentials;
wr.ContentType = "text/xml";
wr.ContentLength = bytes.Length;
wr.ServicePoint.Expect100Continue = false;
using (Stream requestStream = wr.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse)wr.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK && wr.HaveResponse)
{
if (response != null)
{
using (Stream stream = response.GetResponseStream())//获取返回的字符流格式
{
using (StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8))//解决乱码:设置utf-8字符格式
{
if (sr != null)
{
strHtml = sr.ReadToEnd();
}
}
}
}
}
}
}
catch (WebException ex)
{
throw new Exception(ex.Message);
}
return strHtml;
}

/// <summary>
/// POST方式调用接口
/// </summary>
/// <param name="Url">要请求Url</param>
/// <returns></returns>
public static string RequestUrlByPOSTWithParam(string Url, string Parameter)
{
string strHtml = "";
try
{
HttpWebRequest wr;
System.GC.Collect();
wr = (HttpWebRequest)WebRequest.Create(Url);
//ASCIIEncoding encoding = new ASCIIEncoding();
byte[] bytes = Encoding.UTF8.GetBytes(Parameter);//encoding.GetBytes(codestr);
wr.Method = "POST";
//wr.KeepAlive = false;
//wr.ServicePoint.ConnectionLimit = 300;
//wr.AllowAutoRedirect = true;
//wr.ReadWriteTimeout = 10000;
wr.Timeout = Int32.MaxValue;
wr.Credentials = CredentialCache.DefaultCredentials;
wr.ContentType = "application/json";
wr.Accept = "application/xml";
wr.Headers.Add("X-Auth-Token", HttpUtility.UrlEncode("OpenStack"));
wr.ContentLength = bytes.Length;
wr.ServicePoint.Expect100Continue = false;
using (Stream requestStream = wr.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
using (HttpWebResponse response = (HttpWebResponse)wr.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK && wr.HaveResponse)
{
if (response != null)
{
using (Stream stream = response.GetResponseStream())//获取返回的字符流格式
{
using (StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8))//解决乱码:设置utf-8字符格式
{
if (sr != null)
{
strHtml = sr.ReadToEnd();
}
}
}
}
}
}
}
catch (WebException ex)
{
throw new Exception(ex.Message);
}
return strHtml;
}


使用到的方法,刚开始写的时候不注意统一,后来需要时间优化

基础方法与获取微信相关信息并返回

#region 获取AccessToken
public static string GetAccessToken()
{
string tokenUrl = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type={0}&appid={1}&secret={2}", grant_type, appid, secret);
var wc = new WebClient();
var strReturn = wc.DownloadString(tokenUrl);
return strReturn;
}
#endregion
#region 获取Jsapi_Ticket
public static string GetWeiXinJsapi_Ticket(string accessToken)
{
string tokenUrl = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type={1}", accessToken, type);
var wc = new WebClient();
var strReturn = wc.DownloadString(tokenUrl); //取得微信返回的json数据
return strReturn;
}
#endregion
#region 基础字符
private static string[] strs = new string[]
{
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
};
#endregion
#region 创建随机字符串
public static string CreatenNonce_str()
{
Random r = new Random();
var sb = new StringBuilder();
var length = strs.Length;
for (int i = 0; i < 15; i++)
{
sb.Append(strs[r.Next(length - 1)]);
}
return sb.ToString();
}
#endregion
#region  创建时间戳
public static long CreatenTimestamp()
{
return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
#endregion
#region 签名算法
/// <summary>
/// 签名算法
///本代码来自开源微信SDK项目:https://github.com/night-king/weixinSDK
/// </summary>
/// <param name="jsapi_ticket">jsapi_ticket</param>
/// <param name="noncestr">随机字符串(必须与wx.config中的nonceStr相同)</param>
/// <param name="timestamp">时间戳(必须与wx.config中的timestamp相同)</param>
/// <param name="url">当前网页的URL,不包含#及其后面部分(必须是调用JS接口页面的完整URL)</param>
/// <returns></returns>
public static string GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url, out string string1)
{
var string1Builder = new StringBuilder();
string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
.Append("noncestr=").Append(noncestr).Append("&")
.Append("timestamp=").Append(timestamp).Append("&")
.Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
string1 = string1Builder.ToString();
return FormsAuthentication.HashPasswordForStoringInConfigFile(string1, "SHA1");
//return Util.Sha1(string1);
}
#endregion
//GET api/GetInfoMation
/// <summary>
///初始化的数据调用微信接口返回参数
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[ActionName("GetInfoMation")]
[HttpGet]
public IHttpActionResult GetInfoMation(string ID, string url = "")
{
try
{
//生成tokcen
string tocken = GetAccessToken();
JObject TokenJO = (JObject)JsonConvert.DeserializeObject(tocken);
//验证签名
string Jsapi_Ticket = GetWeiXinJsapi_Ticket(TokenJO["access_token"].ToString());
JObject Jsapi_TicketJo = (JObject)JsonConvert.DeserializeObject(Jsapi_Ticket);
#region
string rtn = "";
string jsapi_ticket = Jsapi_TicketJo["ticket"].ToString();
string noncestr = CreatenNonce_str();
long timestamp = CreatenTimestamp();
string outstring = "";
string JS_SDK_Result = GetSignature(jsapi_ticket, noncestr, timestamp, url, out outstring);
//拼接json串返回前台
rtn = "{\"appid\":\"" + appid + "\",\"jsapi_ticket\":\"" + jsapi_ticket + "\",\"noncestr\":\"" + noncestr + "\",\"timestamp\":\"" + timestamp + "\",\"outstring\":\"" + outstring + "\",\"signature\":\"" + JS_SDK_Result.ToLower() + "\"}";
#endregion
return Json(Success(rtn));
}
catch (CustomException ce)
{
return Json(getException(ce.Message));
}
catch (Exception ex)
{
return Json(getException(ex));
}
}


获取公众号下的微信会员信息

//GET api/Login/getCweixinInfo
/// <summary>
///获取网页授权并返回微信账号信息同时更新微信信息
/// </summary>
/// <param name="code">code</param>
/// <param name="UserId">对象ID</param>
/// <param name="Type">对象类型</param>
/// <returns></returns>
[AllowAnonymous]
[ActionName("getCweixinInformation")]
[HttpGet]
public IHttpActionResult getCweixinInformation(string code, string UserId, string Type = "1")
{
try
{
int uid = UserId.ToIntForPage();
string strReturn = "";
DateTime dtnow = DateTime.Now;
string openId = "";
string accessToken = "";
var log = dbo.mf_Weixinlog.OrderByDescending(c => c.ID).FirstOrDefault();
var user = dbo.mf_User.Where(c => c.UserId == uid).FirstOrDefault();
//if (uid > 0 && log != null && dtnow < log.PastTime && !string.IsNullOrEmpty(user.openid) && user.openid != "oW9b7t-XCA5B2VblXh9rt5bYBo9s")
//{
//    openId = user.openid;
//    accessToken = log.Token;
//}
//else
{
strReturn = getToken(code);
//转换成Json
Newtonsoft.Json.Linq.JObject TickectJO = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(strReturn);
openId = TickectJO["openid"].ToString();
accessToken = TickectJO["access_token"].ToString();
Weixinlog model = new Weixinlog
{
Itime = DateTime.Now,
Token = accessToken,
Openid = openId,
Seconds = 7200,
State = 0,
PastTime = DateTime.Now.AddSeconds(7080),
Ticket = "",
UserId = uid
};
dbo.mf_Weixinlog.Add(model);
}
string rnt = "";

strReturn = getWeiXinInfo(accessToken, openId);

rnt = strReturn;

#region 更新微信信息操作
//更新表 User
Newtonsoft.Json.Linq.JObject Cweinxin = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(strReturn);
int id = UserId.ToIntForPage();
if (id > 0)
{
if (Type == "1")
{
User usermodel = dbo.User.Where(c => c.UserId == id).FirstOrDefault();
if (usermodel != null)
{
usermodel.updateTime = DateTime.Now;
usermodel.openid = Cweinxin["openid"].ToString();
usermodel.NickName = Cweinxin["nickname"].ToString();
usermodel.Headimgurl = Cweinxin["headimgurl"].ToString();
usermodel.City = Cweinxin["city"].ToString();
usermodel.Province = Cweinxin["province"].ToString();
usermodel.Sex = Cweinxin["sex"].ToString();
dbo.Entry(usermodel).State = System.Data.Entity.EntityState.Modified;
//dbo.SaveChanges();
}
}
#endregion

int r = dbo.SaveChanges();
return Json(rnt);
}
catch (CustomException ce)
{
return Json(getException(ce.Message));
}
catch (Exception ex)
{
return Json(getException(ex));
}
}


到此 微信基本信息已获取完毕,需要获取更详细的信息则需要更多的权限

当时做这个的时候,由于开发项目是前后端分离,测试的时候各种疑难杂症,前后台的问题交叉在一起,终究还是获益良多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  微信 支付