示例#1
0
文件: pretty.py 项目: jack139/pretty
    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)
示例#2
0
    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&timestamp=%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(),
            })
示例#3
0
文件: addr_add.py 项目: jack139/fair
	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'})
示例#4
0
文件: wx.py 项目: jack139/fair
    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'})
示例#5
0
    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,
        }})
示例#6
0
    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'})
示例#7
0
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&timestamp=%s&url=%s' % (
        ticket, noncestr, timestamp, url)

    print string1

    return {
        'appid': wx_appid,
        'timestamp': timestamp,
        'nonceStr': noncestr,
        'sign': hashlib.sha1(string1).hexdigest(),
    }
示例#8
0
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
示例#9
0
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
示例#10
0
	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>' 
示例#11
0
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
示例#12
0
文件: wxpay.py 项目: jack139/fair
    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'})
示例#13
0
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
示例#14
0
    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,
            }
        })
示例#15
0
文件: wxpay.py 项目: jack139/fair
	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'})
示例#16
0
文件: wx.py 项目: jack139/fair
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
示例#17
0
    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,
            }
        })
示例#18
0
    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'],
                }
            })
示例#19
0
    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,
            }
        })
示例#20
0
文件: addr_add.py 项目: jack139/fair
    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'})
示例#21
0
文件: wxpay.py 项目: jack139/fair
    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'})
示例#22
0
	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'})
示例#23
0
	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'})
示例#24
0
	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'