123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- """
- __title__ = '各个平台的订单API接口'
- @Time : 2020/9/30 12:33
- @Author : Kenny-PC
- @Software: PyCharm
- # code is far away from bugs with the god animal protecting
- I love animals. They taste delicious.
- ┏┓ ┏┓
- ┏┛┻━━━┛┻┓
- ┃ ☃ ┃
- ┃ ┳┛ ┗┳ ┃
- ┃ ┻ ┃
- ┗━┓ ┏━┛
- ┃ ┗━━━┓
- ┃ 神兽保佑 ┣┓
- ┃ 永无BUG! ┏┛
- ┗┓┓┏━┳┓┏┛
- ┃┫┫ ┃┫┫
- ┗┻┛ ┗┻┛
- """
- import datetime
- import hashlib
- import math
- import time
- from concurrent.futures import ProcessPoolExecutor
- from urllib import parse
- import requests
- from util import date_util
- from util import platform_config_util
- from util import robust_util
- # md5加密,使用utf-8编码
- def md5(s):
- md5 = hashlib.md5()
- md5.update(s.encode("utf-8"))
- return md5.hexdigest()
- # 阅文
- @robust_util.catch_exception
- def get_yuewen_order(st, et):
- start_exec_seconds = date_util.getCurrentSecondTime()
- total_order_list = ()
- account_list = platform_config_util.get_yuewen_account_list()
- executor = ProcessPoolExecutor(max_workers=5)
- futures = []
- for account in account_list:
- future = executor.submit(get_yuewen_order_task, st, et, account)
- futures.append(future)
- executor.shutdown(True)
- for future in futures:
- order_list = future.result()
- if len(order_list) > 0:
- total_order_list = order_list + total_order_list
- print('阅文订单数量:', len(total_order_list), '执行时长(秒):', date_util.getCurrentSecondTime() - start_exec_seconds)
- return total_order_list
- def get_yuewen_order_task(st, et, account):
- order_list = ()
- email = account[0]
- appsecert = account[1]
- url = 'https://open.yuewen.com/cpapi/wxRecharge/querychargelog'
- version = 1
- order_status = 2 # 已支付
- page_count = 100 # 每页100条数据
- start_time = st
- for i in range((et - st) // 86400 + 1):
- page = 1
- last_min_id = ''
- last_max_id = ''
- total_count = ''
- last_page = ''
- while True:
- if start_time == et:
- break
- end_time = min(start_time + 86400, et)
- timestamp = int(time.time())
- params = {
- 'email': email,
- 'version': version,
- 'timestamp': timestamp,
- 'start_time': start_time,
- 'end_time': end_time,
- 'page': page,
- 'order_status': order_status
- }
- if page > 1:
- params['last_min_id'] = last_min_id
- params['last_max_id'] = last_max_id
- params['total_count'] = total_count
- params['last_page'] = last_page
- sorted_data = sorted(params.items())
- str_params = ''
- for k, v in sorted_data:
- str_params = str_params + str(k) + str(v)
- sign = md5(appsecert + str_params).upper()
- # 放入签名
- params['sign'] = sign
- response_result_json = requests.get(url=url, params=params).json()
- code = response_result_json['code']
- ## 此接口有调用频率限制,相同查询条件每分钟仅能请求一次
- if code != 0:
- print('阅文查询充值接口异常:', response_result_json, '参数', params)
- break
- # if code == 10408:
- # if fail_count > 0:
- # break
- #
- # sleep_seconds = random.randint(60, 70)
- # print('阅文获取订单数据线程休眠【{sleep_seconds}】秒,因为该接口有一分钟的限制'.format(sleep_seconds=sleep_seconds))
- # time.sleep(sleep_seconds)
- #
- # print('重试一次')
- # fail_count = fail_count + 1
- # get_yuewen_order_task(st, et, account, fail_count)
- response_data = response_result_json['data']
- total_count = response_data['total_count']
- if total_count == 0:
- continue
- last_min_id = response_data['min_id']
- last_max_id = response_data['max_id']
- last_page = response_data['page']
- order_item_list = response_data['list']
- for order_item in order_item_list:
- order_time = order_item['order_time']
- dtime = datetime.datetime.strptime(order_time, "%Y-%m-%d %H:%M:%S")
- order_time_unix = int(time.mktime(dtime.timetuple()))
- order_id = order_item['order_id']
- if date_util.checkInterval(start_time, end_time, order_time_unix) == False:
- print('阅文账号【{key}】,查询时间【{start_time} - {end_time}】,有不符合该时间范围的订单,订单Id【{order_id}】的时间为【{order_time}】'
- .format(key=email, start_time=date_util.getSecondsToDatetime(start_time),
- end_time=date_util.getSecondsToDatetime(end_time), order_id=order_id,
- order_time=order_time))
- # continue
- order = {}
- order['date'] = ((order_time_unix + 8 * 3600) // 86400) * 86400 - 8 * 3600
- order['platform'] = '阅文'
- order['channel'] = order_item['app_name']
- order['from_novel'] = order_item['book_name']
- order['user_id'] = order_item['openid']
- order['stage'] = ''
- order['channel_id'] = 0
- order['order_time'] = order_time
- order['amount'] = order_item['amount']
- order['reg_time'] = order_item['reg_time']
- order['order_id'] = order_id
- order = sorted(order.items(), key=lambda item: item[0])
- order = dict(order)
- order = tuple(order.values())
- order_list = order_list + ((order),)
- # print('阅文账号【{key}】, 查询时间【{start_time} - {end_time}】,当前页【{page}】,本次查询订单数量【{total_count}】'
- # .format(key=email, start_time=date_util.getSecondsToDatetime(start_time),
- # end_time=date_util.getSecondsToDatetime(end_time),page=page, total_count=total_count))
- if int(page) >= math.ceil(total_count / int(page_count)):
- break
- page = page + 1
- start_time = start_time + 86400 # 天数加1
- # sleep_seconds = random.randint(60, 70)
- # print('阅文获取订单数据线程休眠【{sleep_seconds}】秒,因为该接口有一分钟的限制'.format(sleep_seconds=sleep_seconds))
- # time.sleep(sleep_seconds)
- return order_list
- # 掌读
- @robust_util.catch_exception
- def get_zhangdu_order(st, et):
- start_exec_seconds = date_util.getCurrentSecondTime()
- total_order_list = ()
- account_list = platform_config_util.get_zhangdu_account_list()
- executor = ProcessPoolExecutor(max_workers=5)
- futures = []
- for account in account_list:
- future = executor.submit(get_zhangdu_order_task, st, et, account)
- futures.append(future)
- executor.shutdown(True)
- for future in futures:
- order_list = future.result()
- if len(order_list) > 0:
- total_order_list = order_list + total_order_list
- print('掌读订单数量:', len(total_order_list), '执行时长(秒):', date_util.getCurrentSecondTime() - start_exec_seconds)
- return total_order_list
- def get_zhangdu_order_task(st, et, account):
- order_list = ()
- url = 'https://api.zhangdu520.com/channel/getorder'
- uid = account[0]
- appsecert = account[1]
- channel = account[2]
- timestamp = int(time.time())
- sign = md5(str(uid) + '&' + appsecert + '&' + str(timestamp))
- starttime = st
- timespace = 90 * 3600 * 24
- endtime = min(et, st + timespace)
- for x in range((et - st) // timespace + 1): # 分时段
- if x > 0:
- print('掌读跨天数查询:', x)
- page = 1
- while True:
- params = {
- 'uid': uid,
- 'timestamp': timestamp,
- 'sign': sign,
- 'starttime': starttime,
- 'endtime': endtime,
- 'page': page
- }
- response_result_json = requests.get(url=url, params=params).json()
- if 'data' not in response_result_json.keys():
- print('掌读账号【{key}】, 查询时间【{start_time} - {end_time}】,本次请求数据异常,响应报文【{result}】'
- .format(key=uid, start_time=date_util.getSecondsToDatetime(starttime),
- end_time=date_util.getSecondsToDatetime(endtime), result=response_result_json))
- break
- result_data = response_result_json['data']
- page_count = result_data['pageCount']
- if page_count == 0:
- break
- order_item_list = result_data['list']
- for order_item in order_item_list:
- if order_item['status'] != '1':#1为已支付
- continue
- order = {}
- order['amount'] = order_item['amount']
- order['channel_id'] = uid
- order['order_id'] = str(order_item['orderno'])
- order['order_time'] = order_item['ctime']
- order['user_id'] = order_item['openid']
- order['platform'] = '掌读'
- order['channel'] = channel
- order['reg_time'] = order_item['regtime']
- order['from_novel'] = ''
- order['stage'] = ''
- order['date'] = ((int(order_item['ctime']) + 8 * 3600) // 86400) * 86400 - 8 * 3600
- x = sorted(order.items(), key=lambda item: item[0])
- x = dict(x)
- x = tuple(x.values())
- order_list = order_list + ((x),)
- if page == page_count: #是最后一页
- break
- page = page + 1
- starttime = starttime + timespace
- endtime = min(et, starttime + timespace)
- return order_list
- # 花生
- @robust_util.catch_exception
- def get_huasheng_order(st, et):
- start_exec_seconds = date_util.getCurrentSecondTime()
- total_order_list = ()
- account_list = platform_config_util.get_huasheng_account_list()
- executor = ProcessPoolExecutor(max_workers=5)
- futures = []
- for account in account_list:
- url = 'https://vip.rlcps.cn/api/getMerchants'
- apiKey = str(account[0])
- apiSecurity = account[1]
- timestamp = str(int(time.time()))
- sign = md5(apiKey + timestamp + apiSecurity).upper()
- params = {
- 'apiKey': apiKey,
- 'apiSecurity': apiSecurity,
- 'timestamp': timestamp,
- 'sign': sign
- }
- response_result_json = requests.post(url, params).json()
- if 'data' not in response_result_json.keys():
- print('花生账号【{apiKey}】本次请求数据异常,响应报文【{result}】'.format(apiKey=apiKey, result=response_result_json))
- continue
- for merchant in response_result_json['data']:
- future = executor.submit(get_huasheng_order_task, st, et, account, merchant)
- futures.append(future)
- executor.shutdown(True)
- for future in futures:
- order_list = future.result()
- if len(order_list) > 0:
- total_order_list = order_list + total_order_list
- print('花生订单数量:', len(total_order_list), '执行时长(秒):', date_util.getCurrentSecondTime() - start_exec_seconds)
- return total_order_list
- def get_huasheng_order_task(st, et, account, merchant):
- order_list = ()
- apiKey = str(account[0])
- apiSecurity = account[1]
- stage = account[2]
- timestamp = str(int(time.time()))
- order_url = 'https://vip.rlcps.cn/api/orderList'
- merchant_id = merchant['merchant_id']
- merchant_name = merchant['merchant_name']
- start_time = st
- limit = 500
- for i in range((et - st) // 86400 + 1):
- page = 1
- while True:
- date = time.strftime("%Y-%m-%d", time.localtime(start_time))
- sign = md5(apiKey + date + str(merchant_id) + timestamp + apiSecurity).upper()
- order_params = {
- 'apiKey': apiKey,
- 'apiSecurity': apiSecurity,
- 'timestamp': timestamp,
- 'date': date,
- 'merchant_id': merchant_id,
- 'sign': sign,
- 'page': page,
- 'limit': limit
- }
- response_result_json = requests.post(order_url, order_params).json()
- if 'data' not in response_result_json.keys():
- print('花生账号【{key}】, 查询时间【{date}】, 渠道【{merchant_id}:{merchant_name}】本次请求数据异常,响应报文【{result}】'
- .format(key=apiKey, date=date, merchant_id=merchant_id, merchant_name=merchant_name,
- result=response_result_json))
- break
- if len(response_result_json['data']) == 0:
- break
- total_count = response_result_json['count']
- order_item_list = response_result_json['data']
- for order_item in order_item_list:
- if order_item['order_status'] == 1: # 1为已支付
- order = {}
- ##dtime = datetime.datetime.strptime(order_item['pay_at'],"%Y-%m-%d")
- ##order['date']= ((int(time.mktime(dtime.timetuple()))+8*3600)//86400)*86400-8*3600
- order['user_id'] = order_item['openid']
- order['order_id'] = order_item['trans_id']
- order['order_time'] = order_item['pay_at']
- order['reg_time'] = order_item['join_at']
- # TODO 花生的时间需要统一
- order['date'] = (start_time + 8 * 3600) // 86400 * 86400 - 8 * 3600
- order['channel'] = merchant_name
- order['channel_id'] = merchant_id
- order['platform'] = '花生'
- order['stage'] = stage
- order['from_novel'] = order_item['book_name']
- order['amount'] = order_item['amount']
- order = sorted(order.items(), key=lambda item: item[0])
- order = dict(order)
- order = tuple(order.values())
- order_list = order_list + ((order),)
- if int(page) >= math.ceil(total_count / int(limit)):
- break
- # print('花生账号【{key}】, 渠道【{merchant_id}:{merchant_name}】当前页【{page}】,本次查询订单数【{total_count}】,即将查询下一页'
- # .format(key=apiKey, merchant_id=merchant_id, merchant_name=merchant_name, page=page, total_count=total_count))
- page = page + 1
- start_time = start_time + 86400 # 天数加1
- return order_list
- # 掌中云
- @robust_util.catch_exception
- def get_zhangzhongyun_order(st, et):
- start_exec_seconds = date_util.getCurrentSecondTime()
- total_order_list = ()
- account_list = platform_config_util.get_zhangzhongyun_account_list()
- executor = ProcessPoolExecutor(max_workers=5)
- futures = []
- for account in account_list:
- #url = 'https://openapi.818tu.com/partners/channel/channels/list?'
- url = 'https://inovel.818tu.com/partners/channel/channels/list?'
- key = account[0]
- secert = account[1]
- sign = md5(secert + 'key=' + key)
- params = 'key=' + key + '&sign=' + sign
- response_result_json = requests.get(url + params).json() # 获取子渠道列表
- if 'data' not in response_result_json.keys():
- print('掌中云账号【{key}】本次请求数据异常,响应报文【{result}】'.format(key=key, result=response_result_json))
- continue
- items = response_result_json['data']['items']
- for channel in items:
- # 获取channel_id 后逐个拉取历史orders
- future = executor.submit(get_zhangzhongyun_order_task, st, et, account, channel)
- futures.append(future)
- executor.shutdown(True)
- for future in futures:
- order_list = future.result()
- if len(order_list) > 0:
- total_order_list = order_list + total_order_list
- print('掌中云订单数量:', len(total_order_list), '执行时长(秒):', date_util.getCurrentSecondTime() - start_exec_seconds)
- return total_order_list
- def get_zhangzhongyun_order_task(st, et, account, channel):
- # 掌中云的时间格式比较特殊,转换下
- get_time, limit_time = platform_config_util.get_zhangzhongyun_query_time(st, et)
- order_list = ()
- key = account[0]
- secert = account[1]
- stage = account[2]
- order_url = 'https://openapi.818tu.com/partners/channel/orders/list?'
- channel_id = channel['id']
- channel_name = channel['nickname']
- status = str(1)
- page = str(1)
- per_page = str(1000)
- gte = parse.urlencode({'created_at[gte]': get_time}) # gte就是ge 大于等于开始时间
- lt = parse.urlencode({'created_at[lt]': limit_time}) # 小于 结束时间
- while True:
- sign = md5(secert + 'channel_id=' + str(
- channel_id) + '&created_at[gte]=' + get_time + '&created_at[lt]=' + limit_time + '&key=' + key + '&page=' + str(
- page) + '&per_page=' + per_page + '&status=' + status)
- params = 'channel_id=' + str(channel_id) + '&' + gte + '&' + lt + '&page=' + str(
- page) + '&per_page=' + per_page + '&status=' + status + '&key=' + key + '&sign=' + sign
- response_result_json = requests.get(order_url + params).json()
- if 'data' not in response_result_json.keys():
- print('掌中云账号【{key}】,查询时间【{start_time} - {end_time}】,渠道【{channel_id}:{channel_name}】本次请求数据异常,响应报文【{result}】'
- .format(key=key, start_time=date_util.getSecondsToDatetime(get_time),
- end_time=date_util.getSecondsToDatetime(limit_time),channel_id=channel_id, channel_name=channel_name, result=response_result_json))
- break
- total_count = response_result_json['data']['count'] # 总数量
- order_item_list = response_result_json['data']['items'] # 订单列表
- for order_item in order_item_list:
- order = {}
- order['user_id'] = str(order_item['member']['openid'])
- order['channel'] = channel_name
- order['reg_time'] = order_item['member']['created_at']
- order['channel_id'] = channel_id
- order['amount'] = round(order_item['price'] / 100, 2)
- order['order_id'] = str(order_item['id'])
- order['order_time'] = order_item['created_at']
- order['platform'] = '掌中云'
- order['stage'] = stage
- dtime = datetime.datetime.strptime(order_item['created_at'][0:10], "%Y-%m-%d")
- order['date'] = ((int(time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
- if str(order_item['from_novel_id']) != 'None':
- order['from_novel'] = order_item['from_novel']['title']
- else:
- order['from_novel'] = 'None'
- x = sorted(order.items(), key=lambda item: item[0])
- x = dict(x)
- x = tuple(x.values())
- order_list = order_list + ((x),)
- if int(page) >= math.ceil(total_count / int(per_page)):
- break
- # print('掌中云账号【{key}】, 渠道【{channel_id}:{channel_name}】当前页【{page}】,本次查询订单数【{total_count}】,即将查询下一页'
- # .format(key=key, channel_id=channel_id, channel_name=channel_name, page=page, total_count=total_count))
- page = int(page) + 1
- return order_list
- # 悠书阁
- @robust_util.catch_exception
- def get_youshuge_order(st, et):
- start_exec_seconds = date_util.getCurrentSecondTime()
- total_order_list = ()
- account_list = platform_config_util.get_youshuge_account_list()
- executor = ProcessPoolExecutor(max_workers=5)
- futures = []
- for account in account_list:
- future = executor.submit(get_youshuge_order_task, st, et, account)
- futures.append(future)
- executor.shutdown(True)
- for future in futures:
- order_list = future.result()
- if len(order_list) > 0:
- total_order_list = order_list + total_order_list
- print('悠书阁订单数量:', len(total_order_list), '执行时长(秒):', date_util.getCurrentSecondTime() - start_exec_seconds)
- return total_order_list
- def get_youshuge_order_task(st, et, account):
- # 悠书阁的查询end_date时间必须要大于start_date
- start_date, end_date = platform_config_util.get_youshuge_order_query_time(st, et)
- order_list = ()
- host_name = account[0]
- channel_id = int(account[1])
- secert_key = account[2]
- channel = account[3]
- stage = account[4]
- url = 'https://novel.youshuge.com/v2/open/orders'
- page = 1
- timestamp = int(time.time())
- while True:
- sign = md5('channel_id=' + str(channel_id) + '&end_date=' + end_date + '&host_name=' + host_name + '&page='
- + str(page) + '&pay_status=1' + '&start_date=' + start_date + '&time=' + str(timestamp) + '&key=' + secert_key).upper()
- params = {
- 'sign': sign,
- 'host_name': host_name,
- 'time': timestamp,
- 'channel_id': channel_id,
- 'page': page,
- 'pay_status': 1,
- 'start_date': start_date,
- 'end_date': end_date
- }
- respone = requests.post(url, params)
- if respone.status_code == 400:
- print('悠书阁订单查询接口respone', respone)
- response_result_json = respone.json()
- if 'data' not in response_result_json.keys():
- print('悠书阁账号【{key}】,查询时间【{start_time} - {end_time}】,渠道【{channel_id}:{channel_name}】本次请求数据异常,响应报文【{result}】'
- .format(key=host_name, start_time=start_date, end_time=end_date, channel_id=channel_id, result=response_result_json))
- break
- order_item_list = response_result_json['data']
- if len(order_item_list) == 0:
- break
- for order_item in order_item_list:
- order = {}
- dtime = datetime.datetime.strptime(order_item['create_time'][0:10], "%Y-%m-%d")
- order['date'] = ((int(
- time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
- order['order_id'] = order_item['order_num']
- order['amount'] = round(int(order_item['price']) / 100, 2)
- order['order_time'] = order_item['create_time']
- order['channel'] = channel
- order['from_novel'] = order_item['book_name']
- order['stage'] = stage
- order['user_id'] = order_item['openid']
- order['channel_id'] = channel_id
- order['platform'] = '悠书阁'
- order['reg_time'] = order_item['reg_time']
- order = sorted(order.items(), key=lambda item: item[0])
- order = dict(order)
- order = tuple(order.values())
- order_list = order_list + ((order),)
- total_count = order_item_list[0]['count']
- if page == total_count:
- break
- page = page + 1
- return order_list
- def build_ysg_order_data(channel, channel_id, result_json, stage):
- order_list = ()
- if 'data' in result_json.keys():
- data = result_json['data']
- if len(data) > 0:
- for x in data:
- y = {}
- dtime = datetime.datetime.strptime(x['create_time'][0:10], "%Y-%m-%d")
- y['date'] = ((int(
- time.mktime(dtime.timetuple())) + 8 * 3600) // 86400) * 86400 - 8 * 3600
- y['order_id'] = x['order_num']
- y['amount'] = round(int(x['price']) / 100, 2)
- y['order_time'] = x['create_time']
- y['channel'] = channel
- y['from_novel'] = x['book_name']
- y['stage'] = stage
- y['user_id'] = x['openid']
- y['channel_id'] = channel_id
- y['platform'] = '悠书阁'
- y['reg_time'] = x['reg_time']
- y = sorted(y.items(), key=lambda item: item[0])
- y = dict(y)
- y = tuple(y.values())
- order_list = order_list + ((y),)
- return order_list
|