本文实例讲述了Python开发微信公众平台的方法。分享给大家供大家参考,具体如下:
这两天将之前基于微信公众平台的代码重构了下,基础功能以库的方式提供,提供了demo使用的是django,看着之前为赶进度写的代码真的惨不忍睹,所以weixin-knife产生了,正如其名,提供的是必要的功能,而不是完整的应用。weixin-knife可以很方便的处理关注,取关注事件,处理文本消息,回复用户信息,jssdk处理,oauth认证,以及微信支付。
github地址:https://github.com/Skycrab/weixin-knife。
首先看看怎么用
from .weixin import handler as HD @HD.subscribe def subscribe(xml): return "welcome to brain" @HD.unsubscribe def subscribe(xml): print "leave" return "leave brain"
上面处理了关注和取关事件,通过装饰器处理的还算透明。
处理文本消息,回复图文消息如下:
@HD.text def text(xml): content = xml.Content if content == "111": return {"Title":"美女", "Description":"比基尼美女", "PicUrl":"http://9smv.com/static/mm/uploads/150411/2-150411115450247.jpg", "Url":"http://9smv.com/beauty/list"} elif content == "222": return [ ["比基尼美女", "比基尼美女", "http://9smv.com/static/mm/uploads/150411/2-150411115450247.jpg", "http://9smv.com/beauty/list"], ["长腿美女", "长腿美女", "http://9smv.com/static/mm/uploads/150506/2-150506111A9648.jpg", "http://9smv.com/beauty/list"] ] elif content == "push": Helper.send_text_message(xml.FromUserName, "推送消息测试") return "push ok" return "hello world"
如何文本是111或222,我们回复图文消息,如何使push,我们使用客服接口推送消息,其它返回“hello world"
一般我们会使用oauth网页授权获取用户的openid,如果是多个链接都需要通过oauth处理,代码会很难看,通过装饰器可以很好的处理这个问题。
def sns_userinfo_callback(callback=None): """网页授权获取用户信息装饰器 callback(openid, userinfo): return user """ def wrap(func): @wraps(func) def inner(*args, **kwargs): request = args[0] #django第一个参数request openid = request.COOKIES.get('openid') userinfo = None if not openid: code = request.GET.get("code") if not code: current = "http://"+ request.get_host() + request.get_full_path() return redirect(WeixinHelper.oauth2(current)) else: data = json.loads(WeixinHelper.getAccessTokenByCode(code)) access_token, openid, refresh_token = data["access_token"], data["openid"], data["refresh_token"] #WeixinHelper.refreshAccessToken(refresh_token) userinfo = json.loads(WeixinHelper.getSnsapiUserInfo(access_token, openid)) else: ok, openid = Helper.check_cookie(openid) if not ok: return redirect("/") request.openid = openid if callable(callback): request.user = callback(openid, userinfo) response = func(request) return response return inner return wrap sns_userinfo = sns_userinfo_callback()
在所有需要用户openid的函数前使用sns_userinfo装饰器就可以了,callback函数接收openid,userinfo,返回用户实例,这样就可以使用request.user获取当前用户
@sns_userinfo def oauth(request): """网页授权获取用户信息""" resp = HttpResponse(request.openid) resp.set_cookie("openid", Helper.sign_cookie(request.openid)) return resp
使用oauth需要保存cookie,不然每次用户请求都需要授权,需要走一遍完整的oauth流程,拖慢整体响应。
weixin-knife提供了微信支付支持,稍微修改我之前移植的官方PHP版本,https://github.com/Skycrab/wzhifuSDK
@sns_userinfo def pay(request): response = render_to_response("pay.html") response.set_cookie("openid", Helper.sign_cookie(request.openid)) return response @sns_userinfo @catch def paydetail(request): """获取支付信息""" openid = request.openid money = request.POST.get("money") or "0.01" money = int(float(money)*100) jsApi = JsApi_pub() unifiedOrder = UnifiedOrder_pub() unifiedOrder.setParameter("openid",openid) #商品描述 unifiedOrder.setParameter("body","充值测试") #商品描述 timeStamp = time.time() out_trade_no = "{0}{1}".format(WxPayConf_pub.APPID, int(timeStamp*100)) unifiedOrder.setParameter("out_trade_no", out_trade_no) #商户订单号 unifiedOrder.setParameter("total_fee", str(money)) #总金额 unifiedOrder.setParameter("notify_url", WxPayConf_pub.NOTIFY_URL) #通知地址 unifiedOrder.setParameter("trade_type", "JSAPI") #交易类型 unifiedOrder.setParameter("attach", "6666") #附件数据,可分辨不同商家(string(127)) try: prepay_id = unifiedOrder.getPrepayId() jsApi.setPrepayId(prepay_id) jsApiParameters = jsApi.getParameters() except Exception as e: print(e) else: print jsApiParameters return HttpResponse(jsApiParameters) FAIL, SUCCESS = "FAIL", "SUCCESS" @catch def payback(request): """支付回调""" xml = request.raw_post_data #使用通用通知接口 notify = Notify_pub() notify.saveData(xml) print xml #验证签名,并回应微信。 #对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败, #微信会通过一定的策略(如30分钟共8次)定期重新发起通知, #尽可能提高通知的成功率,但微信不保证通知最终能成功 if not notify.checkSign(): notify.setReturnParameter("return_code", FAIL) #返回状态码 notify.setReturnParameter("return_msg", "签名失败") #返回信息 else: result = notify.getData() if result["return_code"] == FAIL: notify.setReturnParameter("return_code", FAIL) notify.setReturnParameter("return_msg", "通信错误") elif result["result_code"] == FAIL: notify.setReturnParameter("return_code", FAIL) notify.setReturnParameter("return_msg", result["err_code_des"]) else: notify.setReturnParameter("return_code", SUCCESS) out_trade_no = result["out_trade_no"] #商户系统的订单号,与请求一致。 ###检查订单号是否已存在,以及业务代码 return HttpResponse(notify.returnXml())
pay.html就是使用WeixinJSBridge.invode调用
$.post("/paydetail",{ money: $momey },function(data){ if(data){ var jsonobj = eval('('+data+')'); WeixinJSBridge.invoke('getBrandWCPayRequest', { "appId" : jsonobj.appId, //公众号名称,由商户传入 "timeStamp" : jsonobj.timeStamp, //时间戳 "nonceStr" : jsonobj.nonceStr, //随机串 "package" : jsonobj.package,//扩展包 "signType" : "MD5", //微信签名方式:1.sha1 "paySign" : jsonobj.paySign //微信签名 }); } } );
由于access_token, jsapi_ticket需要缓存,而缓存方式又依赖于具体环境,所以提供了一个Helper类,使用了django 的cache缓存。
class Helper(object): """微信具体逻辑帮组类""" @class_property def access_token(cls): key = "ACCESS_TOKEN" token = cache.get(key) if not token: data = json.loads(WeixinHelper.getAccessToken()) token, expire = data["access_token"], data["expires_in"] cache.set(key, token, expire-300) return token @class_property def jsapi_ticket(cls): key = "JSAPI_TICKET" ticket = cache.get(key) if not ticket: data = json.loads(WeixinHelper.getJsapiTicket(cls.access_token)) ticket, expire = data["ticket"], data["expires_in"] cache.set(key, ticket, expire-300) return ticket
class_property提供了类级别的property,当然实例也是可以用的。
class class_property(object): """ A property can decorator class or instance class Foo(object): @class_property def foo(cls): return 42 print(Foo.foo) print(Foo().foo) """ def __init__(self, func, name=None, doc=None): self.__name__ = name or func.__name__ self.__module__ = func.__module__ self.__doc__ = doc or func.__doc__ self.func = func def __get__(self, obj, type=None): value = self.func(type) return value
使用weixin-knife助力公众平台开发,你完全可以稍加修改用于flask等其它web框架。
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python字符串操作技巧汇总》、《Python编码操作技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》及《Python入门与进阶经典教程》。
希望本文所述对大家Python程序设计有所帮助。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]