This commit is contained in:
ping 2025-09-23 14:25:29 +08:00
parent d0b6c903ca
commit c85c520df9

View File

@ -112,13 +112,12 @@ async def affirmbz_order(ns={}):
await sor.rollback()
raise error
async def get_baidu_orderlist(ns={}):
"""
百度支付
1、获取订单
2、算出购买的产品折扣
3、比对账号余额
"""
async def baidu_new_update_resouce(ns={}):
# 增加延迟
import asyncio
await asyncio.sleep(12)
db = DBPools()
async with db.sqlorContext('kboss') as sor:
baidu_users = await sor.R('baidu_users', {'user_id': ns.get('userid'),'del_flg':'0'})
@ -139,16 +138,107 @@ async def get_baidu_orderlist(ns={}):
headers=header,
json=nss) as res:
data_ = await res.json()
with open('baidu_new_order_after_confirm.txt', 'a+') as f:
f.write(json.dumps(data_) + '\n')
orders = data_['orders']
for item in orders:
order_items = item['orderItems']
for order_info in order_items:
resourceids = ','.join(order_info['shortIds']) if order_info.get('shortIds') else ''
if not resourceids:
continue
resourcestarttime = await time_convert(order_info.get('resourceStartTime')) if order_info.get(
'resourceStartTime') else None
resourceendtime = await time_convert(order_info.get('resourceEndTime')) if order_info.get(
'resourceEndTime') else None
order_key = order_info['key']
update_order_goods_sql = """ UPDATE order_goods og
JOIN bz_order o ON og.orderid = o.id
SET
og.resourceids = '%s',
og.resourcestarttime = '%s',
og.resourceendtime = '%s'
WHERE
og.orderkey = '%s'
AND o.provider_orderid = '%s'; """ \
% (resourceids, resourcestarttime, resourceendtime, order_key, ns.get('order_id'))
await sor.sqlExe(update_order_goods_sql, {})
update_customer_goods_sql = """ UPDATE customer_goods og
JOIN bz_order o ON og.orderid = o.id
SET
og.resourceid = '%s',
og.start_date = '%s',
og.expire_date = '%s'
WHERE
og.orderkey = '%s'
AND o.provider_orderid = '%s'; """ \
% (resourceids, resourcestarttime, resourceendtime, order_key, ns.get('order_id'))
await sor.sqlExe(update_customer_goods_sql, {})
async def baidu_order_cancel(ns={}):
baidu_id = ns['baidu_id']
order_id = ns['order_id']
paydata = {'queryAccountId': baidu_id, 'orderIds': [order_id]}
ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()])
url = 'https://billing.baidubce.com/v1/order/cancel?%s' % ns_format
method = 'POST'
header = {
"Host": "billing.baidubce.com"
}
header = await get_auth_header(method=method, url=url, header=header)
async with aiohttp_client.request(
method=method,
url=url,
headers=header,
json=paydata) as res:
await res.json()
return {
'status': True,
'msg': 'order cancel success'
}
async def get_baidu_orderlist(ns={}):
"""
百度支付
1、获取订单
2、算出购买的产品折扣
3、比对账号余额
"""
# 增加延迟
import asyncio
await asyncio.sleep(1)
db = DBPools()
async with db.sqlorContext('kboss') as sor:
baidu_users = await sor.R('baidu_users', {'user_id': ns.get('userid'),'del_flg':'0'})
user = await sor.R('users', {'id': ns.get('userid')})
orgid = await sor.R('organization', {'id': user[0]['orgid']})
nss = {'uuids': [ns.get('order_id')], 'queryAccountId': baidu_users[0]['baidu_id']}
ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()])
url = 'https://billing.baidubce.com/v1/order/getByUuid?%s' % ns_format
method = 'POST'
header = {
"Host": "billing.baidubce.com",
"ContentType": "application/json;charset=UTF-8"
}
header = await get_auth_header(method=method, url=url, header=header)
async with aiohttp_client.request(
method=method,
url=url,
headers=header,
json=nss) as res:
data_ = await res.json()
with open('baidu_new_order.txt', 'a+') as f:
f.write(json.dumps(data_) + '\n')
orders = data_['orders']
serviceType = orders[0]['orderItems']
# 可能获取得到的是延迟订单
if orders[0]['type'] == 'REFUND' and orders[0]['status'] != 'CREATED':
return {
'status': False,
'msg': 'delay_order, 当前状态是: %s' % orders[0]['status'],
'data': data_
}
await update_baidu_order_list({'userid': ns.get('userid')})
res_refund = await baidu_confirm_refund_order({'order_id': ns.get('order_id'), 'baidu_id': baidu_users[0]['baidu_id'], 'user_id': ns.get('userid')})
return res_refund
# 避免重复退订
if orders[0]['type'] == 'REFUND' and orders[0]['status'] == 'CREATED':
@ -167,19 +257,52 @@ async def get_baidu_orderlist(ns={}):
(float(orders[0]['price']), orders[0]['status'], updatetime, ns.get('order_id'))
await sor.sqlExe(update_refund_sql, {})
productType = 'prepay'
# 判断订单item中productType是否有后付费的产品
for item in orders:
order_items = item['orderItems']
for order_info in order_items:
postpay_price = order_info['itemFee']['price'] if order_info.get('itemFee') else order_info['catalogPrice']
if not postpay_price:
# cpt1Price: 固定配置,按分钟计费
postpay_price = order_info['pricingDetail'].get('cpt1Price') if order_info.get('pricingDetail') else 0
# 确定是否是后付费订单
if order_info['productType'] == 'postpay' and postpay_price != 0:
return {
'status': False,
'msg': '暂不支持后付费按量购买, 请联系后台开通'
}
productType = 'postpay'
# 获取余额
user_balance = await getCustomerBalance(sor, orgid[0]['id'])
# 判断余额是否大于50
if user_balance < 50:
await sor.rollback()
paydata = {'queryAccountId': baidu_users[0]['baidu_id'], 'orderIds': [ns.get('order_id')]}
ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()])
url = 'https://billing.baidubce.com/v1/order/cancel?%s' % ns_format
method = 'POST'
header = {
"Host": "billing.baidubce.com"
}
header = await get_auth_header(method=method, url=url, header=header)
async with aiohttp_client.request(
method=method,
url=url,
headers=header,
json=paydata) as res:
await res.json()
ns_record = {
'orderid': ns.get('order_id'),
'ordertype': orders[0]['type'],
'userid': ns.get('userid'),
'reason': '后付费 该账号余额不足50无法完成购买'
}
await user_action_record(ns_record)
return {
'status': False,
'msg': '您的余额小于该产品的起购金额50元, 目前无法购买立即充值'
}
# 实付价格
total_price = 0
productType = ''
# productType = ''
# 买/续/退 字段映射
order_type = orders[0]['type']
@ -212,7 +335,8 @@ async def get_baidu_orderlist(ns={}):
bz_ns['order_date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
bz_ns['thirdparty_order'] = ns.get('order_id')
bz_ns['source'] = '百度智能云'
bz_ns['originalprice'] = orders[0]['price']
# bz_ns['originalprice'] = orders[0]['price']
bz_ns['originalprice'] = sum(i['catalogPrice'] for i in serviceType)
bz_ns['provider_orderid'] = ns.get('order_id')
bz_ns['ordertype'] = orders[0]['productType']
bz_ns['servicename'] = orders[0]['serviceType']
@ -221,23 +345,45 @@ async def get_baidu_orderlist(ns={}):
bz_ns['specdataid'] = ns['specdataid']
await sor.C('bz_order', bz_ns)
for i in serviceType:
if i['productType'] == 'prepay':
# 预付费
productType = 'prepay'
# if i['productType'] == 'prepay':
# # 预付费
# productType = 'prepay'
# financePrice = 0
# 获取产品id
product = await sor.R('product', {'providerpid': 'baidu_' + i['serviceType'], 'del_flg': '0'})
if not product:
return {
'status': False,
'msg': '未配置该产品, 请联系售后处理'
}
# 获取协议
saleprotocol = await sor.R('saleprotocol',
saleprotocol_to_person = await sor.R('saleprotocol',
{'bid_orgid': orgid[0]['id'], 'offer_orgid': orgid[0]['parentid'],
'del_flg': '0'})
if saleprotocol == []:
# 等于空就代表这个客户没有特殊折扣,就要找到买方为*的协议
saleprotocol = await sor.R('saleprotocol', {'bid_orgid': '*', 'offer_orgid': orgid[0]['parentid'],
'del_flg': '0', 'salemode': '0'})
product_salemode = await sor.R('product_salemode',
{'protocolid': saleprotocol[0]['id'], 'productid': product[0]['id'],
'del_flg': '0'})
# 等于空就代表这个客户没有特殊折扣,就要找到买方为*的协议
saleprotocol_to_all = await sor.R('saleprotocol', {'bid_orgid': '*', 'offer_orgid': orgid[0]['parentid'],
'del_flg': '0', 'salemode': '0'})
if saleprotocol_to_person:
product_salemode = await sor.R('product_salemode',
{'protocolid': saleprotocol_to_person[0]['id'],
'productid': product[0]['id'],
'del_flg': '0'})
if not product_salemode:
product_salemode = await sor.R('product_salemode',
{'protocolid': saleprotocol_to_all[0]['id'],
'productid': product[0]['id'],
'del_flg': '0'})
else:
product_salemode = await sor.R('product_salemode',
{'protocolid': saleprotocol_to_all[0]['id'],
'productid': product[0]['id'],
'del_flg': '0'})
if not product_salemode:
return {
'status': False,
'msg': '还未上线这个产品的协议配置'
}
supply_price = i['itemFee']['price'] if i.get('itemFee') else i['catalogPrice']
financePrice = abs(supply_price * product_salemode[0]['discount'])
total_price += financePrice
@ -263,10 +409,11 @@ async def get_baidu_orderlist(ns={}):
nss['chargeduration'] = i.get('time')
nss['unit'] = i.get('timeUnit')
nss['resourceids'] = ','.join(i['shortIds']) if i.get('shortIds') else ''
nss['orderkey'] = i.get('key')
# 如果是续费订单 由于没有返回日期, 重新计算日期
if order_type == 'RENEW':
history_time_sql = "select resourcestarttime, resourceendtime from order_goods where resourceids = '%s' order by resourceendtime desc;" % \
history_time_sql = "select resourcestarttime, resourceendtime from order_goods where FIND_IN_SET('%s', resourceids) order by resourceendtime desc;" % \
nss['resourceids']
history_time = await sor.sqlExe(history_time_sql, {})
new_end_time = await cal_expire_time(history_time=history_time[0]['resourceendtime'],
@ -275,27 +422,45 @@ async def get_baidu_orderlist(ns={}):
nss['resourcestarttime'] = history_time[0]['resourcestarttime']
nss['resourceendtime'] = new_end_time
else:
nss['resourcestarttime'] = await time_convert(i.get('resourceStartTime')) if i.get(
'resourceStartTime') else None
nss['resourceendtime'] = await time_convert(i.get('resourceEndTime')) if i.get(
'resourceEndTime') else None
if i.get('resourceStartTime'):
nss['resourcestarttime'] = await time_convert(i.get('resourceStartTime'))
else:
nss['resourcestarttime'] = await time_convert(orders[0]['updateTime'])
if i.get('resourceEndTime'):
nss['resourceendtime'] = await time_convert(i.get('resourceEndTime'))
# 后付费没有资源结束时间
if i.get('productType') == 'prepay':
end_time = await time_convert(orders[0]['updateTime'])
nss['resourceendtime'] = await cal_expire_time(history_time=end_time,
chargeduration=nss['chargeduration'],
unit=nss['unit'])
else:
nss['resourceendtime'] = None
await sor.C('order_goods', nss)
# 循环后更新订单中总价
await sor.U('bz_order', {'id': bz_ns['id'], 'amount': round(total_price, 2)})
except Exception as e:
await baidu_order_cancel({'baidu_id': baidu_users[0]['baidu_id'], 'order_id': ns.get('order_id')})
import traceback
ns_record = {
'orderid': ns.get('order_id'),
'ordertype': orders[0]['type'],
'userid': ns.get('userid'),
'reason': '发生错误, %s' % str(e)[:100]
'reason': '发生错误, %s' % str(traceback.format_exc())
}
await user_action_record(ns_record)
import traceback
with open('baiducloud_err.txt', 'w') as f:
f.write(str(e)+ traceback.format_exc())
f.write(str(e) + str(traceback.format_exc()))
traceback.print_exc()
await sor.rollback()
return {
'status': False,
'msg': '产品错误, 请联系售后'
}
# 判断用户账户余额是否足够支付
try:
@ -305,7 +470,7 @@ async def get_baidu_orderlist(ns={}):
if round(total_price,2) <= count:
#判断预付费或者后付费
if productType == 'prepay':
if productType == 'prepay' or productType == 'postpay':
# 调用扣费接口
affirmbz_order_ns = {
'sor': sor,
@ -320,7 +485,7 @@ async def get_baidu_orderlist(ns={}):
'orderid': ns.get('order_id'),
'ordertype': orders[0]['type'],
'userid': ns.get('userid'),
'reason': '支付错误, 请联系售后'
'reason': '支付错误, 请联系售后, %s' % affirmbz_order_res.get('msg')
}
await user_action_record(ns_record)
return {
@ -336,22 +501,21 @@ async def get_baidu_orderlist(ns={}):
}
else:
# 调用支付订单接口
# paydata = {'queryAccountId':baidu_users[0]['baidu_id'],'orderId':ns.get('order_id')}
# ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()])
# url = 'https://billing.baidubce.com/v1/order/pay?%s' % ns_format
# method = 'POST'
# header = {
# "Host": "billing.baidubce.com"
# }
# header = await get_auth_header(method=method, url=url, header=header)
# async with aiohttp_client.request(
# method=method,
# url=url,
# headers=header,
# json=paydata) as res:
# data_ = await res.json()
# if data_ == {'success': True}:
if True:
paydata = {'queryAccountId':baidu_users[0]['baidu_id'],'orderId':ns.get('order_id')}
ns_format = '&'.join(['%s=%s' % (k, v) for k, v in ns.items()])
url = 'https://billing.baidubce.com/v1/order/pay?%s' % ns_format
method = 'POST'
header = {
"Host": "billing.baidubce.com"
}
header = await get_auth_header(method=method, url=url, header=header)
async with aiohttp_client.request(
method=method,
url=url,
headers=header,
json=paydata) as res:
data_ = await res.json()
if data_ == {'success': True}:
ns_record = {
'orderid': ns.get('order_id'),
'ordertype': orders[0]['type'],
@ -359,12 +523,23 @@ async def get_baidu_orderlist(ns={}):
'reason': '购买成功'
}
await user_action_record(ns_record)
return {
'status': True,
'orderid': bz_ns['id']
ns_cron_job = {
'id': uuid(),
'source': 'baidu',
'orderid': ns.get('order_id'),
'ordertype': orders[0]['type'],
'userid': ns.get('userid'),
'reason': 'buy success'
}
await sor.C('baidu_cron_job', ns_cron_job)
# return {
# 'status': True,
# 'orderid': bz_ns['id']
# }
else:
await sor.rollback()
await baidu_order_cancel(
{'baidu_id': baidu_users[0]['baidu_id'], 'order_id': ns.get('order_id')})
ns_record = {
'orderid': ns.get('order_id'),
'ordertype': orders[0]['type'],
@ -427,10 +602,26 @@ async def get_baidu_orderlist(ns={}):
await user_action_record(ns_record)
return {'status': False,'msg': '该账号余额不足,无法完成购买'}
except Exception as e:
await baidu_order_cancel({'baidu_id': baidu_users[0]['baidu_id'], 'order_id': ns.get('order_id')})
import traceback
with open('baiducloud_err.txt', 'w') as f:
f.write(str(e)+ traceback.format_exc())
traceback.print_exc()
await sor.rollback()
return {
'status': False,
'msg': '产品错误, 请联系售后'
}
# 更新资源时间 资源id
# if order_type == 'NEW':
# await baidu_new_update_resouce(ns)
return {
'status': True,
'orderid': bz_ns['id'],
'originalprice': bz_ns.get('originalprice'),
'servicename': bz_ns.get('servicename'),
'amount': total_price
}
async def get_order_list_base_page(baidu_id, pageNo=1, pageSize=500):
ns = {'queryAccountId': baidu_id, 'pageNo': pageNo, 'pageSize': pageSize}
@ -525,7 +716,6 @@ async def baidu_confirm_refund_order(ns={}):
# 'order_id': ["03ee8d08da79458b8f8d3157d3498330", "e711729606024080bf9613d975294616"],
# 'userid': 'KsKhCUPizQyGiw3L1WVRy'
# }
return {'1': ns}
import asyncio
# 把 NEED_CONFIRM的订单同步到本地库用于后续状态更新
await update_baidu_order_list({'userid': ns.get('userid')})