公众号上运行商家投放会员卡给关注的用户,其中用户在激活会员卡之后其所填写的信息商家是要做保存的。
如果是小程序实现的会员系统或是公众号网页上,那没什么好说的,在页面上随激活按钮的触发你的系统服务器就可以立即操作了。我这里说的是前端页面几乎完全依赖于微信公众平台,微信提供的会员卡功能包括页面实现的会员系统,越简单越好的那种,不然我同事也不会找我,外面弄一个系统或是买一个也要花不少钱,too bad。
不过再怎么想省,服务器都是要有的,但是可以不用购买域名,也不需要备案。
假设你在公众号平台已经编辑好了会员卡的内容,通过了审核获取到了会员卡卡号,虽然这个过程可以在代码里调微信的API实现,但是我接手的时候没有包含前面这些倒也省事。当然了,本质上没什么区别。
因为要用到微信的API,开发者ID和APPSecret都是要的,另外还要在IP白名单加入服务器IP。
文档里面有下面一段内容
步骤三:接收会员信息事件通知
用户填写、提交资料后,会有事件推送给商家,开发者可以在接收到事件通知后调用激活接口,传入会员卡号、初始积分等信息或者调用拉取会员信息接口获取会员信息,进行会员管理。
推送XML数据包示例
<xml>
<ToUserName> < ![CDATA[gh_3fcea188bf78] ]></ToUserName>
<FromUserName>< ![CDATA[obLatjlaNQKb8FqOvt1M1x1lIBFE] ]></FromUserName>
<CreateTime>1432668700</CreateTime>
<MsgType>< ![CDATA[event] ]></MsgType>
<Event>< ![CDATA[submit_membercard_user_info] ]></Event>
<CardId>< ![CDATA[pbLatjtZ7v1BG_ZnTjbW85GYc_E8] ]></CardId>
<UserCardCode>< ![CDATA[018255396048] ]></UserCardCode>
</xml>
上面这个的处理可以看我前一篇《C#-微信公众号开发消息管理》
上面的XML数据包中的信息有卡号CardId和UserCardCode这两个可以给我们用,微信的API中有一个可以获取会员信息的微信开发文档-拉取会员信息
接口调用请求说明
HTTP请求方式: POSTURL:https://api.weixin.qq.com/card/membercard/userinfo/get?access_token=TOKEN
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
POST数据 | 是 | JSON数据 |
access_token | 是 | 调用接口凭证 |
POST数据
{
"card_id": "pbLatjtZ7v1BG_ZnTjbW85GYc_E8",
"code": "916679873278"
}
需要注意的是,微信提供的API POST数据是几乎都是json格式的!请求得到的结果也是json格式!而access_token则是类似get拼接在后面。
看上面就知道要用这个API我们还需要先获取到access_token并加以保存,这里就用到上面说的APPID和APPSecret了。我封装了一个方法专门用来调微信的接口。
/// <summary>
/// 执行POST请求
/// </summary>
/// <param name="method">方法名</param>
/// <param name="requestString">请求传参</param>
/// <returns>json类型格式</returns>
public string WXExcute(string method, string requestString)
{
HttpWebRequest request = WebRequest.Create(method) as HttpWebRequest;
if (method.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
request.ProtocolVersion = HttpVersion.Version10;
}
request.ServicePoint.Expect100Continue = false;
request.ServicePoint.UseNagleAlgorithm = false;
request.Host = "api.weixin.qq.com";
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Accept = "text/plain;charset=utf-8";
request.Timeout = timeOut;
byte[] data = Encoding.GetEncoding("UTF-8").GetBytes(requestString);
using (Stream tempStream = request.GetRequestStream())
{
tempStream.Write(data, 0, data.Length);
}
//响应
HttpWebResponse response;
StreamReader reader;
string jsonStr;
//XmlDataDocument dataDoc = new XmlDataDocument();
try
{
response = request.GetResponse() as HttpWebResponse;
reader = new StreamReader(response.GetResponseStream());
//dataDoc.Load(reader);
jsonStr= reader.ReadToEnd();
}
catch (System.Exception ex)
{
return "{\"data\":[],\"result\":{\"resultCode\":\"500005\",\"resultDesc\":\"" + ex.ToString() + "\"}}";
}
return jsonStr;
}
刷新access_token和检查access_token是否过期,微信开发文档里面建议保存access_token的值并且要检查是否失效,最好是在失效前就更新了,因为这样能保证系统正常运行,微信允许在一定时间内旧的access_token和新的可以同时有效。我这里就有点随意,只在需要access_token时才检查,而不是定时去检测。下面TokenTicketUtil是我自己封装的类,JsonParseBeanData()方法是把json字符串转成Model用的。
/// <summary>
/// 刷新access_token
/// </summary>
/// <returns></returns>
private bool refreshAccessToken(){
string json= new MyHttpRequest().WXExcute(string.Format
("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, secret));
AccessToken access = TokenTicketUtil.JsonParseBeanData<AccessToken>(json);
if (access != null && !string.IsNullOrEmpty(access.access_token))
{
firstGetTokenTime = DateTime.Now;
accessData = access;
return true; //刷新token成功
}
else if(access != null){
string error = access.errcode + "," + access.errmsg;
ViewData["ERROR"] = xml;
}
return false;
}
/// <summary>
/// 检查access_token是否到了可刷新的时候了
/// </summary>
/// <returns></returns>
private bool isTimeToRefreshToken(){
if (firstGetTokenTime != null)
{
DateTime now = DateTime.Now;
TimeSpan ts = now - firstGetTokenTime;
if (accessData != null && !string.IsNullOrEmpty(accessData.access_token))
{
if (ts.Seconds - accessData.expires_in < 300) //小于5分钟刷新
{
return true;
}
}
else {
return true;
}
}
return false;
}
好了,通过上面的方法我们取到了有效的access_token,然后如法炮制,使用WXExcute()方法,把获取会员信息的API链接和必要的参数写进去就可以获取到用户在激活会员卡时填写的信息了。
/// <summary>
/// 获取会员信息。需要会员卡号
/// </summary>
/// <returns></returns>
public JsonResult GetMemberInfo()
{
string memCode = Request["code"];
string memCardId = Request["cardId"];
JsonResult jsonResult = new JsonResult();
jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
if (isTimeToRefreshToken())
{
if(!refreshAccessToken()){
jsonResult.Data = OutPutErrorJson(500);
return jsonResult;
}
}
if (accessData != null)
{
//JavaScriptSerializer serializer = new JavaScriptSerializer();
JObject memCard = new JObject();
memCard["card_id"] = memCardId;
memCard["code"] = memCode ;
string POSTstr = memCard.ToString(); ;
//StringBuilder builder = new StringBuilder();
//builder.AppendFormat("{0}={1}", "POST", POSTstr);
string chgMC = new MyHttpRequest().WXExcute("https://api.weixin.qq.com/card/membercard/userinfo/get?access_token=" + accessData.access_token, POSTstr);
jsonResult.Data = chgMC;
}
else {
jsonResult.Data = OutPutErrorJson(400);
}
return jsonResult;
}
要POST json格式的数据用JObject实现就可以了,简单易读。返回回来的json数据如下:
返回数据
{
"errcode": 0,
"errmsg": "ok",
"openid": "obLatjjwDolFjRRd3doGIdwNqRXw",
"nickname": "Fourier",
"membership_number": "316510891298",
"bonus": 460,
"sex": "MALE",
"user_info": {
"common_field_list": [
{
"name": "USER_FORM_INFO_FLAG_MOBILE",
"value": "15521328888"
},
{
"name": "USER_FORM_INFO_FLAG_NAME",
"value": "微信"
}
],
"custom_field_list": []
},
"user_card_status": "NORMAL"
}
构建相应的Model,然后将上面的数据内容转换为Model方便操作,将需要的信息保存到你的数据库即可。
这一整个过程不需要自己设计前端页面,前端的东西都在微信公众平台上设置就好了。不过有影响的是要启动服务器配置势必会导致自定义菜单和消息自动回复不能使用,也要调接口实现才行,二者不可兼得。