微信现金红包 python
微信现金红包发送接口,好像没法限制一个用户一个活动只能领取一次红包,在调用红包接口上,自己做了限制
REDPACK_RECORD
建表sql
-- Create table create table REDPACK_RECORD ( open_id VARCHAR2(32), act_id VARCHAR2(32), send_time TIMESTAMP(6) WITH LOCAL TIME ZONE default sysdate, mch_billno VARCHAR2(28), result CHAR(1), record_id VARCHAR2(36) default sys_guid() ) tablespace SYSTEM pctfree 10 pctused 40 initrans 1 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited ); -- Add comments to the columns comment on column REDPACK_RECORD.open_id is '用户id'; comment on column REDPACK_RECORD.act_id is '活动id'; comment on column REDPACK_RECORD.send_time is '发送时间'; comment on column REDPACK_RECORD.mch_billno is '商户订单号'; comment on column REDPACK_RECORD.result is '发送结果:0失败 1成功'; comment on column REDPACK_RECORD.record_id is '记录id';
REDPACK_ACTIVATE
建表sql
-- Create table create table REDPACK_ACTIVATE ( act_id VARCHAR2(32) default sys_guid(), act_name VARCHAR2(30), total_amount VARCHAR2(10), wishing VARCHAR2(50), remark VARCHAR2(100), secen_id VARCHAR2(32), state CHAR(1) ) tablespace SYSTEM pctfree 10 pctused 40 initrans 1 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited ); -- Add comments to the columns comment on column REDPACK_ACTIVATE.act_id is '活动id'; comment on column REDPACK_ACTIVATE.act_name is '活动名称'; comment on column REDPACK_ACTIVATE.total_amount is '付款金额,单位分'; comment on column REDPACK_ACTIVATE.wishing is '红包祝福语'; comment on column REDPACK_ACTIVATE.remark is '备注'; comment on column REDPACK_ACTIVATE.secen_id is '发放红包使用场景,红包金额大于200或者小于1元时必传 PRODUCT_1:商品促销 PRODUCT_2:抽奖 PRODUCT_3:虚拟物品兑奖 PRODUCT_4:企业内部福利 PRODUCT_5:渠道分润 PRODUCT_6:保险回馈 PRODUCT_7:彩票派奖 PRODUCT_8:税务刮奖'; comment on column REDPACK_ACTIVATE.state is '活动状态: 0未激活 1激活';
getRedpack,传入openId,actId
def getRedpack(openId, actId): # 查寻actId有效性(现在限制条件为一个活动一个用户只能领一个红包,可能存在改actId突破这一限制) session = DBSession() act = session.query(RedpackAct).filter(RedpackAct.state == '1').filter(RedpackAct.act_id == actId).one() if not act: return redpack['actError'] # 查询是否达到限制 records = session.query(RedpackRecord).filter(RedpackRecord.result == '1').filter( RedpackRecord.act_id == actId).filter(RedpackRecord.open_id == openId).all() if len(records) != 0: return redpack['repeat'] # 构造红包数据 mch_id = 'mch_id ' props = { 'nonce_str': getRangeStr(32), 'mch_id': mch_id, 'mch_billno': mch_id + get_time() + getRangeStr(4), # 28=10+14+4 'wxappid': 'wxappid', 're_openid': openId, 'total_amount': act.total_amount, 'total_num': '1', 'key': 'key', 'send_name': 'send_name', 'wishing': act.wishing, 'act_name': act.act_name, 'remark': act.remark, 'client_ip': 'act_name' } props['sign'] = signFun(props) data = json_xml(props).encode('utf8') # 发送红包 cert = p12_to_pem('证书名') res = requests.post('https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack', data=data, cert=cert) print res.text # 获取发送结果,记录到数据库 result = xml_json(res.text)['xml'] if result['return_code'] == 'SUCCESS': success = xml_json(res.text)['xml']['result_code'] == 'SUCCESS' sqltext = "insert into redpack_record(open_id,act_id,mch_billno,result) values('%s','%s','%s','%s')"%(openId, actId, props['mch_billno'], 1 if success else 0) session.execute(sqltext) session.commit() return result['return_msg'].encode('utf8')
相关函数
redpack = { 'success': '发放红包成功', 'error': '出现问题,请重试', 'repeat': '你已经领取过该红包,请勿重复领取', 'actError': '活动无效' } activate = { '问卷调查红包': '761E52960C497C77E05012AC8E4E0A32'#数据库活动表的id,输入问卷调查找到此活动 } def m_dict(obj, props=[]): result = {} temp = obj.__dict__ if hasattr(obj, '__dict__') else obj target = temp if len(props)==0 else props for i in target: if not i.startswith('_'): try: result[i] = getattr(obj, i) if hasattr(obj, i) else obj[i] except: pass return result def getRangeStr(len): result = '' chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' for i in range(len): result += choice(chars) return result def get_time(formatStr='%Y%m%d%H%M%S'): return time.strftime(formatStr, time.localtime(time.time())) def formateLen(instr, width): instr = str(instr) if len(instr)<width: return formateLen('0'+instr, width) else: return instr def MD5(instr): return hashlib.md5(instr).hexdigest() def signFun(props): tempStr = '' key = props.pop('key') props = sorted(props.items()) for prop in props: tempStr += (prop[0]+'='+prop[1]+'&') return MD5(tempStr+'key='+key).upper() def json_xml(jsonstr): if 'xml' not in jsonstr: jsonstr = {'xml': jsonstr} jsonstr = json.dumps(jsonstr).decode('utf8') jsonstr = json.loads(jsonstr) return xmltodict.unparse(jsonstr) def xml_json(xmlstr): return xmltodict.parse(xmlstr) # return json.dumps(xmlparse,indent=1) def p12_to_pem(certname, pwd='商户号'): pem_name = certname + ".pem" f_pem = open(pem_name, 'wb') p12file = certname + ".p12" p12 = OpenSSL.crypto.load_pkcs12(open(p12file, 'rb').read(), pwd) f_pem.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey())) f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate())) ca = p12.get_ca_certificates() if ca is not None: for cert in ca: f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)) f_pem.close() return pem_name def getUUID(namespace='redpack', name='recode'): return uuid.uuid5(namespace, name)
通过用户输入消息触发
# -*- coding: utf-8 -*- # filename: handle.py import reply import receive import web from util import * class Handle(object): def POST(self): try: webData = web.data() recMsg = receive.parse_xml(webData) if isinstance(recMsg, receive.Msg) and recMsg.MsgType == 'text': toUser = recMsg.FromUserName fromUser = recMsg.ToUserName content = recMsg.Content if content in activate: content = getRedpack(toUser, activate[content]) replyMsg = reply.TextMsg(toUser, fromUser, content) return replyMsg.send() return "success" except Exception, Argment: return Argment
Become a Linux Programmer