def GET(self): if logged(): render = create_render() result = 0 if logged(helper.PRIV_USER | helper.PRIV_MCH): # 提醒改密码 db_user = db.user.find_one({'uname': session.uname}, {'pwd_update': 1}) if int(time.time()) - db_user.get('pwd_update', 0) > 3600 * 24 * 30: raise web.seeother('/settings_user?set_pwd=1') else: return render.portal(session.uname, get_privilege_name(), [result]) else: return render.portal(session.uname, get_privilege_name(), [result]) else: render = create_render() db_sys = db.user.find_one({'uname': 'settings'}) if db_sys == None: signup = 0 else: signup = db_sys['signup'] # 生成验证码 rand = app_helper.my_rand(4).upper() session.uid = rand # uid 临时存放验证码 session.menu_level = 0 # 暂存输入验证码次数 png2 = rand_code.gen_rand_png(rand) return render.login(signup, png2)
def POST(self): web.header('Content-Type', 'application/json') param = web.input(currUrl='', cross='', share_type='') ticket = get_ticket() if ticket == '': # 重试一次 ticket = get_ticket() if ticket == '': print '---------- get ticket fail!' #return None noncestr = app_helper.my_rand() timestamp = str(int(time.time())) url = param.currUrl string1 = 'jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s' % ( ticket, noncestr, timestamp, url) print string1 if param.cross == 'yes': return 'jsonpcallback(%s)' % json.dumps( { 'appid': wx_appid, 'timestamp': timestamp, 'nonceStr': noncestr, 'sign': hashlib.sha1(string1).hexdigest(), }) else: return json.dumps({ 'appid': wx_appid, 'timestamp': timestamp, 'nonceStr': noncestr, 'sign': hashlib.sha1(string1).hexdigest(), })
def POST(self): web.header('Content-Type', 'application/json') param = web.input(app_id='', session='', name='', tel='', addr='', sign='') if '' in (param.app_id, param.session, param.name, param.tel, param.addr, param.sign): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) uname = app_helper.logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign([param.app_id, param.session, param.name, param.tel, param.addr]) if md5_str!=param.sign: return json.dumps({'ret' : -1, 'msg' : '签名验证错误'}) # 需要判断地址是否有对应门店,否则不在送货范围内 # app_helper.check_address() # 更新个人资料 new_addr = ( app_helper.my_rand(), param.name.strip(), param.tel.strip(), param.addr.strip(), int(time.time()) ) r = db.app_user.update_one({'uname':uname}, {'$push' : {'address' : new_addr}}) # 返回 return json.dumps({'ret' : 0, 'data' : { 'addr_id' : new_addr[0], }}) else: return json.dumps({'ret' : -4, 'msg' : '无效的session'})
def POST(self): web.header('Content-Type', 'application/json') #print web.input() param = web.input(openid='', session_id='', number='') if param.number == '': return json.dumps({'ret': -2, 'msg': '参数错误'}) if param.openid == '' and param.session_id == '': return json.dumps({'ret': -2, 'msg': '参数错误1'}) # 同时支持openid和session_id if param.openid != '': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: #print 'user_phone', uname if len(uname['uname'].strip()) > 0: return json.dumps({'ret': -5, 'msg': '已绑定手机号码,不能重复绑定'}) number = param.number.strip() if len(number) < 11 or (not number.isdigit()): return json.dumps({'ret': -3, 'msg': '手机号码格式错误'}) # 随机码 rand = app_helper.my_rand(base=1) register = False #发送短信验证码 sms.send_rand(number, rand, register) #临时保存到phone字段 db.app_user.update({'openid': uname['openid']}, {'$set': { 'phone': number, 'rand': rand }}) # 返回 return json.dumps({'ret': 0}) else: return json.dumps({'ret': -4, 'msg': '无效的openid'})
def POST(self): web.header('Content-Type', 'application/json') param = web.input(session_id='', mobile='') if param.session_id=='': return json.dumps({'ret' : -1, 'msg' : 'session_id参数错误'}) #uname = app_helper.wx_logged(param.session_id) #if uname is None: # return json.dumps({'ret' : -4, 'msg' : '无效的session_id'}) if param.mobile=='': return json.dumps({'ret' : -2, 'msg' : '参数错误'}) number = param.mobile.strip() if len(number)<11 or (not number.isdigit()): return json.dumps({'ret' : -10, 'msg' : '手机号码格式错误'}) if number in app_helper.BLOCK_LIST: return json.dumps({'ret' : -10, 'msg' : '手机号码错误'}) session = app_helper.get_session(param.session_id) if session is None: return json.dumps({'ret': -4, 'msg': '无效的session_id'}) if session.get('userid')!='': return json.dumps({'ret': -9, 'msg': '已绑定,不能重复绑定'}) rand = app_helper.my_rand(base=1) db.app_sessions.update_one({'session_id': session['session_id']}, {'$set': { 'attime': time.time(), 'rand': rand, }}) if number not in app_helper.INNER_NUM.keys(): # 内部号码不发短信,2015-12-22, gt rr = sms.send_rand(param.mobile, rand, False) # 测试不发校验码 if rr is None: return json.dumps({'ret': -11, 'msg': '发送太频繁,稍后再试'}) return json.dumps({'ret': 0, 'data': { 'session' : session['session_id'], 'if_sms_send' : True, }})
def POST(self): web.header('Content-Type', 'application/json') param = web.input(openid='', session_id='', name='', tel='', addr='') if '' in (param.name, param.tel, param.addr): return json.dumps({'ret': -2, 'msg': '参数错误'}) if param.openid == '' and param.session_id == '': return json.dumps({'ret': -2, 'msg': '参数错误1'}) # 同时支持openid和session_id if param.openid != '': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: # 需要判断地址是否有对应门店,否则不在送货范围内 # app_helper.check_address() # 更新个人资料 new_addr = (app_helper.my_rand(), param.name.strip(), param.tel.strip(), param.addr.strip(), int(time.time())) r = db.app_user.update_one({'openid': uname['openid']}, {'$push': { 'address': new_addr }}) # 返回 return json.dumps({ 'ret': 0, 'data': { 'addr_id': new_addr[0], } }) else: return json.dumps({'ret': -4, 'msg': '无效的openid'})
def genSignature(currUrl): ticket = get_ticket() if ticket == '': # 重试一次 ticket = get_ticket() if ticket == '': print '---------- get ticket fail!' #return None noncestr = app_helper.my_rand() timestamp = str(int(time.time())) #url = 'http://test.urfresh.cn/static/hb/001.html' url = currUrl string1 = 'jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s' % ( ticket, noncestr, timestamp, url) print string1 return { 'appid': wx_appid, 'timestamp': timestamp, 'nonceStr': noncestr, 'sign': hashlib.sha1(string1).hexdigest(), }
def init_job(code, need_more_data=False, parent=None, auth_code=''): print '----> MIGIC CODE:', code if code == '': #return render.info('参数错误',goto='/') # info页面要做微信端优化 #raise web.seeother('/wx/init_fair') if need_more_data: return None, None, 0, 0 else: return None if len(code) < 20: # 小于20说明是自定义code,如果不在列表里,则拒绝 2020-04-09 if code in CODE_MIGIC.keys(): # 用于非微信环境进入 openid = code else: raise web.Unauthorized( 'Unauthorized visit.') # 这应该会显示 not found 2020-04-09 else: urllib3.disable_warnings() http = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' \ 'appid=%s&' \ 'secret=%s&' \ 'code=%s&' \ 'grant_type=authorization_code' % \ (wx_appid, wx_secret, code, ) r = http.request('GET', url) if r.status == 200: data = r.data t = json.loads(data) #print t http.clear() if t.has_key('openid'): openid = t['openid'] else: #print '===========Error==============', data, wx_secret, wx_appid if need_more_data: return None, None, 0, 0 else: return None else: http.clear() if need_more_data: return None, None, 0, 0 else: return None # 取得ticket ticket = get_ticket() if ticket == '': print 'get ticket fail!' #raise web.seeother('/wx/init_fair') #return None ticket = get_ticket(True) uname = '' # 检查用户是否已注册 #db_user = db.app_user .find_one({'openid':openid}) db_user = app_user_helper.get_user_info(openid, q_type='openid') is_new_user = 0 is_our_fan = True if db_user == None: # 未注册,新建用户记录 is_new_user = 1 # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info unionid = info.get('unionid', '') coupon = [] new_set = { 'openid': openid, 'unionid': unionid, 'region_id': setting.region_id, # 增加 region_id 'type': 'wx_pub', # 用户类型 'address': [], 'coupon': coupon, # 送优惠券 'app_id': '', # 微信先注册,没有app_id 'reg_time': app_helper.time_str(), 'wx_nickname': info.get('nickname', '游客'), 'wx_headimgurl': info.get('headimgurl', ''), 'wx_info': info, 'refresh_headimg': REFRESH_HEADIMG, 'last_status': int(time.time()), 'app_order_num': 0 # 20160927 lf 未下单 } # 用户中心注册用户接口 app_user_helper.new_user_info(openid, 'openid', new_set) is_our_fan = not (info.get('nickname', u'游客') == u'游客' ) # 是否是公众号粉丝,通过是否是游客判断 # 添加用户关系 2016-03-31 # 只有新注册用户添加 if parent not in [None, '']: from libs import user_tree parent_u = user_tree.owner2unionid(parent) if parent_u != None and unionid != parent_u: user_tree.add_parent(unionid, parent_u) print '======> TREE:', unionid, parent_u else: # 记录今天访问次数 last_date = db_user.get('last_visit_date') today_date = app_helper.time_str(format=1) # 格式 2016-01-01 if last_date != today_date: update_set = { 'last_visit_date': today_date, 'today_visit_count': 1, 'todat_visit_first_tick': int(time.time()), 'todat_push_image_text': 0, } else: update_set = { 'today_visit_count': db_user.get('today_visit_count', 0) + 1, } # 更新 region_id if db_user.get('region_id') != setting.region_id: update_set['region_id'] = setting.region_id if not openid_is_fun(openid) \ or db_user.get('wx_nickname', '')=='' \ or db_user.get('refresh_headimg',0)<=0: # 没有关注 # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info unionid = info.get('unionid', '') # 补充微信用户信息 update_set['unionid'] = unionid update_set['wx_nickname'] = info.get('nickname', '游客') update_set['wx_headimgurl'] = info.get('headimgurl', '') update_set['wx_info'] = info update_set['refresh_headimg'] = REFRESH_HEADIMG #db.app_user .update_one({'openid':openid}, {'$set': update_set}) app_user_helper.update_user_info(openid, q_type='openid', update_set=update_set) is_our_fan = not (info.get('nickname', u'游客') == u'游客') else: unionid = db_user.get('unionid', '') is_our_fan = True # 刷新refresh_headimg db.app_user.update_one({'openid': openid}, { '$set': update_set, '$inc': { 'refresh_headimg': -1 } }) uname = db_user.get('uname', '') # 生成 session ------------------ rand2 = app_helper.my_rand(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'openid': openid, 'unionid': unionid, 'ticket': ticket, 'uname': uname, 'login': 1, 'rand': rand2, 'ip': web.ctx.ip, 'attime': now, 'type': 'wx', 'auth_code': auth_code, # 20190516 记录来源 }) print "session >>>>>>>>>> ", session_id, openid, uname, auth_code if need_more_data: # 返回是否是粉丝 return session_id, is_our_fan, is_new_user, openid else: return session_id
def init_job(code, need_more_data=False, parent=None): if code == '': #return render.info('参数错误',goto='/') # info页面要做微信端优化 #raise web.seeother('/wx/init_fair') if need_more_data: return None, None, 0, 0 else: return None if code == 'test': openid = code else: urllib3.disable_warnings() http = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' \ 'appid=%s&' \ 'secret=%s&' \ 'code=%s&' \ 'grant_type=authorization_code' % \ (wx_appid, wx_secret, code, ) r = http.request('GET', url) if r.status == 200: data = r.data t = json.loads(data) #print t http.clear() if t.has_key('openid'): openid = t['openid'] else: #print '===========Error==============', data, wx_secret, wx_appid if need_more_data: return None, None, 0, 0 else: return None else: http.clear() if need_more_data: return None, None, 0, 0 else: return None # 取得ticket ticket = get_ticket() if ticket == '': print 'get ticket fail!' #raise web.seeother('/wx/init_fair') #return None ticket = get_ticket(True) uname = '' userid = '' if_bind = False # 检查用户是否已注册 db_user = db.app_user.find_one({'openid': openid}) is_new_user = 0 is_our_fan = True if db_user == None: # 未注册,新建用户记录 is_new_user = 1 # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info unionid = info.get('unionid', '') new_set = { 'userid': '', # 用户id,未绑定为空 'openid': openid, 'unionid': unionid, 'type': 3, # 1 电话号码用户, 2 微信app登录用户, 3 微信公众号用户, 4 QQ 用户 'bind': 0, # 1 已绑定, 0 未绑定 'mice': 0, # 1 正常用户, 0 黑名单用户 'app_id': '', # 微信先注册,没有app_id 'reg_time': app_helper.time_str(), 'last_status': int(time.time()), 'nickname': info.get('nickname', '游客'), 'img_url': info.get('headimgurl', ''), 'wx_info': info, 'refresh_headimg': REFRESH_HEADIMG, } # 用户中心注册用户接口 db.app_user.update_one({'openid': openid}, {'$set': new_set}, upsert=True) is_our_fan = not (info.get('nickname', u'游客') == u'游客' ) # 是否是公众号粉丝,通过是否是游客判断 # 添加用户关系 2016-03-31 # 只有新注册用户添加 if parent not in [None, '']: from libs import user_tree parent_u = user_tree.owner2unionid(parent) if parent_u != None and unionid != parent_u: user_tree.add_parent(unionid, parent_u) print '======> TREE:', unionid, parent_u else: # 记录今天访问次数 last_date = db_user.get('last_visit_date') today_date = app_helper.time_str(format=1) # 格式 2016-01-01 if last_date != today_date: update_set = { 'last_visit_date': today_date, 'today_visit_count': 1, 'todat_visit_first_tick': int(time.time()), 'todat_push_image_text': 0, } else: update_set = { 'today_visit_count': db_user.get('today_visit_count', 0) + 1, } if not openid_is_fun(openid) \ or db_user.get('nickname', '')=='' \ or db_user.get('refresh_headimg',0)<=0: # 没有关注 # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info unionid = info.get('unionid', '') # 补充微信用户信息 update_set['unionid'] = unionid update_set['nickname'] = info.get('nickname', '游客') update_set['img_url'] = info.get('headimgurl', '') update_set['wx_info'] = info update_set['refresh_headimg'] = REFRESH_HEADIMG db.app_user.update_one({'openid': openid}, {'$set': update_set}) is_our_fan = not (info.get('nickname', u'游客') == u'游客') else: unionid = db_user.get('unionid', '') is_our_fan = True # 刷新refresh_headimg db.app_user.update_one({'openid': openid}, { '$set': update_set, '$inc': { 'refresh_headimg': -1 } }) uname = db_user.get('uname', '') userid = db_user.get('userid', '') if_bind = (db_user['bind'] == 1) # 更新 unionid_index, 2016-03-01 , gt #db.unionid_index.update_one({'openid':openid}, {'$set':{'unionid':unionid}}, upsert=True) # 生成 session ------------------ rand2 = app_helper.my_rand(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() once_code = hashlib.md5(session_id).hexdigest() # 用于第一次获取session_id db.app_sessions.insert_one({ 'session_id': session_id, 'userid': userid, 'openid': openid, 'unionid': unionid, 'ticket': ticket, #'uname' : uname, 'login': 1, 'rand': rand2, 'ip': web.ctx.ip, 'attime': now, 'type': 3, # session 类型 1 手机 2 微信app登录 3 微信公众号 4 QQ用户 'once_code': once_code, 'bind': 1 if if_bind else 0, }) print session_id, openid, uname, once_code, userid print "qqffdd session_id >>>>>>>>>> %r" % session_id if need_more_data: # 返回是否是粉丝 #return session_id, is_our_fan, is_new_user, openid return once_code, is_our_fan, is_new_user, openid else: #return session_id return once_code
def POST(self, version='v1'): param = web.input() print param str_xml=web.data() print str_xml if check_sign_wx(str_xml): print "WXPAY SIGNATURE CHECK SUCCESS!" else: print "WXPAY SIGNATURE CHECK FAIL ......!" return '<xml>' \ '<return_code><![CDATA[FAIL]]></return_code>' \ '<return_msg><![CDATA[签名失败]]></return_msg>' \ '</xml>' xml=ET.fromstring(str_xml) return_code = xml.find('return_code').text if return_code!='SUCCESS': # 通信失败 return '<xml>' \ '<return_code><![CDATA[FAIL]]></return_code>' \ '<return_msg><![CDATA[FAIL]]></return_msg>' \ '</xml>' result_code = xml.find('result_code').text if result_code=='SUCCESS': # 有付款 # v2 开始微信支付out_trade_no,在order_id后加时间戳 2015-09-19 order_id0 = xml.find('out_trade_no').text order_id = order_id0.split('_')[0] r = db.order_app.find_one({'order_id':order_id}, #{'due':1, 'uname':1, 'coupon':1, 'shop':1, 'cart':1, 'status':1}) {'_id':0}) if r: status = 'PAID' comment = '' # 用于记录history时附加信息 2015-11-21 #if float(r['due'])<=float(xml.find('total_fee').text): # 检查支付金额与应付是否一致 # status = 'PAID' #else: # status = 'PARTIAL_PAID' print r['status'] db_user = db.app_user.find_one({'$or' : [ {'uname':r['uname']},{'openid':r['uname']} # 2015-08-22 ]}) if r['status'] in ['DUE', 'PREPAID', 'TIMEOUT']: # 如果状态已是PAID,说明有重复通知,不减库存 # 消费余额 if float(r.get('use_credit', '0'))>0: print db_user['credit'],float(r['use_credit']) if db_user['credit']>=float(r['use_credit']): # 余额够用 db.app_user.update_one({'$or' : [ {'uname':r['uname']},{'openid':r['uname']} # 2015-08-22 ]},{ '$inc' : { 'credit' : 0-float(r['use_credit']), }, '$push' : { 'credit_history' : ( # 专门记录余额消费 app_helper.time_str(), '消费余额', '-%.2f' % float(r['use_credit']), '订单: %s' % order_id.encode('utf-8') ) }, }) else: # 余额不够用 # 修改订单状态 t = xml.find('time_end').text paid_time = '%s-%s-%s %s:%s:%s' % (t[:4],t[4:6],t[6:8],t[8:10],t[10:12],t[12:]) db.order_app.update_one({'order_id':order_id},{ '$set' : { 'status' : 'CANCEL_TO_REFUND', #'sum_to_refund' : r['due'], 'use_credit' : '0.00', # 清除余额支付,防止多退款 'use_credit_old': r['use_credit'], # 保存应收余额支付金额 #'cart' : b2, # 更新购物车 2015-09-11 'wx_trade_no' : xml.find('transaction_id').text, 'paid_time' : paid_time, 'paid_tick' : int(time.time()), 'wx_out_trade_no' : order_id0, 'pay_type' : 'WXPAY', }, '$push' : { 'wx_notify' : str_xml, 'history' : (app_helper.time_str(), 'wxpay', '付款通知:余额不足转入退款') } }) return '<xml>' \ '<return_code><![CDATA[SUCCESS]]></return_code>' \ '<return_msg><![CDATA[OK]]></return_msg>' \ '</xml>' # 使用的优惠券失效 # app微信支付,和 公众号微信支付都从这返回 coupon = [] if r['coupon']!=None: for i in db_user['coupon']: if i[0]==r['coupon'][0]: # 这次使用 #coupon.append((i[0],i[1],i[2],0)) i2=list(i) i2[3]=0 coupon.append(i2) else: coupon.append(i) else: coupon = db_user['coupon'] # 满30送5元抵用券 #if float(param.get('total_fee','0'))>=30: # valid = app_helper.time_str(time.time()+3600*24*30, 1) # coupon.append((app_helper.my_rand(), valid, '5.00', 1)) # 首单送抵用券 #if db.order_app.find({'user':r['uname'],'status':{'$nin':['TIMEOUT','DUE','CANCEL']},'order_id':{'$ne':order_id}},{'_id':1}).count()==0: # # (id, 有效期, 金额, 是否已用, 门槛) 2015-09-27 # valid = app_helper.time_str(time.time()+3600*24*30, 1) # if str(r['shop']) in app_helper.new_coupon2_shop: # print '首单送优惠券(指定店)' # for i in app_helper.new_coupon2: # coupon.append((app_helper.my_rand(), valid, '%.2f' % float(i[0]), 1, i[1], i[2])) # else: # print '首单送优惠券' # for i in app_helper.new_coupon: # coupon.append((app_helper.my_rand(), valid, '%.2f' % float(i[0]), 1, i[1], i[2])) # 更新优惠券 2015-08-22 db.app_user.update_one({'$or' : [ {'uname':r['uname']},{'openid':r['uname']} ]}, {'$set':{'coupon':coupon}}) # 邀请码用户送抵用券 2015-10-24 invitation = db_user.get('invitation', '') if invitation!='' and db_user.get('invite_coupon_has_sent', 0)==0: # 已填邀请码并且未送过券 coupon_user = db.app_user.find_one({'my_invit_code':invitation},{'uname':1}) if coupon_user: # 送邀请码用户抵用券 print '送邀请码用户抵用券' valid = app_helper.time_str(time.time()+3600*24*30, 1) db.app_user.update_one({'uname':coupon_user['uname']},{'$push':{ 'coupon' : (app_helper.my_rand(), valid, '5.00', 1, 19.9, 'apple') }}) # 设置已送标志 db.app_user.update_one({'uname':r['uname']}, {'$set':{'invite_coupon_has_sent':1}}) if order_id[0]=='t': # 拼团订单处理 # 不修改购物车内容 b2 = r['cart'] # 检查是否已在member中 r1 = db.pt_order.find_one({ 'pt_order_id' : r['pt_order_id'], 'member.openid' : r['uname'] }) if r1: # 已参团 status = 'FAIL_TO_REFUND' # 参团失败,等待退款 comment = ':参团失败-已参团' print '参团失败:已参团' else: # 更新pt_order r2 = db.pt_order.find_one_and_update( { 'pt_order_id' : r['pt_order_id'], 'need' : { '$gt' : 0 }, 'status' : { '$in' : ['OPEN', 'WAIT']}, # 已开团和等待开团状态 }, { '$push' : { 'member' : { 'openid' : r['uname'], 'position' : r['position'], 'time' : app_helper.time_str(), 'order_id' : order_id, } }, '$inc' : { 'need' : -1 } } ) if r2==None: # pt_order 状态不是 OPEN 或 need==0, 取消本用户订单 status = 'FAIL_TO_REFUND' # 参团失败,等待退款 comment = ':参团失败-已成团' print '参团失败:已成团' else: if r2['need']==1: # 最后一人, 成团! db.pt_order.update_one( { 'pt_order_id' : r['pt_order_id']}, { '$set' : { 'status' : 'SUCC', 'succ_time' : app_helper.time_str(), 'succ_tick' : int(time.time()), }, '$push' : {'history':(app_helper.time_str(), 'wxpay', '拼团成功')} } ) # 所有团中PAID_AND_WAIT订单成为 PAID,准备拣货 db.order_app.update_many( { 'pt_order_id' : r['pt_order_id'], 'status':'PAID_AND_WAIT' }, { '$set' : {'status':'PAID'}, '$push' : {'history':(app_helper.time_str(), 'wxpay', '拼团成功')} } ) # 发消息 print '发微信通知' r3=db.pt_order.find_one({ 'pt_order_id' : r['pt_order_id']},{'member':1}) for x in r3['member']: print app_helper.wx_reply_msg(x['openid'], '您参加的拼团活动已成团,我们会尽快为您安排发货') status = 'PAID' comment = ':成团' else: if r2['member']==[]: # 团长开团 db.pt_order.update_one( { 'pt_order_id' : r['pt_order_id']}, { '$set' : { 'status' : 'OPEN', 'succ_time' : app_helper.time_str(), 'succ_tick' : int(time.time()), }, '$push' : {'history':(app_helper.time_str(), 'wxpay', '开团成功')} } ) status = 'PAID_AND_WAIT' # 等待成团 comment = ':等待成团' else: # 普通1小时订单: n开头、e开头 # 正常减库存! # item = [ product_id, num, num2, price] # k - num 库存数量 print "修改库存." b2 = [] # C端商品 b3 = [] # B3整箱预售商品 b3_total = 0.0 for item in r['cart']: # 记录销售量 db.sku_store.update_one({'product_id' : item['product_id']}, {'$inc' : {'volume' : float(item['num2'])}} ) # 暂停整箱预售 2015-10-27 #r3 = db.sku_store.find_one({'product_id' : item['product_id']}, # {'list_in_app':1}) #if r3['list_in_app']==3: # B3商品不需要改库存 # b3_total += float(item['price']) # b3.append(item) # item['title'] = item['title']+u'(整箱预售,次日送达)' # b2.append(item) # continue # 买一送一 if item.has_key('numyy'): # v3 2015-10-25 if item['product_id'] in app_helper.buy_X_give_Y.keys(): print '买X送Y' #item['num2'] = int(float(item['num2']) + float(item['numyy'])) #item['title'] = item['title'] + u'特惠活动' else: if item['product_id'] in app_helper.buy_1_give_1: print '买一送一' lc_num2 = float(item['num2']) item['num2'] = int(lc_num2 + lc_num2) item['title'] = item['title'].replace(u'买一送一',u'特惠活动') # 过滤数量价格为零的 if item['num2']==0 and float(item['price'])==0.0: continue # num2 实际购买数量, numyy 赠送数量, v3之后才有munyy 2015-10-20 num_to_change = float(item['num2']) + float(item.get('numyy', 0.0)) r2 = db.inventory.find_one_and_update( # 不检查库存,有可能负库存 { 'product_id' : item['product_id'], 'shop' : r['shop'], }, { '$inc' : { 'num' : 0-num_to_change, # num2 实际购买数量 'pre_pay_num' : num_to_change, # 记录预付数量 } #'$push' : { 'history' : (helper.time_str(), # helper.get_session_uname(), '售出 %s' % str(item['num']))}, }, {'_id':1} ) #print r if r2==None: # 不应该发生 return json.dumps({'ret' : -9, 'msg' : '修改库存失败,请联系管理员!'}) else: b2.append(item) # 更新第3方库存 2015-10-10 app_helper.elm_modify_num(r['shop'], item['product_id']) # 检查是否有b3商品, 3种情况 # 1. b2, b3 都有,拆单 # 2. 只有b3,站点改为B3站点,保留收货站点 # 3. 只有b2,保持订单不变 #print b2 #print b3 if len(b3)>0 and (len(b2)-len(b3))>0: # 情况1 print "拆单" r4 = r.copy() r4['order_id'] = r4['order_id']+u'-b3' r4['shop_0'] = r['shop'] r4['shop'] = ObjectId(setting.B3_shop) r4['cart'] = b3 r4['status'] = status r4['ali_trade_no'] = param.get('trade_no') r4['paid_time'] = param.get('gmt_payment') r4['paid_tick'] = int(time.time()) r4['history'] = [(app_helper.time_str(), 'alipay', '付款通知-拆单')] r4['total'] = '%.2f' % b3_total r4['cost'] = '0.00' r4['coupon_disc'] = '0.00' r4['first_disc'] = '0.00' r4['delivery_fee'] = '0.00' r4['due'] = '0.00' db.order_app.insert_one(r4) # 增加子订单 elif len(b3)>0: # 情况 2 print "订单改到B3站点" # 如果订单地址不再配送范围,则由b3直接发出, 2015-10-18 if r.get('poly_shop', 1)==1: # 默认到店配送 print 'b3配送到店' shop_0 = r['shop'] else: print 'b3直接发货' shop_0 = ObjectId(setting.B3_shop) db.order_app.update_one({'order_id':order_id},{'$set' : { 'shop_0' : shop_0, #r['shop'], 'shop' : ObjectId(setting.B3_shop), }}) else: # 情况3,什么都不做 print "订单保持不变" # 推送通知 #if len(r['uname'])==11 and r['uname'][0]=='1': # jpush.jpush('已收到您的付款,我们会尽快处理。', r['uname']) else: print "重复通知:wxpay" b2 = r['cart'] # 修改订单状态 t = xml.find('time_end').text paid_time = '%s-%s-%s %s:%s:%s' % (t[:4],t[4:6],t[6:8],t[8:10],t[10:12],t[12:]) db.order_app.update_one({'order_id':order_id},{ '$set' : { 'status' : status, 'cart' : b2, # 更新购物车 2015-09-11 'wx_trade_no' : xml.find('transaction_id').text, 'paid_time' : paid_time, 'paid_tick' : int(time.time()), 'wx_out_trade_no' : order_id0, 'pay_type' : 'WXPAY', 'credit_total' : '%.2f' % float(r.get('use_credit', '0')), 'wxpay_total' : '%.2f' % (float(xml.find('total_fee').text)/100.0) }, '$push' : { 'wx_notify' : str_xml, 'history' : (app_helper.time_str(), 'wxpay', '付款通知'+comment) } }) return '<xml>' \ '<return_code><![CDATA[SUCCESS]]></return_code>' \ '<return_msg><![CDATA[OK]]></return_msg>' \ '</xml>'
def get_prepay_id(wx_appid, mch_id, trade_type, client_ip, order_id, total_fee, openid=None): nonce_str = app_helper.my_rand(30) if trade_type == 'APP': body = 'U掌柜app' para = [('appid', wx_appid), ('body', body), ('mch_id', mch_id), ('nonce_str', nonce_str), ('notify_url', notify_url), ('out_trade_no', order_id), ('spbill_create_ip', client_ip), ('total_fee', total_fee), ('trade_type', trade_type)] else: # trade_type == 'JSAPI' body = 'U掌柜微信' para = [('appid', wx_appid), ('body', body), ('mch_id', mch_id), ('nonce_str', nonce_str), ('notify_url', notify_url), ('openid', openid), ('out_trade_no', order_id), ('spbill_create_ip', client_ip), ('total_fee', total_fee), ('trade_type', trade_type)] print para stringA = '&'.join('%s=%s' % i for i in para) stringSignTemp = '%s&key=%s' % (stringA, api_key) sign = hashlib.md5(stringSignTemp).hexdigest().upper() if trade_type == 'APP': para_xml = '<xml>' \ '<appid>'+wx_appid+'</appid>' \ '<mch_id>'+mch_id+'</mch_id>' \ '<nonce_str>'+nonce_str+'</nonce_str>' \ '<sign>'+sign+'</sign>' \ '<body>'+body+'</body>' \ '<out_trade_no>'+order_id+'</out_trade_no>' \ '<total_fee>'+total_fee+'</total_fee>' \ '<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \ '<notify_url>'+notify_url+'</notify_url>' \ '<trade_type>'+trade_type+'</trade_type>' \ '</xml>' else: para_xml = '<xml>' \ '<appid>'+wx_appid+'</appid>' \ '<mch_id>'+mch_id+'</mch_id>' \ '<nonce_str>'+nonce_str+'</nonce_str>' \ '<sign>'+sign+'</sign>' \ '<body>'+body+'</body>' \ '<out_trade_no>'+order_id+'</out_trade_no>' \ '<total_fee>'+total_fee+'</total_fee>' \ '<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \ '<notify_url>'+notify_url+'</notify_url>' \ '<trade_type>'+trade_type+'</trade_type>' \ '<openid>'+openid+'</openid>' \ '</xml>' print para_xml pool = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' r = pool.urlopen('POST', url, body=para_xml) return r
def POST(self): web.header('Content-Type', 'application/json') param = web.input(app_id='', session='', order_id='', total='', sign='') if '' in (param.app_id, param.order_id, param.session, param.total, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) if web.ctx.has_key('environ'): client_ip = web.ctx.environ['REMOTE_ADDR'] else: return json.dumps({'ret': -5, 'msg': '无法取得客户端ip地址'}) uname = app_helper.logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign( [param.app_id, param.session, param.order_id, param.total]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) db_shop = db.base_shop.find_one( {'_id': ObjectId(setting.default_shop)}, {'name': 1}) # 统一下单接口获取 prepay_id nonce_str = app_helper.my_rand(30) body = 'U掌柜app' trade_type = 'APP' order_id = param.order_id.encode('utf-8') total_fee = param.total.encode('utf-8') para = [('appid', wx_appid), ('body', body), ('mch_id', mch_id), ('nonce_str', nonce_str), ('notify_url', notify_url), ('out_trade_no', order_id), ('spbill_create_ip', client_ip), ('total_fee', total_fee), ('trade_type', trade_type)] #print para stringA = '&'.join('%s=%s' % i for i in para) stringSignTemp = '%s&key=%s' % (stringA, api_key) sign = hashlib.md5(stringSignTemp).hexdigest().upper() para_xml = '<xml>' \ '<appid>'+wx_appid+'</appid>' \ '<mch_id>'+mch_id+'</mch_id>' \ '<nonce_str>'+nonce_str+'</nonce_str>' \ '<sign>'+sign+'</sign>' \ '<body>'+body+'</body>' \ '<out_trade_no>'+order_id+'</out_trade_no>' \ '<total_fee>'+total_fee+'</total_fee>' \ '<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \ '<notify_url>'+notify_url+'</notify_url>' \ '<trade_type>'+trade_type+'</trade_type>' \ '</xml>' print para_xml #return json.dumps({'ret' : 0, 'data' : 'here'}) urllib3.disable_warnings() pool = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' r = pool.urlopen('POST', url, body=para_xml) if r.status == 200: data = r.data print data return json.dumps({'ret': 0, 'data': data}) else: return json.dumps({'ret': -1, 'data': r.status}) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def init_job(code): if code == '': return None if code == 'test': openid = code else: token = get_qy_token() # 读取用户id url='https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s' % \ (token, code) f = urllib.urlopen(url) data = f.read() f.close() t = json.loads(data) print t if t.has_key('UserId'): openid = t['UserId'] else: print 'NOT FOUND: UserId!!!' return None # 用户基本信息 info = get_user_info(openid) if info['errcode'] != 0: get_qy_token0(True) info = get_user_info(openid) print info career_code = get_career_code(info['extattr']['attrs']) uname = '' unionid = '' # 检查用户是否已注册 #db_user = db.app_user .find_one({'openid':openid}) db_user = app_user_helper.get_user_info(openid, q_type='openid') if db_user == None: # 未注册,新建用户记录 new_set = { 'openid': openid, 'unionid': unionid, 'region_id': 'QY', # 增加 region_id 'type': 'wx_qy', # 用户类型 'address': [], #'coupon' : [], # 送优惠券 'app_id': '', # 微信先注册,没有app_id 'reg_time': app_helper.time_str(), 'wx_nickname': info.get('name', '未知'), 'wx_headimgurl': info.get('avatar', ''), 'career_code': career_code, # 教工号 'wx_info': info, 'refresh_headimg': REFRESH_HEADIMG, 'last_status': int(time.time()), } # 用户中心注册用户接口 app_user_helper.new_user_info(openid, 'openid', new_set) else: # 记录今天访问次数 last_date = db_user.get('last_visit_date') today_date = app_helper.time_str(format=1) # 格式 2016-01-01 if last_date != today_date: update_set = { 'last_visit_date': today_date, 'today_visit_count': 1, 'todat_visit_first_tick': int(time.time()), 'todat_push_image_text': 0, } else: update_set = { 'today_visit_count': db_user.get('today_visit_count', 0) + 1, } # 更新 region_id if db_user.get('region_id') != 'QY': update_set['region_id'] = 'QY' # 补充用户信息 update_set['wx_nickname'] = info.get('name', '未知') update_set['wx_headimgurl'] = info.get('avatar', '') update_set['career_code'] = career_code update_set['wx_info'] = info app_user_helper.update_user_info(openid, q_type='openid', update_set=update_set) # 生成 session ------------------ rand2 = app_helper.my_rand(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'openid': openid, 'unionid': unionid, 'ticket': '', 'uname': uname, 'login': 1, 'rand': rand2, 'ip': web.ctx.ip, 'attime': now, 'type': 'wx', 'career_code': career_code, }) print session_id, openid, uname, career_code print "session_id >>>>>>>>>> %r" % session_id return session_id
def user_forgot(param): number = param.mobile.strip() if len(number) < 11 or (not number.isdigit()): return json.dumps({'ret': -3, 'msg': '手机号码格式错误'}) if number in app_helper.BLOCK_LIST: return json.dumps({'ret': -3, 'msg': '手机号码错误'}) # 随机码 rand = app_helper.my_rand(base=1) register = False # 检查用户是否已注册 db_user = db.app_user.find_one({'uname': number}) if db_user == None: # 未注册,新建用户记录 return json.dumps({'ret': -5, 'msg': '手机号码未注册'}) else: # 更新app_id userid = db_user['userid'] db.app_user.update_one({'userid': db_user['userid']}, { '$set': { 'app_id': param.app_id, 'last_status': int(time.time()), } }) # 生成 session ------------------ rand2 = os.urandom(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'userid': userid, 'uname': number, 'login': 0, 'rand': rand, 'ip': web.ctx.ip, 'attime': now, 'type': 1, 'pwd_fail': 0, 'bind': 1, # 电话用户本身就认为是绑定的 }) # ------------------------------- #发送短信验证码 if number not in app_helper.INNER_NUM.keys( ): # 内部号码不发短信,2015-12-22, gt rr = sms.send_rand(number, rand, register) # 测试不发校验码 if rr is None: return json.dumps({'ret': -11, 'msg': '发送太频繁,稍后再试'}) # 返回 return json.dumps({ 'ret': 0, 'data': { 'session': session_id, } })
def POST(self): web.header('Content-Type', 'application/json') param = web.input(openid='', session_id='', pt_order_id='', order_id='', type='', total='') print param if '' in (param.total, param.type): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) if web.ctx.has_key('environ'): client_ip = web.ctx.environ['REMOTE_ADDR'] else: return json.dumps({'ret' : -5, 'msg' : '无法取得客户端ip地址'}) if param.openid=='' and param.session_id=='': return json.dumps({'ret' : -2, 'msg' : '参数错误1'}) # 同时支持openid和session_id if param.openid!='': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: db_shop = db.base_shop.find_one({'_id':ObjectId(setting.default_shop)},{'name':1}) db_session = db.app_sessions.find_one({'session_id':param.session_id},{'ticket':1}) ticket = db_session.get('ticket','') # 修改为付款的过期订单 r = db.order_app.update_many({ 'uname' : {'$in' : uname.values()}, 'status' : 'DUE', 'deadline' : {'$lt':int(time.time())} }, {'$set': {'status':'TIMEOUT'}}) # 统一下单接口获取 prepay_id nonce_str = app_helper.my_rand(30) body = 'U掌柜app' trade_type = 'JSAPI' if len(param.order_id)>0: #order_id = '%s_%d' % (param.order_id.encode('utf-8'), int(time.time())) order_id = param.order_id.encode('utf-8') else: # 生成order_id, 2015-10-29 order_id = app_helper.get_new_order_id('x').encode('utf-8') # 拼团订单 t 开头 if param.type=='TUAN': order_id = 't'+order_id[1:] total_fee = param.total.encode('utf-8') openid = uname['openid'].encode('utf-8') para = [ ('appid' , wx_appid), ('body' , body), ('mch_id' , mch_id), ('nonce_str' , nonce_str), ('notify_url' , notify_url), ('openid' , openid), ('out_trade_no' , order_id), ('spbill_create_ip' , client_ip), ('total_fee' , total_fee), ('trade_type' , trade_type) ] #print para stringA = '&'.join('%s=%s' % i for i in para) stringSignTemp = '%s&key=%s' % (stringA, api_key) sign = hashlib.md5(stringSignTemp).hexdigest().upper() para_xml = '<xml>' \ '<appid>'+wx_appid+'</appid>' \ '<mch_id>'+mch_id+'</mch_id>' \ '<nonce_str>'+nonce_str+'</nonce_str>' \ '<sign>'+sign+'</sign>' \ '<body>'+body+'</body>' \ '<out_trade_no>'+order_id+'</out_trade_no>' \ '<total_fee>'+total_fee+'</total_fee>' \ '<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \ '<notify_url>'+notify_url+'</notify_url>' \ '<trade_type>'+trade_type+'</trade_type>' \ '<openid>'+openid+'</openid>' \ '</xml>' print para_xml #return json.dumps({'ret' : 0, 'data' : 'here'}) urllib3.disable_warnings() pool = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' r = pool.urlopen('POST', url, body=para_xml) if r.status==200: data = r.data print data # 检查和生成订单 if len(param.order_id)>0: db_order = db.order_app.find_one({'order_id':param.order_id}) if db_order['status']!='DUE': print '============================== -100' return json.dumps({'ret' : -100, 'msg' : '订单状态变化,请确认'}) # 再次 checkout if param.type=='TUAN': ret_json = pt_checkout( uname, { 'region_id' : db_order['region_id'], 'addr_id' : db_order['address'][0], 'coupon_id' : db_order['coupon'][0] if float(db_order['coupon_disc'])>0 else '', 'cart' : json.dumps(db_order['cart']), 'pt_order_id' : db_order['pt_order_id'], }) if ret_json['ret']<0: # checkout 出错 return json.dumps({'ret' : ret_json['ret'], 'msg' : ret_json['msg']}) else: ret_json = checkout( uname, { 'shop_id' : str(db_order['shop']), 'addr_id' : db_order['address'][0], 'coupon_id' : db_order['coupon'][0] if float(db_order['coupon_disc'])>0 else '', 'cart' : json.dumps(db_order['cart']), 'order_id' : db_order['order_id'], }) if ret_json['ret']<0: # checkout 出错 return json.dumps({'ret' : ret_json['ret'], 'msg' : ret_json['msg']}) if float(ret_json['data']['due'])!=float(db_order['due']): # checkout后金额有变化,说明库存或优惠券有变化 db.order_app.update_one({'order_id':param.order_id},{ '$set' : {'status': 'CANCEL'}, '$push' : {'history':(app_helper.time_str(), uname['uname'], '订单取消(微信支付)')} }) print '============================== -100' return json.dumps({'ret' : -100, 'msg' : '很抱歉,数据异常,订单已取消,请重新下单'}) # 可支付 db.order_app.update_one({'order_id':param.order_id},{ '$set' : {'wx_out_trade_no':order_id}, '$push' : {'history':(app_helper.time_str(), uname['openid'], '提交微信支付2')} }) if param.type=='TUAN': # 拼团订单 return json.dumps({ 'ret' : 0, 'order_id' : param.order_id, 'pt_order_id' : db_order['pt_order_id'], 'position' : db_order['position'], 'data' : data, 'ticket' : ticket }) else: # 1小时订单 return json.dumps({ 'ret' : 0, 'order_id' : param.order_id, 'data' : data, 'ticket' : ticket }) else: # 生成新订单 db_cart = db.app_user.find_one({'openid':uname['openid']},{'cart_order_wx':1}) if param.type=='TUAN': # 拼团订单 if not db_cart.has_key('cart_order_wx'): print 'fail: 不该发生, 缺少购物车数据' return json.dumps({'ret' : -9, 'msg' : '系统错误,请重试!'}) new_order = dict(db_cart['cart_order_wx'][0]) new_order['order_id']=order_id new_order['status']='DUE' new_order['user_note']=param.note.strip() new_order['wx_out_trade_no']=order_id new_order['history']=[(app_helper.time_str(), uname['openid'], '提交微信支付')] # 如果是新开团,添加pt_order if len(db_cart['cart_order_wx'])>1: new_pt_order = dict(db_cart['cart_order_wx'][1]) new_pt_order['pt_order_id']='pt'+order_id[1:] new_pt_order['status']='WAIT' new_pt_order['history']=[(app_helper.time_str(), uname['openid'], '等待开团')] db.pt_order.insert_one(new_pt_order) # 订单数据里添加 pt_order_id new_order['pt_order_id']=new_pt_order['pt_order_id'] # 再次 checkout ret_json = pt_checkout( uname, { 'region_id' : new_order['region_id'], 'addr_id' : new_order['address'][0], 'coupon_id' : new_order['coupon'][0] if float(new_order['coupon_disc'])>0 else '', 'cart' : json.dumps(new_order['cart']), 'pt_order_id' : new_order['pt_order_id'], }) if ret_json['ret']<0: print 'checkout 检查未通过,不能支付' return json.dumps({'ret' : -9, 'msg' : ret_json['msg']}) db.order_app.insert_one(new_order) return json.dumps({ 'ret' : 0, 'order_id' : new_order['order_id'], 'pt_order_id' : new_order['pt_order_id'], 'position' : new_order['position'], # 测试 'data' : data, 'ticket' : ticket }) else: # 1小时订单 new_order = dict(db_cart['cart_order_wx']) new_order['order_id']=order_id new_order['status']='DUE' new_order['user_note']=param.note.strip() new_order['wx_out_trade_no']=order_id new_order['history']=[(app_helper.time_str(), uname['openid'], '提交微信支付')] # 再次 checkout ret_json = checkout( uname, { 'shop_id' : str(new_order['shop']), 'addr_id' : new_order['address'][0], 'coupon_id' : new_order['coupon'][0] if float(new_order['coupon_disc'])>0 else '', 'cart' : json.dumps(new_order['cart']), 'order_id' : new_order['order_id'], }) if ret_json['ret']<0: print 'checkout 检查未通过,不能支付' return json.dumps({'ret' : -9, 'msg' : ret_json['msg']}) if float(ret_json['data']['due'])!=float(new_order['due']): # checkout后金额有变化,说明库存或优惠券有变化 print '============================== -100' return json.dumps({'ret' : -100, 'msg' : '很抱歉,数据异常,请重新下单'}) db.order_app.insert_one(new_order) return json.dumps({ 'ret' : 0, 'order_id' : order_id, 'data' : data, 'ticket' : ticket }) else: return json.dumps({'ret' : -1, 'data' : r.status}) else: return json.dumps({'ret' : -4, 'msg' : '无效的openid'})
def init_job(code): if code == '': #return render.info('参数错误',goto='/') # info页面要做微信端优化 #raise web.seeother('/wx/init_fair') return None if code == 'test': openid = code else: urllib3.disable_warnings() http = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' \ 'appid=%s&' \ 'secret=%s&' \ 'code=%s&' \ 'grant_type=authorization_code' % \ (wx_appid, wx_secret, code, ) r = http.request('GET', url) if r.status == 200: data = r.data t = json.loads(data) #print t if t.has_key('openid'): openid = t['openid'] else: #return render.info('授权失败',goto='/') #raise web.seeother('/wx/init_fair') return None else: #raise web.seeother('/wx/init_fair') return None # 取得ticket ticket = get_ticket() if ticket == '': print 'get ticket fail!' #raise web.seeother('/wx/init_fair') #return None ticket = get_ticket(True) #session.login = 1 #session.uname = '' #session.openid = openid #session.privilege = helper.PRIV_WX uname = '' # 检查用户是否已注册 db_user = db.app_user.find_one({'openid': openid}) if db_user == None: # 未注册,新建用户记录 # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info coupon = [] valid = app_helper.time_str(time.time() + 3600 * 24 * 10, 1) # 有效期10天 2015-11-22 # 注册发抵用券 v3 for i in app_helper.reginster_coupon: coupon.append((app_helper.my_rand(), valid, '%.2f' % float(i[0]), 1, i[1], i[2])) db.app_user.insert_one({ 'openid': openid, 'address': [], 'coupon': coupon, # 送优惠券 'app_id': '', # 微信先注册,没有app_id 'reg_time': app_helper.time_str(), 'wx_nickname': info.get('nickname', '游客'), 'wx_headimgurl': info.get('headimgurl', ''), 'wx_info': info, }) else: if db_user.get('wx_headimgurl', '') == '': # 用户基本信息 info = get_info(openid) if info.has_key('errcode'): get_ticket(True) info = get_info(openid) print info # 补充微信用户信息 db.app_user.update_one({'openid': openid}, { '$set': { 'wx_nickname': info.get('nickname', '游客'), 'wx_headimgurl': info.get('headimgurl', ''), 'wx_info': info, } }) uname = db_user.get('uname', '') # 生成 session ------------------ import hashlib rand2 = app_helper.my_rand(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'openid': openid, 'ticket': ticket, 'uname': uname, 'login': 1, 'rand': rand2, 'ip': web.ctx.ip, 'attime': now, }) # 清理 session, 12小时前的微信session ---- 有隐患 #db.app_sessions.remove({'openid':{'$exists':True},'attime':{'$lt':(now-3600*12)}}) # 清理 session, 12小时前的未登录的session db.app_sessions.delete_many({ 'login': 0, 'attime': { '$lt': (now - 3600 * 12) } }) # 清理 session, 30天前的未使用的session db.app_sessions.delete_many({'attime': {'$lt': (now - 3600 * 24 * 30)}}) # ------------------------------- print session_id, openid, uname render = create_render(plain=True) #return render.fair(session_id, uname) #raise web.seeother('/static/wx/fair.html?session_id=%s' % session_id) return session_id
def user_reg(param): number = param.mobile.strip() if len(number) < 11 or (not number.isdigit()): return json.dumps({'ret': -10, 'msg': '手机号码格式错误'}) if number in app_helper.BLOCK_LIST: return json.dumps({'ret': -10, 'msg': '手机号码错误'}) # 随机码 rand = app_helper.my_rand(base=1) # 检查用户是否已注册 db_user = db.app_user.find_one({'uname': number}) if db_user == None: # 未注册,新建用户记录 userid = app_helper.gen_new_userid() new_set = { 'userid': userid, # 用户id,用于唯一标识 'uname': number, 'type': 1, # 1 电话号码用户, 2 微信app登录用户, 3 微信公众号用户 'bind': 1, # 1 已绑定, 0 未绑定, 电话用户本身就认为是绑定的 'mice': 0, # 1 正常用户, 0 黑名单用户 'app_id': param.app_id, 'reg_time': app_helper.time_str(), 'last_status': int(time.time()), 'reg_ok': 0, } # 用户中心注册用户接口 db.app_user.update_one({'userid': userid}, {'$set': new_set}, upsert=True) else: # 更新app_id #userid = db_user['userid'] #db.app_user.update_one({'userid':db_user['userid']},{'$set':{ # 'app_id' : param.app_id, # 'last_status' : int(time.time()), #}}) if db_user.get('reg_ok') == 1: return json.dumps({'ret': -6, 'msg': '手机号码已注册'}) userid = db_user['userid'] # 生成 session ------------------ rand2 = os.urandom(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'userid': userid, 'uname': number, 'login': 0, 'rand': rand, 'ip': web.ctx.ip, 'attime': now, 'type': 1, 'pwd_fail': 0, 'bind': 1, # 电话用户本身就认为是绑定的 }) # ------------------------------- #发送短信验证码 if number not in app_helper.INNER_NUM.keys( ): # 内部号码不发短信,2015-12-22, gt rr = sms.send_rand(number, rand, True) # 测试不发校验码 if rr is None: return json.dumps({'ret': -11, 'msg': '发送太频繁,稍后再试'}) # 返回 return json.dumps({ 'ret': 0, 'data': { 'session': session_id, } })
def POST(self, version='v1'): web.header('Content-Type', 'application/json') #print web.input() param = web.input(app_id='', session='', rand='', invitation='', sign='') if '' in (param.app_id, param.session, param.rand, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) #验证签名 md5_str = app_helper.generate_sign( [param.app_id, param.session, param.rand, param.invitation]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) session = app_helper.get_session(param.session) if session == None: return json.dumps({'ret': -4, 'msg': '无效的session'}) if param.rand.strip() != session['rand']: if session['uname'] == '18516569412' and param.rand.strip( ) == '9998': None elif session['uname'] in setting.inner_number.keys() and \ param.rand.strip()==setting.inner_number[session['uname']]: None else: return json.dumps({'ret': -5, 'msg': '短信验证码错误'}) db.app_sessions.update_one( {'session_id': session['session_id']}, {'$set': { 'login': 1, 'attime': time.time(), }}) #邀请码 if param.has_key('invitation'): invitation = param.invitation.lower() if db.invitation.find({ 'code': invitation }).count() == 0: # 无效地推邀请码 if db.app_user.find({ 'my_invit_code': invitation }).count() == 0: # 无效用户邀请码 invitation = '' if invitation != '': r = db.app_user.find_one({'uname': session['uname']}, {'invitation': 1}) if r.get('invitation', '') != '': # 已填邀请码 invitation = '' else: invitation = '' invitation_coupon = 0 if invitation != '': # 赠送优惠券 invitation_coupon = 1 valid = app_helper.time_str(time.time() + 3600 * 24 * 10, 1) # 有效期10天 r = db.app_user.find_one_and_update( {'uname': session['uname']}, { '$set': { 'invitation': invitation, 'last_time': app_helper.time_str() }, '$push': { 'coupon': (app_helper.my_rand(), valid, '5.00', 1, 14.9, 'apple') }, # 邀请码送5+4+3 }, { 'address': 1, 'new_coupon': 1 }) db.app_user.update_one({'uname' : session['uname']},{ # 4元 '$push' : {'coupon' : (app_helper.my_rand(), valid, '4.00', 1, 24.9, 'apple')}, }) db.app_user.update_one({'uname' : session['uname']},{ # 3元 '$push' : {'coupon' : (app_helper.my_rand(), valid, '3.00', 1, 19.9, 'apple')}, }) else: r = db.app_user.find_one_and_update( {'uname': session['uname']}, {'$set': { 'last_time': app_helper.time_str() }}, { 'address': 1, 'new_coupon': 1 }) if len(r['address']) > 0: # 应该实现:返回最近使用的地址 !!!! addr = { 'id': r['address'][0][0], 'name': r['address'][0][1], 'tel': r['address'][0][2], 'addr': r['address'][0][3], } else: addr = {} # 检查是否有新红包 app_helper.check_hb(session['uname']) # 返回 if version == 'v3': # 是否有新收到的抵用券,进行提示 if r.has_key('new_coupon') and r['new_coupon'] > 0: alert = True message = '掌柜送您%d张抵用券,请在个人中心查看哦' % (r['new_coupon'] + invitation_coupon) db.app_user.update_one({'uname': session['uname']}, {'$set': { 'new_coupon': 0 }}) else: alert = False message = '' return json.dumps({ 'ret': 0, 'data': { 'session': session['session_id'], 'login': True, 'addr': addr, 'uname': session['uname'], 'alert': alert, 'message': message } }) else: # v1,v2 return json.dumps({ 'ret': 0, 'data': { 'session': session['session_id'], 'login': True, 'addr': addr, 'uname': session['uname'], } })
def POST(self, version='v1'): web.header('Content-Type', 'application/json') #print web.input() param = web.input(app_id='', number='', secret='') if '' in (param.app_id, param.number, param.secret, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) #验证签名 md5_str = app_helper.generate_sign( [param.app_id, param.number, param.secret]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) number = param.number.strip() if len(number) < 11 or (not number.isdigit()): return json.dumps({'ret': -5, 'msg': '手机号码格式错误'}) # 随机码 rand = app_helper.my_rand(base=1) register = False openid = '' # 检查用户是否已注册 db_user = db.app_user.find_one({'uname': number}) if db_user == None: # 未注册,新建用户记录 coupon = [] valid = app_helper.time_str(time.time() + 3600 * 24 * 10, 1) # 有效期10天 2015-11-20 # 注册发抵用券 for i in app_helper.reginster_coupon: coupon.append((app_helper.my_rand(), valid, '%.2f' % float(i[0]), 1, i[1], i[2])) db.app_user.insert_one({ 'uname': number, 'address': [], 'coupon': coupon, # 送优惠券 'app_id': param.app_id, 'reg_time': app_helper.time_str(), }) register = True else: openid = db_user.get('openid', '') # 更新app_id db.app_user.update_one({'uname': number}, {'$set': { 'app_id': param.app_id }}) # 生成 session rand2 = os.urandom(16) now = time.time() secret_key = 'f6102bff8451236b8ca1' session_id = hashlib.sha1( "%s%s%s%s" % (rand2, now, web.ctx.ip.encode('utf-8'), secret_key)) session_id = session_id.hexdigest() db.app_sessions.insert_one({ 'session_id': session_id, 'uname': number, 'openid': openid, 'login': 0, 'rand': rand, 'ip': web.ctx.ip, 'attime': now, }) #发送短信验证码 if number not in setting.inner_number.keys(): sms.send_rand(number, rand, register) # 返回 return json.dumps({ 'ret': 0, 'data': { 'session': session_id, 'register': register, } })
def POST(self): web.header('Content-Type', 'application/json') param = web.input(openid='', session_id='', name='', tel='', addr='', city='') if '' in (param.name, param.tel, param.addr, param.city): return json.dumps({'ret': -2, 'msg': '参数错误'}) if param.openid == '' and param.session_id == '': return json.dumps({'ret': -2, 'msg': '参数错误1'}) # 同时支持openid和session_id if param.openid != '': uname = app_helper.check_openid(param.openid) else: uname = app_helper.wx_logged(param.session_id) if uname: # 判断地址是否有对应门店,否则不在送货范围内 alert = False sort_tick = int(time.time()) message = '' # 获得 收货地址 坐标, 设置城市, v3 ret, loc = lbs.addr_to_loc(param.addr.strip().encode('utf-8'), city=param.city.strip().encode('utf-8')) print ret, loc if ret < 0: loc = {'lat': 0, 'lng': 0} alert = False #True message = '地址定位失败,请重新输入地址' sort_tick = 0 else: poly_shop, loc_shop = lbs.locate_shop((loc['lat'], loc['lng'])) if poly_shop == None: print '不在配送范围内' alert = False # True # 拼团不提示 message = '很抱歉,收货地址不在配送范围内,请更改地址' #,整箱预售商品可正常购买' sort_tick = 0 # 更新个人资料 new_addr = ( app_helper.my_rand(), param.name.strip(), param.tel.strip(), param.addr.strip(), sort_tick, loc, '', # app 的title '', # app 的detail param.city.strip(), ) r = db.app_user.update_one({'openid': uname['openid']}, {'$push': { 'address': new_addr }}) # 返回 return json.dumps({ 'ret': 0, 'data': { 'addr_id': new_addr[0], 'alert': alert, 'message': message, } }) else: return json.dumps({'ret': -4, 'msg': '无效的openid'})
def POST(self, version='v2'): web.header('Content-Type', 'application/json') if version not in ('v2', 'v3'): return json.dumps({'ret': -999, 'msg': '版本错误!'}) print 'version=', version param = web.input(app_id='', session='', order_id='', total='', note='', sign='') if version == 'v2': if '' in (param.app_id, param.order_id, param.session, param.total, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) elif version == 'v3': if '' in (param.app_id, param.session, param.total, param.sign): return json.dumps({'ret': -2, 'msg': '参数错误'}) if web.ctx.has_key('environ'): client_ip = web.ctx.environ['REMOTE_ADDR'] else: return json.dumps({'ret': -5, 'msg': '无法取得客户端ip地址'}) uname = app_helper.app_logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign([ param.app_id, param.session, param.order_id, param.total, param.note ]) if md5_str != param.sign: return json.dumps({'ret': -1, 'msg': '签名验证错误'}) #db_shop = db.base_shop.find_one({'_id':ObjectId(setting.default_shop)},{'name':1}) # 统一下单接口获取 prepay_id nonce_str = app_helper.my_rand(30) body = 'U掌柜app' trade_type = 'APP' if version == 'v2': order_id = '%s_%d' % (param.order_id.encode('utf-8'), int(time.time())) elif version == 'v3': if len(param.order_id) > 0: order_id = '%s_%d' % (param.order_id.encode('utf-8'), int(time.time())) print order_id else: # 生成order_id order_id = app_helper.get_new_order_id(version).encode( 'utf-8') print 'new order_id', order_id total_fee = param.total.encode('utf-8') para = [('appid', wx_appid), ('body', body), ('mch_id', mch_id), ('nonce_str', nonce_str), ('notify_url', notify_url), ('out_trade_no', order_id), ('spbill_create_ip', client_ip), ('total_fee', total_fee), ('trade_type', trade_type)] print para stringA = '&'.join('%s=%s' % i for i in para) stringSignTemp = '%s&key=%s' % (stringA, api_key) sign = hashlib.md5(stringSignTemp).hexdigest().upper() para_xml = '<xml>' \ '<appid>'+wx_appid+'</appid>' \ '<mch_id>'+mch_id+'</mch_id>' \ '<nonce_str>'+nonce_str+'</nonce_str>' \ '<sign>'+sign+'</sign>' \ '<body>'+body+'</body>' \ '<out_trade_no>'+order_id+'</out_trade_no>' \ '<total_fee>'+total_fee+'</total_fee>' \ '<spbill_create_ip>'+client_ip+'</spbill_create_ip>' \ '<notify_url>'+notify_url+'</notify_url>' \ '<trade_type>'+trade_type+'</trade_type>' \ '</xml>' print para_xml #return json.dumps({'ret' : 0, 'data' : 'here'}) urllib3.disable_warnings() pool = urllib3.PoolManager(num_pools=2, timeout=180, retries=False) url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' r = pool.urlopen('POST', url, body=para_xml) if r.status == 200: data = r.data print data if version == 'v2': # 记录微信商户订单号 db.order_app.update_one( {'order_id': param.order_id}, {'$set': { 'wx_out_trade_no': order_id }}) return json.dumps({'ret': 0, 'data': data}) elif version == 'v3': if len(param.order_id) > 0: db_order = db.order_app.find_one( {'order_id': param.order_id}) if db_order['status'] != 'DUE': print '============================== -100' return json.dumps({ 'ret': -100, 'msg': '订单状态变化,请确认' }) ret_json = checkout( version, uname, { 'session': param.session, 'order_id': param.order_id, 'shop_id': str(db_order['shop']), 'addr_id': db_order['address'][0], 'coupon_id': db_order['coupon'][0] if float(db_order['coupon_disc']) > 0 else '', 'cart': json.dumps(db_order['cart']), 'app_id': param.app_id, 'use_credit': '1' if float(db_order.get('use_credit', '0')) > 0 else '', #2015-11-19 }) if ret_json['ret'] < 0: # checkout 出错 return json.dumps({ 'ret': ret_json['ret'], 'msg': ret_json['msg'] }) if float(ret_json['data']['due']) != float( db_order.get('due3', db_order['due'])): # checkout后金额有变化,说明库存或优惠券有变化 db.order_app.update_one( {'order_id': param.order_id}, { '$set': { 'status': 'CANCEL' }, '$push': { 'history': (app_helper.time_str(), uname['uname'], '订单取消(微信支付)') } }) print '============================== -100' return json.dumps({ 'ret': -100, 'msg': '很抱歉,数据异常,订单已取消,请重新下单' }) # 可支付 db.order_app.update_one({'order_id': param.order_id}, { '$set': { 'wx_out_trade_no': order_id }, '$push': { 'history': (app_helper.time_str(), uname['uname'], '提交微信支付2') } }) return json.dumps({ 'ret': 0, 'order_id': param.order_id, 'data': data }) else: # 生成新订单 db_cart = db.app_user.find_one( {'uname': uname['uname']}, {'cart_order.%s' % param.session: 1}) new_order = dict(db_cart['cart_order'][param.session]) new_order['order_id'] = order_id new_order['status'] = 'DUE' new_order['user_note'] = param.note.strip() new_order['wx_out_trade_no'] = order_id new_order['history'] = [(app_helper.time_str(), uname['uname'], '提交微信支付')] ret_json = checkout( version, uname, { 'session': param.session, 'order_id': order_id, 'shop_id': str(new_order['shop']), 'addr_id': new_order['address'][0], 'coupon_id': new_order['coupon'][0] if float(new_order['coupon_disc']) > 0 else '', 'cart': json.dumps(new_order['cart']), 'app_id': param.app_id, 'use_credit': '1' if float(new_order.get('use_credit', '0')) > 0 else '', #2015-11-23 }) if ret_json['ret'] < 0: # checkout 出错 return json.dumps({ 'ret': ret_json['ret'], 'msg': ret_json['msg'] }) if float(ret_json['data']['due']) != float( new_order.get('due3', new_order['due'])): # checkout后金额有变化,说明库存或优惠券有变化 print '============================== -100' return json.dumps({ 'ret': -100, 'msg': '很抱歉,数据异常,请重新下单' }) db.order_app.insert_one(new_order) return json.dumps({ 'ret': 0, 'order_id': order_id, 'data': data }) else: return json.dumps({'ret': -1, 'data': r.status}) else: return json.dumps({'ret': -4, 'msg': '无效的session'})
def POST(self, version='v2'): web.header('Content-Type', 'application/json') if version not in ('v2','v3'): return json.dumps({'ret' : -999, 'msg' : '版本错误!'}) print 'version=',version param = web.input(app_id='',session='',name='',tel='',addr='',title='',detail='',city='',loc='',sign='') if '' in (param.app_id, param.session, param.name, param.tel, param.addr, param.sign): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) # v3 参数检查 if version=='v3' and '' in (param.title, param.detail, param.city, param.loc): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) uname = app_helper.app_logged(param.session) # 检查session登录 if uname: #验证签名 if version=='v2': md5_str = app_helper.generate_sign([param.app_id, param.session, param.name, param.tel, param.addr]) elif version=='v3': md5_str = app_helper.generate_sign([param.app_id, param.session, param.name, param.tel, param.addr, param.title, param.detail, param.city, param.loc]) if md5_str!=param.sign: return json.dumps({'ret' : -1, 'msg' : '签名验证错误'}) # 判断地址是否有对应门店,否则不在送货范围内 alert = False message = '' if version=='v2': # 获得 收货地址 坐标 ret, loc = lbs.addr_to_loc(param.addr.strip().encode('utf-8')) print ret, loc if ret<0: loc = {'lat': 0, 'lng': 0} alert = True message = '地址定位失败,请重新输入地址' else: poly_shop, loc_shop = lbs.locate_shop((loc['lat'],loc['lng'])) if poly_shop==None: print '不在配送范围内' alert = True message = '很抱歉,收货地址不在配送范围内,请更改地址' #,整箱预售商品可正常购买' # 更新个人资料 new_addr = ( app_helper.my_rand(), param.name.strip(), param.tel.strip(), param.addr.strip(), int(time.time()), loc, ) elif version=='v3': # 使用提示地址的坐标进行匹配 loc0 = param.loc.split(',') # 31.20474193,121.620708272 if len(loc0)<2 or '' in loc0: loc = {'lat': 0, 'lng': 0} alert = True message = '地址定位失败,请重新输入地址' else: loc = {'lat' : float(loc0[0]), 'lng' : float(loc0[1])} print loc poly_shop, loc_shop = lbs.locate_shop((loc['lat'],loc['lng'])) if poly_shop==None: print '不在配送范围内' alert = True message = '很抱歉,收货地址不在配送范围内,请更改地址' #,整箱预售商品可正常购买' # 更新个人资料 new_addr = ( app_helper.my_rand(), param.name.strip(), param.tel.strip(), param.addr.strip(), int(time.time()), loc, param.title.strip(), param.detail.strip(), param.city.strip(), ) r = db.app_user.update_one({'uname':uname['uname']}, {'$push' : {'address' : new_addr}}) # 返回 return json.dumps({'ret' : 0, 'data' : { 'addr_id' : new_addr[0], 'alert' : alert, 'message' : message, }}) else: return json.dumps({'ret' : -4, 'msg' : '无效的session'})
def POST(self, version='v2'): web.header('Content-Type', 'application/json') if version not in ('v2','v3'): return json.dumps({'ret' : -999, 'msg' : '版本错误!'}) print 'version=',version param = web.input(app_id='', session='', order_id='', pay_type='', data='', sign='') print param if '' in (param.app_id, param.session, param.order_id, param.pay_type, param.sign): return json.dumps({'ret' : -2, 'msg' : '参数错误'}) uname = app_helper.app_logged(param.session) # 检查session登录 if uname: #验证签名 md5_str = app_helper.generate_sign([param.app_id, param.session, param.order_id, param.pay_type, param.data]) if md5_str!=param.sign: return json.dumps({'ret' : -1, 'msg' : '签名验证错误'}) db_user = db.app_user.find_one({'uname':uname['uname']},{'coupon':1, 'credit':1}) if db_user==None: # 不应该发生 return json.dumps({'ret' : -5, 'msg' : '未找到用户信息'}) # 支付操作:1,记录订单支付,2.改变订单状态,3.修改库存显示 !!!!!! # 获得订单 db_order = db.order_app.find_one( {'order_id' : param.order_id}, #{'status':1, 'cart':1, 'due':1, 'shop':1} ) if db_order==None: return json.dumps({'ret' : -3, 'msg' : '未找到订单!'}) # 支付宝和微信支付订单,已PAID说明提前收到异步通知 if db_order['status']=='PAID' and param.pay_type in ('ALIPAY','WXPAY'): # 记录此次调用 db.order_app.update_one( { 'order_id' : param.order_id, }, { '$set' : { 'pay_type' : param.pay_type, 'pay' : db_order.get('due3', db_order['due']), 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '提交付款')}, } ) return json.dumps({'ret' : 0, 'data' : { 'order_id' : param.order_id, 'due' : db_order.get('due3', db_order['due']), 'paid' : db_order.get('due3', db_order['due']), 'status' : '已支付', 'alert' : False, 'message' : '测试信息, 已经收到异步通知了', 'url' : 'http://app-test.urfresh.cn' }}) # 只能处理未支付订单 if db_order['status']!='DUE': return json.dumps({'ret' : -3, 'msg' : '不是待付款订单!'}) # 余额支付和支付宝/微信支付未到账处理 if param.pay_type=='CREDIT': # 余额支付0元提交的问题,原因未知 2015.08.20 if round(float(db_order['due']),2)<=0.0: return json.dumps({'ret' : -2, 'msg' : '参数错误'}) # 检查余额是否够支付 if float(db_order['due'])>db_user.get('credit',0.0): return json.dumps({'ret' : -6, 'msg' : '余额不足!'}) # 使用的优惠券失效 #db_user = db.app_user.find_one({'uname':r['uname']}) coupon = [] if db_order['coupon']!=None: for i in db_user['coupon']: if i[0]==db_order['coupon'][0]: # 这次使用 #coupon.append((i[0],i[1],i[2],0)) i2=list(i) i2[3]=0 coupon.append(i2) else: coupon.append(i) else: coupon = db_user['coupon'] # 未处理首单送券的逻辑 # 更新优惠券 db.app_user.update_one({'uname':db_order['uname']}, {'$set':{'coupon':coupon}}) # 邀请码用户送抵用券 2015-10-24 invitation = db_user.get('invitation', '') if invitation!='' and db_user.get('invite_coupon_has_sent', 0)==0: # 已填邀请码并且未送过券 coupon_user = db.app_user.find_one({'my_invit_code':invitation},{'uname':1}) if coupon_user: # 送邀请码用户抵用券 print '送邀请码用户抵用券' valid = app_helper.time_str(time.time()+3600*24*30, 1) db.app_user.update_one({'uname':coupon_user['uname']},{'$push':{ 'coupon' : (app_helper.my_rand(), valid, '5.00', 1, 19.9, 'apple') }}) # 设置已送标志 db.app_user.update_one({'uname':r['uname']}, {'$set':{'invite_coupon_has_sent':1}}) # 正常减库存! # item = [ product_id, num, num2, price] # k - num 库存数量 print "修改库存." b2 = [] # C端商品 b3 = [] # B3整箱预售商品 b3_total = 0.0 for item in db_order['cart']: # 记录销售量 db.sku_store.update_one({'product_id' : item['product_id']}, {'$inc' : {'volume' : float(item['num2'])}} ) #r3 = db.sku_store.find_one({'product_id' : item['product_id']}, # {'list_in_app':1}) #if r3['list_in_app']==3: # B3商品不需要改库存 # b3_total += float(item['price']) # b3.append(item) # item['title'] = item['title']+u'(整箱预售,次日送达)' # b2.append(item) # continue # 买一送一 if item.has_key('numyy'): # v3 2015-10-25 if item['product_id'] in app_helper.buy_X_give_Y.keys(): print '买X送Y' #item['num2'] = int(float(item['num2']) + float(item['numyy'])) #item['title'] = item['title'] + u'特惠活动' else: if item['product_id'] in app_helper.buy_1_give_1: print '买一送一' lc_num2 = float(item['num2']) item['num2'] = int(lc_num2 + lc_num2) item['title'] = item['title'].replace(u'买一送一',u'特惠活动') # 过滤数量价格为零的 if item['num2']==0 and float(item['price'])==0.0: continue # num2 实际购买数量, numyy 赠送数量, v3之后才有munyy 2015-10-20 num_to_change = float(item['num2']) + float(item.get('numyy', 0.0)) r = db.inventory.find_one_and_update( # 不检查库存,有可能负库存 { 'product_id' : item['product_id'], 'shop' : db_order['shop'], }, { '$inc' : { 'num' : 0-num_to_change, # num2 实际购买数量 'pre_pay_num' : num_to_change, # 记录预付数量 } #'$push' : { 'history' : (helper.time_str(), # helper.get_session_uname(), '售出 %s' % str(item['num']))}, }, {'_id':1} ) #print r if r==None: # 不应该发生 return json.dumps({'ret' : -9, 'msg' : '修改库存失败,请联系管理员!'}) else: b2.append(item) # 更新第3方库存 2015-10-10 app_helper.elm_modify_num(db_order['shop'], item['product_id']) # 检查是否有b3商品, 3种情况 # 1. b2, b3 都有,拆单 # 2. 只有b3,站点改为B3站点,保留收货站点 # 3. 只有b2,保持订单不变 #print b2 #print b3 if len(b3)>0 and (len(b2)-len(b3))>0: # 情况1 print "拆单" r4 = db_order.copy() r4['order_id'] = r4['order_id']+u'-b3' r4['shop_0'] = db_order['shop'] r4['shop'] = ObjectId(setting.B3_shop) r4['cart'] = b3 r4['status'] = 'PAID' r4['ali_trade_no'] = param.get('trade_no') r4['paid_time'] = param.get('gmt_payment') r4['paid_tick'] = int(time.time()) r4['history'] = [(app_helper.time_str(), 'credit', '余额付款-拆单')] r4['total'] = '%.2f' % b3_total r4['cost'] = '0.00' r4['coupon_disc'] = '0.00' r4['first_disc'] = '0.00' r4['delivery_fee'] = '0.00' r4['due'] = '0.00' db.order_app.insert_one(r4) # 增加子订单 elif len(b3)>0: # 情况 2 print "订单改到B3站点" # 如果订单地址不再配送范围,则由b3直接发出, 2015-10-18 if db_order.get('poly_shop', 1)==1: # 默认到店配送 print 'b3配送到店' shop_0 = db_order['shop'] else: print 'b3直接发货' shop_0 = ObjectId(setting.B3_shop) db.order_app.update_one({'order_id':param.order_id},{'$set' : { 'shop_0' : shop_0, 'shop' : ObjectId(setting.B3_shop), }}) else: # 情况3,什么都不做 print "订单保持不变" # 推送通知 #if len(db_order['uname'])==11 and db_order['uname'][0]=='1': # jpush.jpush('已收到您的付款,我们会尽快处理。', db_order['uname']) # 更新销货单信息 db.order_app.update_one({'order_id' : param.order_id},{ '$set' : { 'status' : 'PAID', 'cart' : b2, # 更新购物车 2015-09-11 'pay_type' : param.pay_type, 'pay' : db_order['due'], 'paid_time' : app_helper.time_str(), 'paid_tick' : int(time.time()), 'credit_total' : db_order['due'], # 2015-11-24 }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '余额付款')}, }) # 消费余额 db.app_user.update_one({'uname' : uname['uname'],},{ '$inc' : { 'credit' : 0-float(db_order['due']), }, '$push' : { 'credit_history' : ( # 专门记录余额消费 app_helper.time_str(), '消费余额', '-%.2f' % float(db_order['due'].encode('utf-8')), '订单: %s' % param.order_id.encode('utf-8') ) }, }) elif param.pay_type in ('ALIPAY', 'WXPAY'): # 更新销货单信息, r = db.order_app.find_one_and_update( { 'order_id' : param.order_id, 'status' : 'DUE' }, { '$set' : { 'status' : 'PREPAID', 'pay_type' : param.pay_type, 'pay' : db_order.get('due3', db_order['due']), 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), 'pay_data' : param.data, }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '提交付款')}, }, {'status':1} ) # 如果不是DUE,说明已收到异步通知 if r==None: db.order_app.update_one( { 'order_id' : param.order_id, }, { '$set' : { 'pay_type' : param.pay_type, 'pay' : db_order.get('due3', db_order['due']), 'paid2_time' : app_helper.time_str(), 'paid2_tick' : int(time.time()), }, '$push' : { 'history' : (app_helper.time_str(), uname['uname'], '提交付款')}, } ) # 返回 return json.dumps({'ret' : 0, 'data' : { 'order_id' : param.order_id, 'due' : db_order.get('due3', db_order['due']), 'paid' : db_order.get('due3', db_order['due']), 'status' : '已支付', 'alert' : False, 'message' : '测试信息,还未收到异步通知', 'url' : 'http://app-test.urfresh.cn' }}) else: return json.dumps({'ret' : -4, 'msg' : '无效的session'})
def POST(self, version='v1'): param = web.input() print param if check_sign_alipay(param): print "ALIPAY SIGNATURE CHECK SUCCESS!" else: print "ALIPAY SIGNATURE CHECK FAIL ......!" return 'fail' order_id = param.get('out_trade_no','') if param.get('refund_status') == 'REFUND_SUCCESS': # 有退款 db.order_app.update_one({'order_id':order_id},{ '$set' : { 'status' : 'REFUND', 'refund_time' : param.get('gmt_refund'), 'refund_tick' : int(time.time()), }, '$push' : { 'ali_notify': param, 'history' : (app_helper.time_str(), 'alipy', '退款通知') } }) elif param.get('trade_status') == 'TRADE_SUCCESS': # 有付款 r = db.order_app.find_one({'order_id':order_id}, #{'due':1, 'uname':1, 'coupon':1, 'shop':1, 'cart':1, 'status':1}) {'_id':0}) if r: status = 'PAID' #if float(r['due'])<=float(param.get('total_fee','0')): # 检查支付金额与应付是否一致 # status = 'PAID' #else: # status = 'PARTIAL_PAID' print r['status'] db_user = db.app_user.find_one({'$or' : [ {'uname':r['uname']},{'openid':r['uname']} # 2015-08-22 ]}) if r['status'] in ['DUE', 'PREPAID', 'TIMEOUT']: # 如果状态已是PAID,说明有重复通知,不减库存 # 消费余额 if float(r.get('use_credit', '0'))>0: print db_user['credit'],float(r['use_credit']) if db_user['credit']>=float(r['use_credit']): # 余额够用 db.app_user.update_one({'$or' : [ {'uname':r['uname']},{'openid':r['uname']} # 2015-08-22 ]},{ '$inc' : { 'credit' : 0-float(r['use_credit']), }, '$push' : { 'credit_history' : ( # 专门记录余额消费 app_helper.time_str(), '消费余额', '-%.2f' % float(r['use_credit']), '订单: %s' % order_id.encode('utf-8') ) }, }) else: # 余额不够用 # 修改订单状态 db.order_app.update_one({'order_id':order_id},{ '$set' : { 'status' : 'CANCEL_TO_REFUND', #'sum_to_refund' : r['due'], # 没有 sum_to_refund 表示全额退 'use_credit' : '0.00', # 清除余额支付,防止多退款 'use_credit_old': r['use_credit'], # 保存应收余额支付金额 #'cart' : b2, # 更新购物车 2015-09-11 'ali_trade_no' : param.get('trade_no'), 'paid_time' : param.get('gmt_payment'), 'paid_tick' : int(time.time()), 'pay_type' : 'ALIPAY', }, '$push' : { 'ali_notify': param, 'history' : (app_helper.time_str(), 'alipay', '付款通知:余额不足转入退款') } }) return 'success' # 使用的优惠券失效 coupon = [] if r['coupon']!=None: for i in db_user['coupon']: if i[0]==r['coupon'][0]: # 这次使用 i2=list(i) i2[3]=0 coupon.append(i2) else: coupon.append(i) else: coupon = db_user['coupon'] # 满30送5元抵用券 #if float(param.get('total_fee','0'))>=30: # valid = app_helper.time_str(time.time()+3600*24*30, 1) # coupon.append((app_helper.my_rand(), valid, '5.00', 1)) # 首单送抵用券 #if db.order_app.find({'user':r['uname'],'status':{'$nin':['TIMEOUT','DUE','CANCEL']},'order_id':{'$ne':order_id}},{'_id':1}).count()==0: # # (id, 有效期, 金额, 是否已用, 门槛) 2015-09-27 # valid = app_helper.time_str(time.time()+3600*24*30, 1) # if str(r['shop']) in app_helper.new_coupon2_shop: # print '首单送优惠券(指定店)' # for i in app_helper.new_coupon2: # coupon.append((app_helper.my_rand(), valid, '%.2f' % float(i[0]), 1, i[1], i[2])) # else: # print '首单送优惠券' # for i in app_helper.new_coupon: # coupon.append((app_helper.my_rand(), valid, '%.2f' % float(i[0]), 1, i[1], i[2])) # 更新优惠券 db.app_user.update_one({'uname':r['uname']}, {'$set':{'coupon':coupon}}) # 邀请码用户送抵用券 2015-10-24 invitation = db_user.get('invitation', '') if invitation!='' and db_user.get('invite_coupon_has_sent', 0)==0: # 已填邀请码并且未送过券 coupon_user = db.app_user.find_one({'my_invit_code':invitation},{'uname':1}) if coupon_user: # 送邀请码用户抵用券 print '送邀请码用户抵用券' valid = app_helper.time_str(time.time()+3600*24*30, 1) db.app_user.update_one({'uname':coupon_user['uname']},{'$push':{ 'coupon' : (app_helper.my_rand(), valid, '5.00', 1, 19.9, 'apple') }}) # 设置已送标志 db.app_user.update_one({'uname':r['uname']}, {'$set':{'invite_coupon_has_sent':1}}) # 正常减库存! # item = [ product_id, num, num2, price] # k - num 库存数量 print "修改库存." b2 = [] # C端商品 b3 = [] # B3整箱预售商品 b3_total = 0.0 for item in r['cart']: # 记录销售量 db.sku_store.update_one({'product_id' : item['product_id']}, {'$inc' : {'volume' : float(item['num2'])}} ) # 暂停整箱预售 2015-10-27 #r3 = db.sku_store.find_one({'product_id' : item['product_id']}, # {'list_in_app':1}) #if r3['list_in_app']==3: # B3商品不需要改库存 # b3_total += float(item['price']) # b3.append(item) # item['title'] = item['title']+u'(整箱预售,次日送达)' # b2.append(item) # continue # 买一送一 if item.has_key('numyy'): # v3 2015-10-25 if item['product_id'] in app_helper.buy_X_give_Y.keys(): print '买X送Y' #item['num2'] = int(float(item['num2']) + float(item['numyy'])) #item['title'] = item['title'] + u'特惠活动' else: if item['product_id'] in app_helper.buy_1_give_1: print '买一送一' lc_num2 = float(item['num2']) item['num2'] = int(lc_num2 + lc_num2) item['title'] = item['title'].replace(u'买一送一',u'特惠活动') # 过滤数量价格为零的 if item['num2']==0 and float(item['price'])==0.0: continue # num2 实际购买数量, numyy 赠送数量, v3之后才有munyy 2015-10-20 num_to_change = float(item['num2']) + float(item.get('numyy', 0.0)) r2 = db.inventory.find_one_and_update( # 不检查库存,有可能负库存 { 'product_id' : item['product_id'], 'shop' : r['shop'], }, { '$inc' : { 'num' : 0-num_to_change, 'pre_pay_num' : num_to_change, # 记录预付数量 } #'$push' : { 'history' : (helper.time_str(), # helper.get_session_uname(), '售出 %s' % str(item['num']))}, }, {'_id':1} ) #print r if r2==None: # 不应该发生 return json.dumps({'ret' : -9, 'msg' : '修改库存失败,请联系管理员!'}) else: b2.append(item) # 更新第3方库存 2015-10-10 app_helper.elm_modify_num(r['shop'], item['product_id']) # 检查是否有b3商品, 3种情况 # 1. b2, b3 都有,拆单 # 2. 只有b3,站点改为B3站点,保留收货站点 # 3. 只有b2,保持订单不变 #print b2 #print b3 if len(b3)>0 and (len(b2)-len(b3))>0: # 情况1 print "拆单" r4 = r.copy() r4['order_id'] = r4['order_id']+u'-b3' r4['shop_0'] = r['shop'] r4['shop'] = ObjectId(setting.B3_shop) r4['cart'] = b3 r4['status'] = status r4['ali_trade_no'] = param.get('trade_no') r4['paid_time'] = param.get('gmt_payment') r4['paid_tick'] = int(time.time()) r4['history'] = [(app_helper.time_str(), 'alipay', '付款通知-拆单')] r4['total'] = '%.2f' % b3_total r4['cost'] = '0.00' r4['coupon_disc'] = '0.00' r4['first_disc'] = '0.00' r4['delivery_fee'] = '0.00' r4['due'] = '0.00' db.order_app.insert_one(r4) # 增加子订单 elif len(b3)>0: # 情况 2 print "订单改到B3站点" # 如果订单地址不再配送范围,则由b3直接发出, 2015-10-18 if r.get('poly_shop', 1)==1: # 默认到店配送 print 'b3配送到店' shop_0 = r['shop'] else: print 'b3直接发货' shop_0 = ObjectId(setting.B3_shop) db.order_app.update_one({'order_id':order_id},{'$set' : { 'shop_0' : shop_0, 'shop' : ObjectId(setting.B3_shop), }}) else: # 情况3,什么都不做 print "订单保持不变" # 推送通知 #if len(r['uname'])==11 and r['uname'][0]=='1': # jpush.jpush('已收到您的付款,我们会尽快处理。', r['uname']) else: print "重复通知:alipay" b2 = r['cart'] # 修改订单状态 db.order_app.update_one({'order_id':order_id},{ '$set' : { 'status' : status, 'cart' : b2, # 更新购物车 2015-09-11 'ali_trade_no' : param.get('trade_no'), 'paid_time' : param.get('gmt_payment'), 'paid_tick' : int(time.time()), 'pay_type' : 'ALIPAY', 'credit_total' : '%.2f' % float(r.get('use_credit', '0')), 'alipay_total' : param.get('total_fee','0.00'), # 支付宝实际支付 }, '$push' : { 'ali_notify': param, 'history' : (app_helper.time_str(), 'alipay', '付款通知') } }) return 'success'