本文实例讲述了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?category=5"}
elif content == "222":
return [
["比基尼|美女|", "比基尼|美女|", "http://9smv.com/static/mm/uploads/150411/2-150411115450247.jpg", "http://9smv.com/beauty/list?category=5"],
["长腿|美女|", "长腿|美女|", "http://9smv.com/static/mm/uploads/150506/2-150506111A9648.jpg", "http://9smv.com/beauty/list?category=8"]
]
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程序设计有所帮助。
# Python
# 微信公众平台
# weixin-knife
# 使用Python来开发微信功能
# python微信公众号开发简单流程
# Python微信公众号开发平台
# Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
# 利用Python开发微信支付的注意事项
# Python开发之快速搭建自动回复微信公众号功能
# python tornado微信开发入门代码
# 商户
# 的是
# 就可以
# 进阶
# 操作技巧
# 看着
# 很好
# 相关内容
# 第一个
# 多个
# 客服
# 可以用
# 这个问题
# 感兴趣
# 一遍
# 数据结构
# 给大家
# 其名
# 还算
# 本是
相关文章:
如何零基础开发自助建站系统?完整教程解析
清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?
重庆市网站制作公司,重庆招聘网站哪个好?
在线教育网站制作平台,山西立德教育官网?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?
制作充值网站的软件,做人力招聘为什么要自己交端口钱?
网站设计制作企业有哪些,抖音官网主页怎么设置?
建站之星如何快速解决建站难题?
如何选择CMS系统实现快速建站与SEO优化?
Swift中循环语句中的转移语句 break 和 continue
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
岳西云建站教程与模板下载_一站式快速建站系统操作指南
建站主机与服务器功能差异如何区分?
建站主机助手选型指南:2025年热门推荐与高效部署技巧
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
建站org新手必看:2024最新搭建流程与模板选择技巧
如何构建满足综合性能需求的优质建站方案?
青浦网站制作公司有哪些,苹果官网发货地是哪里?
如何选择网络建站服务器?高效建站必看指南
沈阳个人网站制作公司,哪个网站能考到沈阳事业编招聘的信息?
建站主机核心功能解析:服务器选择与网站搭建流程指南
如何在局域网内绑定自建网站域名?
内网网站制作软件,内网的网站如何发布到外网?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
制作电商网页,电商供应链怎么做?
音乐网站服务器如何优化API响应速度?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
如何快速生成橙子建站落地页链接?
如何在Windows 2008云服务器安全搭建网站?
如何高效配置IIS服务器搭建网站?
建站OpenVZ教程与优化策略:配置指南与性能提升
利用JavaScript实现拖拽改变元素大小
小建面朝正北,A点实际方位是否存在偏差?
C#如何序列化对象为XML XmlSerializer用法
网站制作价目表怎么做,珍爱网婚介费用多少?
Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递
如何通过VPS搭建网站快速盈利?
高防服务器租用指南:配置选择与快速部署攻略
Android使用GridView实现日历的简单功能
网站插件制作软件免费下载,网页视频怎么下到本地插件?
宝塔建站助手安装配置与建站模板使用全流程解析
建站之星CMS建站配置指南:模板选择与SEO优化技巧
宝塔面板如何快速创建新站点?
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
定制建站策划方案_专业建站与网站建设方案一站式指南
seo网站制作优化,网站SEO优化步骤有哪些?
北京营销型网站制作公司,可以用python做一个营销推广网站吗?
*请认真填写需求信息,我们会在24小时内与您取得联系。