def get(self): # /callback?sid=RO201408271533244583 # &ste=0 # &cid=quxun # &pid=YDJS00101 # &oid=Q2014082715335400000038 # &pn=13951771065 # &tf=10 # &fm=10 # &info1=&info2=&info3= # &dm=.9885 # &sign=B94197B31EBD6956403E89F63653E1B1 try: sid = self.get_argument('sid') ste = self.get_argument('ste') # 0=success,1=fail cid = self.get_argument('cid') pid = self.get_argument('pid') oid = self.get_argument('oid') pn = self.get_argument('pn') tf = self.get_argument('tf') fm = self.get_argument('fm') request_log.info(self.request.uri, extra={'orderid': oid}) except MissingArgumentError: request_log.info(self.request.uri, extra={'orderid': 'unknown'}) sign = self.get_argument('sign') key = self.application.config['upstream']['liandong']['key'] sign2 = signature(sid, ste, cid, pid, oid, pn, tf, fm, key) if sign2 != sign: return self.write_error(405) resultno = (ste == '0' and '1') or '9' finish_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) order_info = self.redis.hgetall('order:' + oid) downstream = self.application.config['downstream'][order_info['user_id']] url = order_info['back_url'] body = 'userid=%s&orderid=%s&sporderid=%s&merchantsubmittime=%s&resultno=%s' % ( order_info['user_id'], oid, order_info['sp_order_id'], finish_time, resultno) sign = signature(body + '&key=' + downstream['key']) body += "&sign=" + sign http_client = AsyncHTTPClient() yield http_client.fetch(url, method='POST', body=body) self.write("success") self.finish()
def product_query(): key = '' http_client = HTTPClient() t = time.localtime() tsp = int(time.mktime(t)) x = '' + str(tsp) + key userkey = signature(x) print(tsp, userkey, x) url = 'http://cz.umeol.com:6090/dm/v/cz/getdp.do?spid=3&did=1687×tamp={tsp}&userkey={userkey}'.format( tsp=tsp, userkey=userkey) print(url) try: response = http_client.fetch(url, method='GET') print(response.code, response.body.decode()) # except HTTPError as http_error: # # request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': order_id}) # except Exception as e: # # request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': order_id}) finally: http_client.close()
def query_balance(): http_client = HTTPClient() url = 'http://111.20.150.45:7001/FBSY/FBSYQueryBalance.do' t = time.time() tsp = time.strftime("%Y%m%d%H%M%S", time.localtime(t)) sign = signature('100006', tsp, 'q59ka440') body = '&'.join( ['channelId=' + '100006', 'timeStamp=' + tsp, 'sign=' + sign.lower()]) try: response = http_client.fetch(url, method='POST', headers=h, body=body, request_timeout=120) resp = json.loads(response.body.decode()) print(resp) b = int(resp.get('result').get('balance')) b = '%.02f' % (b / 100) print('BALANCE=%s' % b) finally: http_client.close()
def up_shili(handler, partner): handler.up_req_time = time.localtime() # sign t = '201001' + handler.order_id + partner[ 'user'] + handler.mobile + handler.price + partner['key'] sign = signature(t).lower() body = REQUEST.format( order_id=handler.order_id, user_id=partner['user'], mobile=handler.mobile, price=handler.price, sign=sign, ) url = partner['url.order'] request_log.info('CALL_REQ %s', body, extra={'orderid': handler.order_id}) # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='POST', headers=h, body=body) except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) response = None finally: http_client.close() handler.up_resp_time = time.localtime() # <-------------- result = 9999 if response and response.code == 200: body = response.body.decode() request_log.info('CALL_RESP %s', body, extra={'orderid': handler.order_id}) try: root = et.fromstring(body) result = int(root.find('retcode').text) handler.up_order_id = root.find('oid_goodsorder').text # handler.up_cost = root.find('ordercash').text or 0 handler.up_result = result except Exception as e: result = 9999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) # mapping result = RESULT_MAPPING.get(result, result) return result
def up_liandong(self, config): """联动通讯 oid 商家订单编号 32 不可空 商户系统自己生成的订单号 cid 商家编号 20 不可空 商户注册的时候产生的一个商户ID pr 单位面值 10 不可空 您所充值的单位商品面值 nb 商品数量 1 不可空 您所需要充值的充值数量(固定为1) fm 充值金额 10 不可空 充值金额=商品面值*商品数量 pn 充值号码 11 不可空 您所需要充值的帐号信息 ct 充值类型 可以空 充值类型,缺省为快充 ru 通知地址 不可空 通知地址,根据协议2.4充值结果通知,返回充值结果 tsp 时间戳 14 不可空 请求时间戳,格式yyyyMMddHHmmss info1 扩展参数I 128 可以空 info1 扩展参数II 128 可以空 info1 扩展参数III 128 可以空 sign 签名 不可空 原串拼接规则: md5({oid}{cid}{pr}{nb}{fm}{pn}{ru}{tsp}{key}) """ partner = self.application.config['upstream']['liandong'] tsp = time.strftime("%Y%m%d%H%M%S", time.localtime()) print(partner['key']) # sign md5({oid}{cid}{pr}{nb}{fm}{pn}{ru}{tsp}{key}) sign = signature(self.order_id, partner['cid'], self.price, '1', self.price, self.mobile, partner['ru'], tsp, partner['key']) # package url = '{url}?oid={oid}&cid={cid}&pr={pr}&nb=1&fm={pr}&pn={pn}&ru={ru}&tsp={tsp}&sign={sign}'.format( url=partner['url.order'], oid=self.order_id, cid=partner['cid'], pr=self.price, pn=self.mobile, ru=urllib.parse.quote(partner['ru']), tsp=tsp, sign=sign) request_log.info('UP_REQ liandong - %s', url, extra={'orderid': self.order_id}) # call & wait http_client = AsyncHTTPClient() response = yield http_client.fetch(url) body = response.body.decode('gbk') request_log.info('UP_RESP liandong - %d:%s', response.code, body, extra={'orderid': self.order_id}) if response.code == 200: root = ElementTree.fromstring(body) if root.find('result').text == 'true' and root.find('code').text == '100': self.up_order_id = root.find('sid').text self.result = root.find('code').text else: self.result = root.find('code').text else: return '9999'
def query_fengyun_order(handler, partner): result = 0 query = '&'.join([ 'ShtVer=02', 'Action=CX', 'AgentAccount=%s' % partner['account'], 'Orderid=%s' % handler.order_id[4:] ]) sign = signature(query, '&Password=%s' % partner['key']) url = partner['url.query'] + '?' + query + '&Sign=' + sign.lower() request_log.info('QUERY_REQ %s', url, extra={'orderid': handler.order_id}) http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='GET') if response and response.code == 200: body = response.body.decode('gbk') request_log.info('QUERY_RESP %s', body, extra={'orderid': handler.order_id}) for args in body.split('&'): k, v = args.split('=') if k == 'Orderstatu_int': result = QUERY_MAP.get(v, 0) except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': handler.order_id}) except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) finally: http_client.close() return result
def query_order(handler, partner): result = 0 did = partner['did'] key = partner['key'] tsp = int(time.mktime(time.localtime())) # tel+did+ timestamp+key userkey = signature(handler.mobile, did, str(tsp), key) q = 'tel={tel}&did={did}&dorderid={dorderid}×tamp={timestamp}&userkey={userkey}'.format( tel=handler.mobile, did=did, dorderid=handler.order_id, timestamp=tsp, userkey=userkey) url = partner['url.query'] + '?' + q http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='GET') body = response.body.decode() request_log.info('QUERY_RESP %s', body, extra={'orderid': handler.order_id}) resp = json.loads(body) status = resp['status'] result = QUERY_MAPPING.get(status, 0) except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': handler.order_id}) except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) finally: http_client.close() return result
def test_aes(): code = '{"cpUser":"******","channelOrderId":"201500000000001","content":"流量直充测试","createTime":"20150811154558","type":1,"amount":102400,"range":0,"mobile":"13333333333","notifyUrl":"http://www.xxx.com/"}' aes = AES.new('AYiZxwvT6IDeSffqWRaCyre9FDGQy5IT', AES.MODE_CBC, "176543218'653#23") s = pad_bytes(code.encode('gbk')) print(len(s) / 16) bytes = aes.encrypt(s) encrypted = codecs.encode(bytes, 'hex') print(encrypted) digest = signature(encrypted.decode()).lower() print(digest) k = sorted(['200266', 'aspRKtT074Bipl8E', digest, '1439279159'], reverse=True) h = hashlib.sha1() h.update(''.join(k).encode()) print(h.hexdigest())
def product_query(): OP_MAP = { 0: '移动', 1: '联通', 2: '电信' } http_client = HTTPClient() t = time.localtime() tsp = int(time.mktime(t)) user = '******' sign = signature(user, str(tsp), 'RtGpAPFoXiSY8BgDWz85V7GPPFJeWvoh') url = 'http://122.224.212.160:8980/common/quotation.action?cpUser={user}&time={tsp}&sign={sign}'.format( user=user, tsp=tsp, sign=sign) print(url) try: response = http_client.fetch(url, method='GET') if response.code == 200: body = response.body.decode() resp = json.loads(body) for obj in resp.get('data'): op_code = obj['opCode'] size = obj['amount'] price = obj['discountPrice'] print('%s,%s,%s' % (OP_MAP.get(op_code), size, price)) # except HTTPError as http_error: # # request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': order_id}) # except Exception as e: # # request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': order_id}) finally: http_client.close()
def post(self): order_id = 'UNKNOWN' # check ip # parse input try: up_order_id = self.get_argument('orderid') order_id = self.get_argument('sporderid') user_id2 = self.get_argument('userid') submit_time = self.get_argument('merchantsubmittime') up_back_result = self.get_argument('resultno') sign = self.get_argument('sign') except MissingArgumentError as e: request_log.info('%s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) self.finish() return # check input self.write("success") self.finish() request_log.info('CALLBACK %s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) # update order status try: # check sign master = self.master order_info = master.hmget('order:' + order_id, [ 'user_id', # 0 'value', # 1 'stage', # 2 'area', # 3 'price', # 4 'back_url', # 5 'sp_order_id', # 6 'mobile', # 7 'price', # 8 'product', # 9 'plat_offer_id' # 10 ]) self.order_id = order_id self.user_id = order_info[0] self.value = int(order_info[1]) stage = int(order_info[2]) area = order_info[3] self.carrier, self.area = area.split(':') self.price = order_info[4] self.back_url = order_info[5] self.sp_order_id = order_info[6] self.mobile = order_info[7] self.price = order_info[8] self.product = order_info[9] self.plat_offer_id = order_info[10] self.route = master.hget('order:' + order_id, 'route/%d' % stage) self.up_back_result = up_back_result # checking callback user = self.application.config['upstream'][self.route] if user is None or 'key' not in user: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return # sign=MD5(userid=xxxx&orderid=xxxxxxx&sporderid=xxxxx&merchantsubmittime=xxxxx &resultno=xxxxx&key=xxxxxxx q = 'userid=%s&orderid=%s&sporderid=%s&merchantsubmittime=%s&resultno=%s&key=%s' % ( user_id2, up_order_id, order_id, submit_time, up_back_result, user['key']) sign2 = signature(q) if sign != sign2: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return up_back_time = time.localtime() master.hmset('order:%s' % order_id, { 'up_back_result/%d' % stage: up_back_result, 'up_back_time/%d' % stage: time.mktime(up_back_time) }) except Exception as e: request_log.info('restore order info error %s', e, extra={'orderid': order_id}) return # downstream callback or route to next... if up_back_result == '1': self.callback('1') elif up_back_result == '9': yield self.dispatch() else: pass # TODO: logging & waiting for human
def up_standard(handler, partner): """速卡科技 userid string 1-20 商代理商编号 productid string 1-20 平台对应商品编号(可以为空,为空时,以手机号实际所在地自动对应商品编号,并且不做充值金额判断) price string 1-20 充值金额(面值)整数,如:50,100 num int 1-10 订单商品数量(只能为1) mobile string 1-11 充值手机号 spordertime time 1-14 代理商订单时间YYYY-MM-DD HH:MI:SS sporderid string 1-30 代理商系统订单号(流水号)要求不可重复,每笔只可同时提交一次 md5({oid}{cid}{pr}{nb}{fm}{pn}{ru}{tsp}{key}) """ handler.up_req_time = time.localtime() tsp = time.strftime("%Y%m%d%H%M%S", handler.up_req_time) price = handler.price # get product_id for data product if handler.product == 'data': prefix = partner.get('prefix', 'suka') k1 = 'private:{prefix}:{carrier}:{area}:{price}'.format( prefix=prefix, carrier=handler.carrier, area=handler.area, price=handler.price) k2 = 'private:{prefix}:{carrier}:{price}'.format( prefix=prefix, carrier=handler.carrier, price=handler.price) p1, p2 = handler.slave.mget(k1, k2) product_id = p1 or p2 if product_id is None: handler.up_result = 5003 return handler.up_result if ',' in product_id: product_id, price = product_id.split(',') if prefix == 'suka' and handler.carrier == 2 and price == 10: price = 5 else: product_id = '' if handler.product in ['fee', 'data']: # package qt = 'userid=%s&productid=%s&price=%s&num=1&mobile=%s&spordertime=%s&sporderid=%s' % ( partner['userid'], product_id, price, handler.mobile, tsp, handler.order_id) else: # package qt = 'product=%s&userid=%s&productid=%s&price=%s&num=1&account_number=%s&spordertime=%s&sporderid=%s' % ( handler.product, partner['userid'], product_id, price, handler.mobile, tsp, handler.order_id) # sign sign = signature(qt + '&key=' + partner['key']) url = partner['url.order'] # urllib.parse.quote( body = '%s&sign=%s&back_url=%s' % (qt, sign, partner['callback']) # upuserid if 'send_user' in partner: body = body + '&upuserid=' + handler.user_id # print(handler.order_id + ":" + body) request_log.info('CALL_REQ %s', body, extra={'orderid': handler.order_id}) # call & wait result = 9999 http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='POST', headers=h, body=body, connect_timeout=30, request_timeout=30) except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': handler.order_id}) result = 60000 + http_error.code response = None except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) response = None finally: http_client.close() handler.up_resp_time = time.localtime() # <-------------- if response and response.code == 200: body = response.body.decode('gbk') request_log.info('CALL_RESP %s', body, extra={'orderid': handler.order_id}) try: root = et.fromstring(body) result = int(root.find('resultno').text) handler.up_order_id = root.find('orderid').text handler.up_cost = root.find('ordercash').text or 0 handler.up_result = result except Exception as e: result = 9999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) return result
def callback(self, back_result): master = self.master if back_result == '9': self.refund() self.update_upstream(refund=True) try: self.back_result = str(self.back_result or self.up_back_result or self.up_result or back_result) master.hset('order:%s' % self.order_id, 'back_result', self.back_result) except Exception as e: root_log.error("SET", e) downstream = self.application.config['downstream'][self.user_id] url = self.back_url back_time = time.localtime() if self.product == 'data': body = json.dumps({ 'order_id': self.sp_order_id, 'transactionid': self.order_id, 'orderstatus': ((back_result == '1') and 'finish') or 'fail', 'result_code': self.back_result, 'plat_offer_id': self.plat_offer_id, 'facevalue': self.price, 'phone_id': self.mobile, 'ordertime': time.strftime("%Y-%m-%d %H:%M:%S", back_time) }) else: body = 'userid=%s&orderid=%s&sporderid=%s&merchantsubmittime=%s&resultno=%s' % ( self.user_id, self.order_id, self.sp_order_id, time.strftime("%Y%m%d%H%M%S", back_time), back_result) sign = signature(body + '&key=' + downstream['key']) body += "&sign=" + sign request_log.info('CALLBACK %s - %s' % (url, body), extra={'orderid': self.order_id}) h = None if downstream.get('content'): h = {'Content-Type': 'application/json;charset=UTF-8'} for i in range(3): http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='POST', headers=h, body=body) if response and response.code == 200: break except Exception as e: request_log.warn('CALLBACK FAIL - %s', e, extra={'orderid': self.order_id}) finally: http_client.close() # wait for 5*i secs yield gen.sleep(60 * (i + 1)) # finish order back_time = time.localtime() try: master.hset('order:%s' % self.order_id, 'back_time', time.mktime(back_time)) master.sadd('list:finish', self.order_id) master.srem('list:create', self.order_id) except Exception as e: root_log.error("MOVE ORDER %s", e)
# except HTTPError as http_error: # # request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': order_id}) # except Exception as e: # # request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': order_id}) finally: http_client.close() if __name__ == '__main__': # product_query() did = '1687' key = '674ZAHa5Z3h/MntVVAR' tsp = int(time.mktime(time.localtime())) # tel+did+ timestamp+key userkey = signature('18520311237', did, str(tsp), key) q = 'tel={tel}&did={did}&dorderid={dorderid}×tamp={timestamp}&userkey={userkey}'.format( tel='18520311237', did=did, dorderid='Q2015072409372110811547', timestamp=tsp, userkey=userkey) url = 'http://cz.umeol.com:6090/dm/v/cz/qorder.do' + '?' + q http_client = HTTPClient() try: response = http_client.fetch(url, method='GET')
def post(self): order_id = 'UNKNOWN' # check ip # UserNumber=9000215&InOrderNumber=IP9000215201506251622000184&OutOrderNumber=Q2015062516220010000184&PayResult=5&CustomInfo=--&RecordKey=2189E9266575527D&OrderType=P # parse input try: user_number = self.get_argument('UserNumber') up_order_id = self.get_argument( 'InOrderNumber') # 0=success,1=fail order_id = self.get_argument('OutOrderNumber') # 0=success,1=fail pay_result = self.get_argument('PayResult') custom_info = self.get_argument('CustomInfo') sign = self.get_argument('RecordKey') # result mapping if pay_result == '4': up_back_result = '1' elif pay_result == '5': up_back_result = '9' else: up_back_result = '9999' except MissingArgumentError as e: request_log.info('%s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) self.finish() return # check input self.finish( '<?xml version="1.0" encoding="GB2312"?><root><result>success</result></root>' ) request_log.info('CALLBACK %s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) # update order status try: # check sign master = self.master if not master.sismember('list:create', order_id): request_log.error('ORDER IS BACK ALREADY', extra={'orderid': order_id}) return order_info = master.hmget( 'order:' + order_id, [ 'user_id', # 0 'value', # 1 'stage', # 2 'area', # 3 'price', # 4 'back_url', # 5 'sp_order_id', # 6 'mobile', # 7 'price', # 8 'product', # 9 'plat_offer_id' # 10 ]) self.order_id = order_id self.user_id = order_info[0] self.value = int(order_info[1]) stage = int(order_info[2]) area = order_info[3] self.carrier, self.area = area.split(':') self.price = order_info[4] self.back_url = order_info[5] self.sp_order_id = order_info[6] self.mobile = order_info[7] self.price = order_info[8] self.product = order_info[9] self.plat_offer_id = order_info[10] self.route = master.hget('order:' + order_id, 'route/%d' % stage) self.up_back_result = up_back_result # checking callback user = self.application.config['upstream'].get(self.route) if user is None or 'key' not in user: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return key = user['key'] sign2 = signature(user_number, up_order_id, order_id, pay_result, custom_info, key) if sign != sign2[0:16]: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return up_back_time = time.localtime() master.hmset( 'order:%s' % order_id, { 'up_back_result/%d' % stage: up_back_result, 'up_back_time/%d' % stage: time.mktime(up_back_time) }) except Exception as e: request_log.exception('restore order info error %s', e, extra={'orderid': order_id}) return # downstream callback or route to next... if up_back_result == '1': self.callback('1') elif up_back_result == '9': yield self.dispatch() else: pass # TODO: logging & waiting for human
def up_yuechen(handler, partner): """联动通讯 oid 商家订单编号 32 不可空 商户系统自己生成的订单号 cid 商家编号 20 不可空 商户注册的时候产生的一个商户ID pr 单位面值 10 不可空 您所充值的单位商品面值 nb 商品数量 1 不可空 您所需要充值的充值数量(固定为1) fm 充值金额 10 不可空 充值金额=商品面值*商品数量 pn 充值号码 11 不可空 您所需要充值的帐号信息 ct 充值类型 可以空 充值类型,缺省为快充 ru 通知地址 不可空 通知地址,根据协议2.4充值结果通知,返回充值结果 tsp 时间戳 14 不可空 请求时间戳,格式yyyyMMddHHmmss info1 扩展参数I 128 可以空 info1 扩展参数II 128 可以空 info1 扩展参数III 128 可以空 sign 签名 不可空 原串拼接规则: md5({oid}{cid}{pr}{nb}{fm}{pn}{ru}{tsp}{key}) """ handler.up_req_time = time.localtime() tsp = time.strftime("%Y%m%d%H%M%S", time.localtime()) # print(partner['key']) # sign md5({oid}{cid}{pr}{nb}{fm}{pn}{ru}{tsp}{key}) sign = signature(handler.order_id, partner['cid'], handler.price, '1', handler.price, handler.mobile, partner['ru'], tsp, partner['key']) # package url = '{url}?oid={oid}&cid={cid}&pr={pr}&nb=1&fm={pr}&pn={pn}&ru={ru}&tsp={tsp}&sign={sign}'.format( url=partner['url.order'], oid=handler.order_id, cid=partner['cid'], pr=handler.price, pn=handler.mobile, # ru=urllib.parse.quote(partner['ru']), ru=partner['ru'], tsp=tsp, sign=sign) request_log.info('CALL_REQ YUECHEN %s', url, extra={'orderid': handler.order_id}) # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, connect_timeout=30, request_timeout=30) except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) response = None finally: http_client.close() result = 9999 if response and response.code == 200: body = response.body.decode('gbk') request_log.info('CALL_RESP (%d) %s', response.code, body, extra={'orderid': handler.order_id}) root = ElementTree.fromstring(body) if root.find('result').text == 'true' and root.find( 'code').text == '100': result = int(root.find('code').text) handler.up_order_id = root.find('data/sid').text handler.result = RESULT_MAP.get(result, result) else: result = int(root.find('code').text) handler.result = RESULT_MAP.get(result, result) return handler.result
def get(self): master = self.master route = self.get_argument('r', 'legend') order_id = self.get_argument('o') if not master.sismember('list:create', order_id): request_log.error('ORDER IS BACK ALREADY', extra={'orderid': order_id}) return request_log.info('LEGEND QUERY BACK %s' % self.request.uri, extra={'orderid': order_id}) partner = self.application.config['upstream'][route] did = partner['did'] key = partner['key'] tsp = int(time.mktime(time.localtime())) mobile = master.hget('order:' + order_id, 'mobile') if mobile is None: self.send_error(403) return # tel+did+ timestamp+key userkey = signature(mobile, did, str(tsp), key) q = 'tel={tel}&did={did}&dorderid={dorderid}×tamp={timestamp}&userkey={userkey}'.format( tel=mobile, did=did, dorderid=order_id, timestamp=tsp, userkey=userkey) url = partner['url.query'] + '?' + q result = 0 http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='GET') body = response.body.decode() request_log.info('QUERY_RESP %s', body, extra={'orderid': order_id}) resp = json.loads(body) status = resp['status'] result = QUERY_MAPPING.get(status, 0) except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': order_id}) except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': order_id}) finally: http_client.close() if result not in [1, 9]: request_log.info('LEGEND NOT RETURN %s', result, extra={'orderid': order_id}) self.finish('processing') return try: self.up_back_result = str(result) stage = self.restore_order(order_id) # checking callback up_back_time = time.localtime() master.hmset('order:%s' % order_id, { 'up_back_result/%d' % stage: self.up_back_result, 'up_back_time/%d' % stage: time.mktime(up_back_time) }) except Exception as e: request_log.info('restore order info error %s', e, extra={'orderid': order_id}) self.send_error(500) return if self.up_back_result == '1': self.callback('1') else: yield self.dispatch() self.finish('success')
def parse_product(self): """check all argument check sign """ product_value = None try: product_value = self.get_body_argument('product') self.product = product_value except MissingArgumentError: self.product = 'fee' if self.product not in ['fee', 'sinopec']: request_log.error('UNKNOWN PRODUCT!!!', extra={'orderid': self.order_id}) return '5012' try: sign_account_key = None if self.product == 'fee': self.mobile = self.get_body_argument('mobile') sign_account_key = 'mobile' elif self.product == 'sinopec': self.mobile = self.get_body_argument('account_number') sign_account_key = 'account_number' self.user_id = self.get_body_argument('userid') self.price = self.get_body_argument('price') self.sp_order_id = self.get_body_argument('sporderid') self.back_url = self.get_body_argument('back_url') self.master_id = self.user_id # tsp = self.get_body_argument('spordertime') sign = self.get_body_argument('sign').upper() # stop flag in config if 'stop' in self.application.config['config']: request_log.error('STOP FLAG FOUND', extra={'orderid': self.order_id}) return '5003' # verifying... num = self.get_body_argument('num') if num is None or num != '1': return '5012' # verifying user user = self.application.config['downstream'][self.user_id] if user is None or 'key' not in user: request_log.error('USERINFO NOT EXIST', extra={'orderid': self.order_id}) return '5001' # check ip if self.check_ip(user): return '5009' # verifying signature q = 'userid={userid}&price={price}&num={num}&{sign_account_key}={sign_account_value}&spordertime={tsp}&sporderid={orderid}&key={key}'.format( userid=self.user_id, price=self.price, num=num, sign_account_key=sign_account_key, sign_account_value=self.mobile, tsp=tsp, orderid=self.sp_order_id, key=user['key']) if product_value: q = 'product=' + product_value + '&' + q sign2 = signature(q) if sign != sign2: request_log.error('SIGN ERROR %s %s', sign, sign2, extra={'orderid': self.order_id}) return "5005" # dual order if self.slave.exists('map:%s:%s' % (self.user_id, self.sp_order_id)): request_log.warning('DUAL ORDER %s', self.sp_order_id, extra={'orderid': self.order_id}) return '5006' # verifying mobile if self.product in ['fee', 'data']: o, a = self.classifier.search(self.mobile) if o is None: request_log.warning('UNKNOWN AREA', extra={'orderid': self.order_id}) return '5003' self.carrier = o self.area = a elif self.product == 'sinopec': self.carrier = 'sinopec' self.area = 'CN' except MissingArgumentError: request_log.exception('MissingArgumentError', extra={'orderid': self.order_id}) return "5012"
def up_legend(handler, partner): bid1 = handler.slave.get('private:legend:%s:%d' % (handler.carrier, handler.price)) bid2 = handler.slave.get('private:legend:%s:%s:%d' % (handler.carrier, handler.area, handler.price)) bid = bid2 or bid1 did = partner['did'] key = partner['key'] handler.up_req_time = time.localtime() tsp = int(time.mktime(handler.up_req_time)) handler.up_order_id = handler.order_id # tel+did+ timestamp+key userkey = signature(handler.mobile, did, str(tsp), key) query = ( 'tel={tel}&did={did}&bid={bid}&dorderid={dorderid}×tamp={timestamp}&userkey={userkey}' ).format(tel=handler.mobile, did=did, bid=bid, dorderid=handler.order_id, timestamp=tsp, userkey=userkey) url = partner['url.order'] + '?' + query request_log.info('CALL_REQ %s', query, extra={'orderid': handler.order_id}) # call & wait response = None result = 99999 http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='GET') except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': handler.order_id}) result = 60000 + http_error.code except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) finally: http_client.close() handler.up_resp_time = time.localtime() # <-------------- if response and response.code == 200: body = response.body.decode() request_log.info('CALL_RESP %s', body, extra={'orderid': handler.order_id}) try: resp = json.loads(body) status = resp['status'] result = RESULT_MAPPING.get(status, 0) handler.up_result = str(result) except Exception as e: result = 99999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) if handler.up_result is None: handler.up_result = result # if result in [0, 60599]: # for i in range(2): # # wait # yield tornado.gen.Task(IOLoop.instance().add_timeout, time.time() + i * 60) # # result = yield query_order(handler, partner) # if result in [1, 9]: # handler.up_result = str(result) # break if result == 1: yield handler.callback('1') elif result == 9: pass elif result == 0: # handler.master.sadd('set:legend:pending', handler.order_id) request_log.info('LEGEND NOT_FINISHED', extra={'orderid': handler.order_id}) return result
def post(self): order_id = 'UNKNOWN' # check ip # parse input try: body = self.request.body.decode() root = et.fromstring(body) up_back_result = root.find('retcode').text up_order_id = root.find('oid_goodsorder').text order_id = root.find('jno_cli').text user_id = root.find('oid_reguser').text fill_time = root.find('fill_time').text up_cost = root.find('succ_amount').text sign = root.find('sign').text except MissingArgumentError as e: request_log.info('%s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) self.finish() return # check input self.finish( '<?xml version="1.0" encoding="UTF-8"?><root><retcode>000000</retcode></root>' ) request_log.info('CALLBACK %s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) # update order status try: # check sign master = self.master order_info = master.hmget( 'order:' + order_id, [ 'user_id', # 0 'value', # 1 'stage', # 2 'area', # 3 'price', # 4 'back_url', # 5 'sp_order_id', # 6 'mobile', # 7 'price', # 8 'product', # 9 'plat_offer_id' # 10 ]) self.order_id = order_id self.user_id = order_info[0] self.value = int(order_info[1]) stage = int(order_info[2]) area = order_info[3] self.carrier, self.area = area.split(':') self.price = order_info[4] self.back_url = order_info[5] self.sp_order_id = order_info[6] self.mobile = order_info[7] self.price = order_info[8] self.product = order_info[9] self.plat_offer_id = order_info[10] self.route = master.hget('order:' + order_id, 'route/%d' % stage) self.up_back_result = int(up_back_result) # checking callback up_stream = self.application.config['upstream'][self.route] if up_stream is None or 'key' not in up_stream or up_stream[ 'user'] != user_id: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return # retcode; oid_reguser; jno_cli; oid_goodsorder; succ_amount; fill_time q = up_back_result + user_id + order_id + up_order_id + up_cost + fill_time + up_stream[ 'key'] sign2 = signature(q).lower() if sign != sign2: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return up_back_time = time.localtime() master.hmset( 'order:%s' % order_id, { 'up_back_result/%d' % stage: up_back_result, 'up_back_time/%d' % stage: time.mktime(up_back_time), 'up_cost/%d' % stage: up_cost, }) except Exception as e: request_log.info('restore order info error %s', e, extra={'orderid': order_id}) return r = int(up_back_result) up_back_result = RESULT_MAPPING.get(r, r) # downstream callback or route to next... if up_back_result == 1: self.callback('1') elif up_back_result == 9: yield self.dispatch() else: request_log.info('UNKNOWN RESULT %s', up_back_result, extra={'orderid': order_id})
def post(self): cfg = self.application.config try: json_args = json.loads(self.request.body.decode('utf8')) _type = json_args['type'] user_id = json_args['user_id'] operator = json_args['operator'] token = json_args['token'] income0 = json_args['income'] notes = json_args['notes'] sign0 = json_args['sign'] order_id = json_args['order_id'] except Exception as e: return self.fail('参数输入错误') income = to_int(income0) outcome = 0 if _type not in ['deposit', 'refund-manual', 'debit-manual']: return self.fail('财务类型异常') if operator not in cfg['operator']: return self.fail('无效用户') if _type == 'deposit' and (income > 10000000000 or income <= 0): return self.fail('一次性加款额度不得超过1,000,000元') if _type == 'refund-manual' and income > 5000000: return self.fail('订单退款额度异常') if _type == 'debit-manual': outcome = income income = 0 operator_info = cfg['operator'][operator] secret = operator_info['secret'] if not otp.valid_totp(token, secret, window=1): return self.fail('验证码失效') sign1 = signature( '{user_id}{order_id}{income}{operator}{token}'.format( user_id=user_id, order_id=order_id, income=income0, operator=operator, token=token)) if sign1 != sign0: return self.fail('安全签名错误!') sign2 = signature( '{user_id}{order_id}{income}{operator}{token}{secret}'.format( user_id=user_id, order_id=order_id, income=income0, operator=operator, token=token, secret=secret)) # redis try: k = 'point:%s' % user_id balance = self.master.incrby(k, income - outcome) finance_log.info('%s user=%s, value=%d, balance=%d', _type.upper(), user_id, income, balance, extra={'orderid': order_id}) except Exception as e: finance_log.info('%s ERROR user=%s, value=%d, balance=%d', _type.upper(), user_id, income, balance, extra={'orderid': order_id}) return self.fail('内部错误!' + str(e)) # type|income|outcome|balance|order_id|user_id|account|name|t|operator|sign|notes finance = '{type}|{income}|{outcome}|{balance}|{order_id}|{user_id}|||{time}|{operator}|{sign}|{notes}'.format( type=_type, income=income, outcome=outcome, balance=balance, order_id=order_id, user_id=user_id, time=time.mktime(time.localtime()), operator=operator, sign=sign2, notes=notes) try: self.master.lpush('finance', finance) finance_log.info('FINANCE ' + finance, extra={'orderid': order_id}) except Exception as e: finance_log.info('FINANCE ERROR' + finance, extra={'orderid': order_id}) return self.fail('内部错误!' + str(e)) return self.success(str(balance))
def up_mopote(handler, partner): slave = handler.slave # private data k = 'private:mopote:{carrier}:{price}'.format(carrier=handler.carrier, price=handler.price) amount, _range = slave.hmget(k, ['amount', 'range']) if amount is None: return 99999 handler.up_req_time = time.localtime() str_time = time.strftime('%Y%m%d%H%M%S', handler.up_req_time) tsp = int(time.mktime(handler.up_req_time)) code = json.dumps({ 'cpUser': partner.get('user'), 'channelOrderId': handler.order_id, 'content': '', 'createTime': str_time, 'type': 1, 'amount': amount, 'range': _range, 'mobile': handler.mobile, 'notifyUrl': partner.get('callback') }) aes = AES.new(partner['aes_key'], AES.MODE_CBC, partner['aes_iv']) bytes = aes.encrypt(pad_bytes(code.encode('gbk'))) encrypted = codecs.encode(bytes, 'hex').decode() digest = signature(encrypted).lower() # case-insensitive sort k = sorted([partner['user'], partner['sha_key'], digest, str(tsp)], key=lambda s: s.lower(), reverse=True) h = hashlib.sha1() h.update(''.join(k).encode()) sign = h.hexdigest() url = partner['url.order'] full_url = url + '?d={digest}&t={tsp}&s={sign}&a={user}'.format( digest=digest, tsp=str(tsp), sign=sign, user=partner['user']) request_log.info('CALL_REQ %s', code, extra={'orderid': handler.order_id}) request_log.info('CALL_REQ %s', full_url, extra={'orderid': handler.order_id}) request_log.info('CALL_REQ %s', encrypted, extra={'orderid': handler.order_id}) response = None result = 99999 up_result = None # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(full_url, method='POST', body=encrypted, headers={'Content-Type': 'application/octet-stream; charset=UTF-8'}, request_timeout=120) except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': handler.order_id}) result = 60000 + http_error.code except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) finally: http_client.close() if response and response.code == 200: body = response.body.decode() request_log.info('CALL_RESP %s', body, extra={'orderid': handler.order_id}) try: resp = json.loads(body) data = resp.get('data') if data: handler.up_order_id = data.get('orderId') up_result = data.get('status') if up_result: result = RESULT_MAPPING.get(up_result,0) except Exception as e: result = 99999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) handler.up_result = up_result handler.up_resp_time = time.localtime() # <-------------- return result
def up_esai(handler, partner): handler.up_req_time = time.localtime() tsp = time.strftime("%Y-%m-%d %H:%M:%S", handler.up_req_time) # t2 = time.strftime("%Y%m%d%H%M%S", handler.up_req_time) price = handler.price in_order = 'IP%s%s%s' % (partner['user_number'], handler.order_id[1:15], handler.order_id[-4:]) # sign UserNumber + PhoneNumber+ Province + City + PhoneClass + PhoneMoney(正整数) +Time + Sign sign = signature(partner['user_number'], in_order, handler.order_id, handler.mobile, 'Auto', 'Auto', 'Auto', price, 'None', tsp, '600', partner['key']) body = '&'.join([ 'UserNumber=%s' % partner['user_number'], 'InOrderNumber=%s' % in_order, 'OutOrderNumber=%s' % handler.order_id, 'PhoneNumber=%s' % handler.mobile, 'Province=Auto', 'City=Auto', 'PhoneClass=Auto', 'PhoneMoney=%s' % price, 'SellPrice=None', 'StartTime=%s' % quote(tsp), 'TimeOut=600', 'RecordKey=%s' % sign[0:16], 'Remark=--' ]) url = partner['url.order'] # print(handler.order_id + ":" + body) request_log.info('CALL_REQ %s', body, extra={'orderid': handler.order_id}) # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='POST', body=body, connect_timeout=60, request_timeout=60) except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) response = None finally: http_client.close() handler.up_resp_time = time.localtime() # <-------------- result = 9999 if response and response.code == 200: body = response.body.decode('gbk') request_log.info('CALL_RESP %s', body, extra={'orderid': handler.order_id}) try: root = et.fromstring(body) r = root.find('result').text if r == 'success': handler.up_order_id = root.find('inOrderNumber').text result = 0 elif r in [ 'sameorder', 'ordererr', 'attrerr', 'phoneerr', 'moneyerr', 'sellpriceerr', 'dberr' ]: result = 5003 handler.up_result = result except Exception as e: result = 9999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) return result
def up_yangchan(self, partner): prod = self.slave.hmget( 'private:yangchan:{carrier}:{price}'.format(carrier=self.carrier, price=self.price), ['flow', 'range', 'start', 'effect', 'net']) flow_value = prod[0] range = prod[1] start = prod[2] effect = prod[3] net = prod[4] self.up_req_time = time.localtime() tsp = time.strftime("%Y%m%d%H%M%S", self.up_req_time) sign = partner['user_id'] + self.mobile + str( self.price) + flow_value + range + start sign = signature(signature(sign).lower() + partner['secret']).lower() body = '&'.join([ 'user_id=' + partner['user_id'], 'phone=' + self.mobile, 'money=' + str(self.price), 'flowValue=' + flow_value, 'range=' + range, 'effectStartTime=' + start, 'effectTime=' + effect, 'netType=' + net, 'verification=' + sign, 'order_id=' + self.order_id ]) url = partner['url.order'] request_log.info('CALL_REQ %s %s', url, body, extra={'orderid': self.order_id}) response = None result = 99999 # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='POST', headers=h, body=body) except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': self.order_id}) result = 60000 + http_error.code except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': self.order_id}) finally: http_client.close() if response and response.code == 200: body = response.body.decode() request_log.info('CALL_RESP %s', body, extra={'orderid': self.order_id}) try: root = et.fromstring(body) result = int(root.find('code').text) # self.up_order_id = resp['request_no'] # self.up_cost = self.cost except Exception as e: result = 99999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': self.order_id}) # result mapping result = RESULT_MAPPING.get(result, result) self.up_result = result self.up_resp_time = time.localtime() # <-------------- return result
def post(self): request_log.info('PRICE CONFIG START', extra={'orderid': 'UNKNOWN'}) try: safety = self.application.config.get('safety') if safety is None: request_log.error('CONFIG FAIL (NO SAFETY)', extra={'orderid': 'UNKNOWN'}) return self.send_error(500) # verify ip in white list if self.request.remote_ip not in safety['white_list']: request_log.error("CONFIG FAIL ('%s'NOT IN WHITELIST)", self.request.remote_ip, extra={'orderid': 'UNKNOWN'}) return self.send_error(500) # verify key tsp0 = self.request.headers['tsp'] encrypted0 = self.request.headers['v'] encrypted1 = signature(tsp0 + safety['secret']) if encrypted1 != encrypted0: request_log.error('CONFIG FAIL (SECRET FAIL)', extra={'orderid': 'UNKNOWN'}) return self.send_error(500) # reload body = self.request.body.decode() request_log.debug(body, extra={'orderid': 'PRICING'}) for line in body.split('\n'): if line.startswith('set '): keys = line.split() self.master.set(keys[1], keys[2]) elif line.startswith('setex '): keys = line.split() if len(keys) < 3 or not keys[3].isdigit(): continue self.master.setex(keys[1], int(keys[3]), keys[2]) # name time value elif line.startswith('hmset '): keys = line.split() mapping = { keys[x]: keys[x + 1] for x in range(2, len(keys), 2) } self.master.hmset(keys[1], mapping) elif line.startswith('del '): keys = line.split() self.master.delete(keys[1]) elif line.startswith('clr '): keys = line.split() keys = self.master.keys(keys[1]) for k in keys: self.master.delete(k) elif line.startswith('incrby '): keys = line.split() if len(keys) < 3 or not keys[2].isdigit(): continue self.master.incrby(keys[1], int(keys[2])) return self.finish() except Exception as e: request_log.exception('CONFIG SYNC FAIL', extra={'orderid': 'UNKNOWN'}) self.send_error(500)
def post(self): request_log.info('FEE QUERY BODY {%s}', self.request.body.decode(), extra={'orderid': 'UNKNOWN'}) try: slave = self.slave user_id = self.get_argument('userid') sp_order_id = self.get_argument('sporderid') sign = self.get_argument('sign') user = self.application.config['downstream'].get(user_id) if user is None: self.send_error(500) return if sign: key = user.get('key') sign0 = signature('userid={user_id}&sporderid={sp_order_id}&key={key}'.format( user_id=user_id, sp_order_id=sp_order_id, key=key)) if sign != sign0: order = ET.Element('order') ET.SubElement(order, 'resultno').text = '5005' request_log.info('FEE QUERY SIGN FAIL %s %s %s', sp_order_id, sign, sign0, extra={'orderid': sp_order_id}) self.finish(ET.tostring(order, encoding='gbk')) return order_id = slave.get('map:%s:%s' % (user_id, sp_order_id)) in_cache = False if order_id: in_cache = slave.exists('order:%s' % order_id) if order_id is None or not in_cache: info = self.from_db(user_id, sp_order_id) self.finish(info) return data = slave.hgetall('order:%s' % order_id) if 'value' in data: value = int(data['value']) else: value = 0 if 'mobile' in data: mobile = data['mobile'] else: mobile = '' if 'back_result' in data: result = data['back_result'] else: if 'result' in data: result = data['result'] else: result = '9999' order = ET.Element('order') ET.SubElement(order, 'orderid').text = order_id ET.SubElement(order, 'num').text = '1' ET.SubElement(order, 'ordercash').text = str(value / 10000) ET.SubElement(order, 'sporderid').text = sp_order_id ET.SubElement(order, 'account').text = mobile ET.SubElement(order, 'resultno').text = result self.set_header('Access-Control-Allow-Origin', '*') # for web-based debugger body = ET.tostring(order, encoding='gbk') request_log.info('FEE QUERY RESPONSE %s', body, extra={'orderid': order_id}) self.finish(body) except: request_log.exception('FEE QUERY ERROR', extra={'orderid': 'UNKNOWN'}) self.write_error(500)
def up_cmcc_sn(handler, partner): # product_id = partner['product_id'] # package = handler.slave.get('private:cmcc-sn:%d' % handler.price, 'package') product_id = PRICE_TO_PACKAGE.get(handler.price) handler.up_req_time = time.localtime() t = time.time() tsp = time.strftime("%Y%m%d%H%M%S", time.localtime(t)) channel_id = partner['channelId'] # channelId+14位时间戳+6位序号 seq_no = '%s%s%s' % (channel_id, tsp, handler.order_id[-6:]) key = partner['key'] sign = signature(channel_id, tsp, handler.mobile, seq_no, key) body = '&'.join([ 'channelId=' + channel_id, 'timeStamp=' + tsp, 'productId=' + product_id, 'mobile=' + handler.mobile, 'channelSeqNo=' + seq_no, 'sign=' + sign.lower() ]) url = partner['url.order'] # print(handler.order_id + ":" + body) request_log.info('CALL_REQ %s', body, extra={'orderid': handler.order_id}) # call & wait response = None result = 99999 http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='POST', headers=h, body=body, request_timeout=120) except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': handler.order_id}) result = 60000 + http_error.code except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) finally: http_client.close() handler.up_resp_time = time.localtime() # <-------------- if response and response.code == 200: body = response.body.decode('utf8') request_log.info('CALL_RESP %s', body.replace('\n', ''), extra={'orderid': handler.order_id}) try: root = json.loads(body) handler.up_result = root.get('resultCode') handler.up_order_id = seq_no result = RESULT_MAP.get(handler.up_result, 0) if handler.up_result == '0001': handler.master.set('map:cmcc-sn:%s' % seq_no, handler.order_id) except Exception as e: result = 99999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) if handler.up_result is None: handler.up_result = result return result
def up_seek(handler, partner): slave = handler.slave # private data if handler.scope is None: k = 'private:seek:{area}:{price}'.format(area=handler.area, price=handler.price) else: k = 'private:seek:{area}:{price}:{scope}'.format(area=handler.area, price=handler.price, scope=handler.scope) prod = slave.hmget(k, ['prod_id', 'sum']) if prod[0] is None: return 99999 prod_id = prod[0] prod_sum = prod[1] handler.up_req_time = time.localtime() tsp = int(time.mktime(handler.up_req_time)) back_url = urllib.parse.quote_plus(partner['callback']) sign = ''.join([ 'appkey', partner['key'], 'channelOrderNo', handler.order_id, 'customer', handler.mobile, 'notifyUrl', back_url, 'prodId', prod_id, 'prodNum1prodPayType0', 'sum', prod_sum, 'timestamp', str(tsp), partner['secret'] ]) sign = signature(sign).lower() q = '&'.join([ 'appkey=' + partner['key'], 'prodId=' + prod_id, 'customer=' + handler.mobile, 'sum=' + prod_sum, 'prodNum=1', 'prodPayType=0', 'channelOrderNo=' + handler.order_id, 'notifyUrl=' + back_url, 'timestamp=' + str(tsp), 'sign=' + sign ]) url = partner['url.order'] # print(handler.order_id + ":" + body) full_url = url + '/r/Channel/createOrder?' + q request_log.info('CALL_REQ %s', full_url, extra={'orderid': handler.order_id}) response = None result = 99999 # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(full_url, method='GET') except HTTPError as http_error: request_log.error('CALL UPSTREAM FAIL %s', http_error, extra={'orderid': handler.order_id}) result = 60000 + http_error.code except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) finally: http_client.close() if response and response.code == 200: body = response.body.decode('utf8') request_log.info('CALL_RESP1 %s', body, extra={'orderid': handler.order_id}) try: # {"orderNo":"1418189340100004","orderStatus":0,"createOrderTime":"20141210132900","resultCode":"1000","resultReason":""} resp = json.loads(body) result = int(resp['resultCode']) if result == 1000: handler.up_order_id = resp['orderNo'] except Exception as e: result = 99999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) if result == 1000 and handler.up_order_id: # SUBMIT tsp = int(time.mktime(handler.up_req_time)) sign = ''.join([ 'appkey' + partner['key'], 'orderNo' + handler.up_order_id, 'timestamp' + str(tsp), partner['secret'] ]) sign = signature(sign).lower() q = '&'.join([ 'orderNo=' + handler.up_order_id, 'appkey=' + partner['key'], 'timestamp=' + str(tsp), 'sign=' + sign ]) full_url = url + '/r/Channel/submitOrder?' + q response = None result = 99999 # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(full_url, method='GET') except HTTPError as http_error: request_log.error('CALL UPSTREAM2 FAIL %s', http_error, extra={'orderid': handler.order_id}) result = 60000 + http_error.code except Exception as e: request_log.error('CALL UPSTREAM2 FAIL %s', e, extra={'orderid': handler.order_id}) finally: http_client.close() if response and response.code == 200: body = response.body.decode('utf8') request_log.info('CALL_RESP2 %s', body, extra={'orderid': handler.order_id}) try: # {"orderNo":"1418189340100004","orderStatus":0,"createOrderTime":"20141210132900","resultCode":"1000","resultReason":""} resp = json.loads(body) result = int(resp['resultCode']) except Exception as e: result = 99999 request_log.error('PARSE UPSTREAM2 %s', e, extra={'orderid': handler.order_id}) # result mapping result = RESULT_MAPPING.get(result, result) handler.up_result = result handler.up_resp_time = time.localtime() # <-------------- return result
def post(self): request_log.info('CONFIG START', extra={'orderid': 'CONFIG'}) try: safety = self.application.config.get('safety') if safety is None: request_log.error('FAIL (NO SAFETY)', extra={'orderid': 'CONFIG'}) return self.send_error(500) # verify ip in white list if self.request.remote_ip not in safety['white_list']: request_log.error("FAIL ('%s'NOT IN WHITELIST)", self.request.remote_ip, extra={'orderid': 'CONFIG'}) return self.send_error(500) # verify key tsp0 = self.request.headers['tsp'] encrypted0 = self.request.headers['v'] encrypted1 = signature(tsp0 + safety['secret']) if encrypted1 != encrypted0: request_log.error('FAIL (SECRET FAIL)', extra={'orderid': 'CONFIG'}) return self.send_error(500) # decode (optional) # reload body = self.request.body.decode() cfg = yaml.load(body) if cfg: # basic check d1 = len(cfg.get('downstream')) d0 = len(self.application.config.get('downstream')) delta = abs((d1 - d0) * 100 / d0) request_log.info('DELTA %.3f', delta, extra={'orderid': 'CONFIG'}) tsp = time.strftime("%m%d%H%M%S", time.localtime()) # back config shutil.copy('downstream.yaml', 'downstream.yaml.%s' % tsp) # write config with open('downstream.tmp', 'w', encoding='utf8') as stream: stream.write(body) if delta > 10 and abs(d1 - d0) > 10: request_log.error('CONFIG FAIL DELTA %.3f', delta, extra={'orderid': 'CONFIG'}) return self.send_error(500) shutil.move('downstream.tmp', 'downstream.yaml') self.application.config['downstream'] = cfg.get('downstream') request_log.info('SYNCED', extra={'orderid': 'CONFIG'}) return self.finish(json.dumps({'status': 'ok'})) except Exception as e: request_log.exception('SYNC FAIL', extra={'orderid': 'CONFIG'}) self.send_error(500)
def post(self): order_id = 'UNKNOWN' # check ip # parse input try: sid = self.get_argument('sid') up_back_result = ste = self.get_argument('ste') # 0=success,1=fail cid = self.get_argument('cid') pid = self.get_argument('pid') order_id = oid = self.get_argument('oid') pn = self.get_argument('pn') tf = self.get_argument('tf') fm = self.get_argument('fm') sign = self.get_argument('sign') except MissingArgumentError as e: request_log.info('%s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) self.finish() return # check input self.write("success") self.finish() request_log.info('CALLBACK %s - %s' % (self.request.uri, self.request.body), extra={'orderid': order_id}) # update order status try: # check sign master = self.master order_info = master.hmget('order:' + order_id, [ 'user_id', # 0 'value', # 1 'stage', # 2 'area', # 3 'price', # 4 'back_url', # 5 'sp_order_id', # 6 'mobile', # 7 'price', # 8 'product', # 9 'plat_offer_id' # 10 ]) self.order_id = order_id self.user_id = order_info[0] self.value = int(order_info[1]) stage = int(order_info[2]) area = order_info[3] self.carrier, self.area = area.split(':') self.price = order_info[4] self.back_url = order_info[5] self.sp_order_id = order_info[6] self.mobile = order_info[7] self.price = order_info[8] self.product = order_info[9] self.plat_offer_id = order_info[10] self.route = master.hget('order:' + order_id, 'route/%d' % stage) self.up_back_result = RESULT_MAP.get(up_back_result, up_back_result) # checking callback user = self.application.config['upstream'][self.route] if user is None or 'key' not in user: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return key = user['key'] sign2 = signature(sid, ste, cid, pid, oid, pn, tf, fm, key) if sign != sign2: request_log.error('INVALID CALLBACK', extra={'orderid': order_id}) return up_back_time = time.localtime() master.hmset('order:%s' % order_id, { 'up_back_result/%d' % stage: up_back_result, 'up_back_time/%d' % stage: time.mktime(up_back_time) }) except Exception as e: request_log.info('restore order info error %s', e, extra={'orderid': order_id}) return # downstream callback or route to next... if up_back_result == '0': self.callback('1') elif up_back_result == '3': yield self.dispatch() else: pass # TODO: logging & waiting for human
def up_fengyun(handler, partner): handler.up_req_time = time.localtime() body = '&'.join([ 'ShtVer=02', 'Action=CZ', 'AgentAccount=%s' % partner['account'], 'Phone=%s' % handler.mobile, 'Payment=%s' % handler.price, 'Orderid=%s' % handler.order_id[4:], # '&RetUrl=' + quote(partner['callback']) ]) sign = signature(body + '&Password=%s' % partner['key']) url = partner['url.order'] + '?' + body + '&Sign=' + sign.lower() request_log.info('CALL_REQ %s', url, extra={'orderid': handler.order_id}) # call & wait http_client = AsyncHTTPClient() try: response = yield http_client.fetch(url, method='GET', connect_timeout=60, request_timeout=60) except Exception as e: request_log.error('CALL UPSTREAM FAIL %s', e, extra={'orderid': handler.order_id}) response = None finally: http_client.close() handler.up_resp_time = time.localtime() # <-------------- result = 9999 if response and response.code == 200: body = response.body.decode('gbk') request_log.info('CALL_RESP %s', body, extra={'orderid': handler.order_id}) try: for args in body.split('&'): k, v = args.split('=') if k == 'Errorcode': result = RESULT_MAP.get(v, 0) elif k == 'Chargeid': handler.up_order_id = v except Exception as e: result = 9999 request_log.error('PARSE UPSTREAM %s', e, extra={'orderid': handler.order_id}) if result in [0]: for i in range(5): # wait yield tornado.gen.Task(IOLoop.instance().add_timeout, time.time() + 60 * i) # query result = yield query_fengyun_order(handler, partner) if result in [1, 9]: break handler.up_result = result if result == 1: yield handler.callback('1') elif result == 9: yield handler.callback('9') elif result == 0: handler.master.sadd('set:pending:fengyun', handler.order_id) request_log.info('FENGYUN NOT_FINISHED', extra={'orderid': handler.order_id}) return result