现在很多APP都有提现功能,而提现大部分都是用微信提现,微信提现有两种,一是红包,二是企业付款,在这里结合一下开发,做一些微信服务号发送红包功能的介绍。
例如当前比较火的直播APP映客的提现就是通过微信公众号的红包功能实现的。它的流程是在APP内绑定微信号,然后需要绑定的微信号关注特定的公众号,关注之后就可以在APP内或者公众号提现,公众号通过红包的形式实现提现功能。这一切的前提是要关注特定
的公众号。由于微信红包是通过公众号发送的,这个时候就需要知道绑定的微信相对于这个公众号的openid,通过关注可以获得openid。

APP内部绑定微信号

1 客户端通过微信AUTH获得微信的code发送给服务器
2 服务器通过code获取用户access_token和openid,参照https://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html
3 通过access_token和openid获得unionid,并记录该APP用户的unionid,以方便在关注公众号的时候获取对应的openid, 参照http://mp.weixin.qq.com/wiki/1/8a5ce6257f1d3b2afb20f83e72b72ce9.html

公众号配置

这个公众号是微信开放平台https://open.weixin.qq.com/里面所绑定的公众号,平台里面的移动应用应该包括了你需要实现提现功能的APP
1 公众号开启开发模式,如何开启请自行搜索(开启开发模式之后,原来公众号设置的自动回复,菜单等功能全部会失效,需要开发者自己实现)
2 填写开发模式的服务器配置 参照http://mp.weixin.qq.com/wiki/8/f9a0b8382e0b77d87b3bcc1ce6fbc104.html
我选择的是明文模式,配置之后,要确定这个服务器url能够正常访问。
3 验证服务器地址的有效性
我这边采用的是twisted框架用python实现的web开发,由于采用的是明文模式,验证代码只原样返回了'echostr'
4 获取微信公众号的access_token,参照https://mp.weixin.qq.com/wiki/11/0e4b294685f817b95cbed85ba5e82b8f.html,并使用redis做缓存处理,
5 依据接口文档实现业务逻辑
由于公众号的菜单功能已经失效,需要重新配置菜单,我是参照https://mp.weixin.qq.com/debug/cgi-bin/apiinfo?t=index&type=自定义菜单&form=自定义菜单创建接口%20/menu/create 创建菜单,其中的access_token通过公众号的APPID和APPSECRET获得,也>可以根据http://mp.weixin.qq.com/wiki/10/0234e39a2025342c17a7d23595c6b40a.html使用代码实现。
6 关注/取消关注事件,参照https://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html
在发生这类事件的时候,我们配置的服务器url会收到调用,参数如下
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
</xml>
'EVENT'是subscribe和unsubscribe分表表示关注和取消关注,'FromUserName'为微信用户的openid,我们可以根据公众号的access_token和这个openid获取用户的信息,参照https://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html,这个里

面包含了unionid,这个unionid和通过APP内部绑定时获得unionid相同的时候就可以把APP用户和微信公众号的openid对应起来,之后我们就可以在APP申请提现,公众号发红包实现提现。

这部分的部分代码如下

class EventNotify(GreenResource):isLeaf = Truedef green_render_GET(self, request):return arg_named(request, 'echostr')def green_render_POST(self, request):data = request.content.read()root = ElementTree.fromstring(data)response = {child.tag: child.text for child in root.getchildren()}ret_xml = ''event_type = response.get('Event')openid = response.get('FromUserName')if event_type == 'subscribe':wx_user = WXClient.get_fuwuhao_user_info(opened)  #获取用户信息if not wx_user or wx_user.get('errcode'):logging.info(wx_user)returnunionid = wx_user.get('unionid')nickname = wx_user.get('nickname')fwh = PWWeixinFuwuhao.find_or_new(openid)fwh.unionid = unionidfwh.nickname = nicknamefwh.save()bind_query = WeixinBind.query(master=True, fetchone=False, unionid=unionid) #使用psql获取app用户bind_all = [WeixinBind(**each) for each in bind_query]for bind_one in bind_all:bind_one.openid = openidbind_one.save()ret_fmt = '''<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content><FuncFlag>0</FuncFlag></xml>'''ret_parm = (response.get('FromUserName'),response.get('ToUserName'),int(time.time()),config.WX_FWH_AUTO_MSG,)ret_xml  = ret_fmt % ret_parmelif event_type == 'unsubscribe':result = WeixinFuwuhao.delete(openid=openid)if not result:logging.info('fuwuhao unsubscribe is not exist %s' % (openid, ))elif response.get('MsgId'):ret_fmt = '''<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content><FuncFlag>0</FuncFlag></xml>'''ret_parm = (response.get('FromUserName'),response.get('ToUserName'),int(time.time()),config.WX_FWH_AUTO_MSG_2,)ret_xml  = ret_fmt % ret_parmreturn ret_xml

公众号发送红包

1 发送红包,微信红包针对所有用户、单个用户都有发送频率的限制,金额也有限制,如果提现金额大于红包最大金额,需要分批发送。参照https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5
2 由于红包需要微信用户去领取,所以APP服务器需要不断查询红包状态,查询参照https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_7&index=6

每个红包是 SENDING:发放中 SENT:已发放待领取 FAILED:发放失败 RECEIVED:已领取 REFUND:已退款 中的任何一种状态,只有 为FAILED RECEIVED REFUND状态的时候表示这个红包的生命周期已经结束

部分代码如下

class WeixinWithdrawOrder(object):def __init__(self, withhdraw_id, openid, mch_billno, total_amount):self.wid = withhdraw_idself.pw_tid = 0self.nonce_str = hashlib.md5('%s-%s' % (self.wid, time.time())).hexdigest()self.mch_id = config.WX_FWH_MCH_IDself.mch_billno = mch_billnoself.wxappid = config.WX_FWH_APPIDself.send_name = config.WX_WITHDRAW_SEND_NAMEself.re_openid = openidself.total_amount = 100 if config.ENV_TEST else total_amountself.total_num = 1self.act_name = config.WX_WITHDRAW_ACT_NAMEself.wishing = config.WX_WITHDRAW_WISHINGself.client_ip = config.WX_PAY_IP_ADDRself.remark = config.WX_WITHDRAW_REMARK@classmethoddef sign(cls, data):weixin_params = []for key, value in data.iteritems():if key not in ('wid', 'sign', 'pw_tid', ):weixin_params.append([str(key), str(value)])weixin_params.sort(key=lambda x:x[0])sign_src = '%s&key=%s' % ('&'.join(['%s=%s'%(x[0], x[1]) for x in weixin_params]), config.WX_FWH_MCH_KEY)logging.info(sign_src)return hashlib.md5(sign_src).hexdigest().upper()def order(self):return '''<xml><nonce_str>%s</nonce_str><sign>%s</sign><mch_billno>%s</mch_billno><mch_id>%s</mch_id><wxappid>%s</wxappid><send_name>%s</send_name><re_openid>%s</re_openid><total_amount>%s</total_amount><total_num>%s</total_num><wishing>%s</wishing><act_name>%s</act_name><client_ip>%s</client_ip><remark>%s</remark>
</xml>''' % (self.nonce_str, WeixinWithdrawOrder.sign(self.__dict__), self.mch_billno,self.mch_id, self.wxappid, self.send_name,self.re_openid.encode('utf8'), self.total_amount, self.total_num, self.wishing,self.act_name, self.client_ip, self.remark,)def run_withdraw(self):try:order = self.order()logging.info(order)url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack'cert = ('data/weixin/apiclient_cert.pem', 'data/weixin/apiclient_key.pem') #微信商户号的key,通过商户平台下载data = requests.post(url, data=order, cert=cert).text  #使用第三方库requestroot = ElementTree.fromstring(data)response = {child.tag : child.text for child in root.getchildren()}logging.info(response)if response.get('return_code') == 'SUCCESS':if response.get('result_code') == 'SUCCESS':return True, response.get('mch_billno'), response.get('err_code'), response.get('return_msg')else:logging.error(data)return False, self.mch_billno, response.get('err_code'), response.get('return_msg')else:logging.error(data)return False, self.mch_billno, response.get('err_code'), response.get('return_msg')except:traceback.print_exc()return False, self.mch_billno, 'url not connect', 'url not connect'

APP提现之微信服务号红包相关推荐

  1. 微信服务号+支付+php,微信服务号发送营销红包给关注用户步骤及部分php代码

    微信红包 一.前言: 这里主要讲述的是微信服务号给关注用户发送微信红包的相关内容:主要使用的业务场景有:1.业务员匆匆销员的奖励:2.现场会议互动抽奖:3.微信推广转发奖励:4.其他等等等,大开脑洞想 ...

  2. 百万级微信服务号如何做活动运营和用户运营?

    原文发布于2014年9月初. 大家好,我叫米拉,我是做新媒体运营的,我们运营的微信服务号目前已突破100W+粉丝.通过活动测试我们的用户活跃度在20%左右.头条阅读打开率基本保持业内水平10%,在新榜 ...

  3. 商城系统开发,使用微信服务号好?还是小程序?

    微信服务号和小程序都可以使用微信授权登录(获取用户微信头像.昵称.).微信支付.带参数二维码.微信红包等功能. 很多企业在开发商城时,会纠结使用微信服务号还是小程序? 了解服务号与小程序 服务号定位是 ...

  4. 商城系统开发使用微信服务号和小程序那个好?

    "我们开发公众号不是为了媒体,我们的本意不是传播内容,我们要提供服务,但服务号没有达到预期,我们在讨论一个新的形态,叫应用号.平时不发东西,他安静的存在在那,低频的需求不需要安装App,微信 ...

  5. 多个微信服务号对接一个微信商户号流程

    微信服务号发送红包需要开通对应的微信商户号,如果多个微信服务号开通多个微信商户号会非常麻烦,项目管理上也会非常乱,写下多个微信服务号对接一个微信商户号的流程. 先登录微信商户平台,产品中心下的APPI ...

  6. 微信服务号开发-整合微信支付

    最近的项目在对接微信支付,所以抽出一些时间,将方法总结一下: 欢迎加群交流:724225958 官方开发文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi. ...

  7. vue开发的微信服务号的H5网页禁止点击时页面放大或者缩小

    vue开发的微信服务号 问题:点击H5页面时,页面会放大 ,不能固定 解决方案: 1.在index.html 页面 添加以下代码 width=device-width :表示宽度是设备屏幕的宽度 in ...

  8. 基于airtest+poco微信服务号自动化测试NO1

    基于airtest微信服务号自动化测试NO1 1. 项目背景 1.1 框架选择airtest+模拟器 1.2 软件安装 1.2.1 mumu模拟器 1.2.2 airtest安装 1.2.3 调试工具 ...

  9. 微信服务号及支付功能接入详解

    本文同步至个人博客 微信服务号及支付功能接入详解,转载请注明出处 最近在实现微信服务号支付功能,这边对接入商户资料审核及接口接入相关内容进行梳理. 旨在理清相关帐号的申请流程.整理服务开通.开发数据的 ...

最新文章

  1. 水晶报表导出数据并实现打印
  2. java fseek_转到C中的二进制文件的某个点(使用fseek),然后从该位置读取(使用fread)...
  3. LINQ系列:Linq to Object分区操作符
  4. MVC 视图与控制器传值的几种方法
  5. Java反射实现几种方式
  6. cmake跨平台编译之判断操作系统平台、32位64位系统
  7. leetcode(3)——414. 第三大的数(C++中的 set,::作用符号,迭代器),628 三个数的最大乘积(sort函数的用法)
  8. ElasticSearch探索之路(三)分布式原理:分布式路由、存储、搜索原理
  9. 1151 LCA in a Binary Tree 甲级
  10. 你不知道的JavaScript-0
  11. Linux Shell Record
  12. SpringCloud 微服务入门-Spring Cloud 与微服务概述
  13. [OfficeExcel] 王佩丰老师OfficeExcel2010 7-10讲 函数 学习笔记
  14. rtlinux linux实时补丁,(九)RTLinux补丁以及cyclictest
  15. Centos备份文件
  16. PHP中文转换为数组,PHP文本处理之中文汉字字符串转换为数组
  17. 数据库字典 - 微擎开发文档
  18. C4D模型工具—优化
  19. oracle数据库报错:ORA-01654: 索引 aaa 无法通过 128 (在表空间 bb 中) 扩展
  20. 说说Teams里的Card

热门文章

  1. 如何学习大型项目的源码?
  2. faster rcn固定输入图片尺寸(二)
  3. Excel计算开始与结束时间之间的小时/分钟/秒数
  4. Python 棋子移动游戏
  5. 使用css3 filter属性实现图片毛玻璃效果
  6. 最全iOS 应用上架流程(提交到AppStore)
  7. 移动应用测试与PC端测试区别
  8. 本地spa应用的nginx简单配置
  9. imagenet分类
  10. 变形金刚图片----汽车人